Validate that model and model are not model expression (#1004)

This commit is contained in:
Timothee Guerin 2022-09-08 16:30:29 -04:00 коммит произвёл GitHub
Родитель c7a655c468
Коммит 6fc20ad102
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 98 добавлений и 1 удалений

Просмотреть файл

@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@cadl-lang/compiler",
"comment": "**Breaking** Model `extends` or `is` canot reference a model expression.",
"type": "minor"
}
],
"packageName": "@cadl-lang/compiler"
}

Просмотреть файл

@ -2191,6 +2191,14 @@ export function createChecker(program: Program): Checker {
heritageRef: Expression,
mapper: TypeMapper | undefined
): Model | undefined {
if (heritageRef.kind === SyntaxKind.ModelExpression) {
reportDiagnostic(program, {
code: "extend-model",
messageId: "modelExpression",
target: heritageRef,
});
return undefined;
}
if (heritageRef.kind !== SyntaxKind.TypeReference) {
reportDiagnostic(program, {
code: "extend-model",
@ -2228,6 +2236,14 @@ export function createChecker(program: Program): Checker {
return undefined;
}
if (heritageType.name === "") {
reportDiagnostic(program, {
code: "extend-model",
messageId: "modelExpression",
target: heritageRef,
});
}
if (isIntrinsic(program, heritageType)) {
program.reportDiagnostic(
createDiagnostic({
@ -2254,7 +2270,14 @@ export function createChecker(program: Program): Checker {
const modelSymId = getNodeSymId(model);
pendingResolutions.add(modelSymId);
let isType;
if (isExpr.kind === SyntaxKind.ArrayExpression) {
if (isExpr.kind === SyntaxKind.ModelExpression) {
reportDiagnostic(program, {
code: "is-model",
messageId: "modelExpression",
target: isExpr,
});
return undefined;
} else if (isExpr.kind === SyntaxKind.ArrayExpression) {
isType = checkArrayExpression(isExpr, mapper);
} else if (isExpr.kind === SyntaxKind.TypeReference) {
const target = resolveTypeReference(isExpr, mapper);
@ -2284,6 +2307,10 @@ export function createChecker(program: Program): Checker {
return;
}
if (isType.name === "") {
reportDiagnostic(program, { code: "is-model", messageId: "modelExpression", target: isExpr });
}
return isType;
}

Просмотреть файл

@ -282,6 +282,7 @@ const diagnostics = {
severity: "error",
messages: {
default: "Models must extend other models.",
modelExpression: "Models cannot extend model expressions.",
},
},
"extend-primitive": {
@ -294,6 +295,7 @@ const diagnostics = {
severity: "error",
messages: {
default: "Model `is` must specify another model.",
modelExpression: "Model `is` cannot specify a model expression.",
},
},
"is-operation": {

Просмотреть файл

@ -318,6 +318,35 @@ describe("compiler: models", () => {
});
});
it("emit error when extend model expression", async () => {
testHost.addCadlFile(
"main.cadl",
`
model A extends {name: string} {}
`
);
const diagnostics = await testHost.diagnose("main.cadl");
expectDiagnostics(diagnostics, {
code: "extend-model",
message: "Models cannot extend model expressions.",
});
});
it("emit error when extend model expression via alias", async () => {
testHost.addCadlFile(
"main.cadl",
`
alias B = {name: string};
model A extends B {}
`
);
const diagnostics = await testHost.diagnose("main.cadl");
expectDiagnostics(diagnostics, {
code: "extend-model",
message: "Models cannot extend model expressions.",
});
});
it("emit error when extends itself", async () => {
testHost.addCadlFile(
"main.cadl",
@ -475,6 +504,35 @@ describe("compiler: models", () => {
});
});
it("emit error when is model expression", async () => {
testHost.addCadlFile(
"main.cadl",
`
model A is {name: string} {}
`
);
const diagnostics = await testHost.diagnose("main.cadl");
expectDiagnostics(diagnostics, {
code: "is-model",
message: "Model `is` cannot specify a model expression.",
});
});
it("emit error when is model expression via alias", async () => {
testHost.addCadlFile(
"main.cadl",
`
alias B = {name: string};
model A is B {}
`
);
const diagnostics = await testHost.diagnose("main.cadl");
expectDiagnostics(diagnostics, {
code: "is-model",
message: "Model `is` cannot specify a model expression.",
});
});
it("emit error when is itself", async () => {
testHost.addCadlFile(
"main.cadl",