Fix mapper node set in model expression (#4144)

fix [#3935](https://github.com/microsoft/typespec/issues/3935)

---------

Co-authored-by: Mark Cowlishaw <markcowl@microsoft.com>
This commit is contained in:
Timothee Guerin 2024-08-12 15:05:30 -07:00 коммит произвёл GitHub
Родитель 3775eec3bc
Коммит 712aa4f385
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
4 изменённых файлов: 83 добавлений и 0 удалений

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

@ -0,0 +1,8 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: fix
packages:
- "@typespec/compiler"
---
Fix: Model and union expression in template were not considered as template instances

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

@ -2007,6 +2007,8 @@ export function createChecker(program: Program): Checker {
}
}
linkMapper(unionType, mapper);
return unionType;
}
@ -4010,6 +4012,7 @@ export function createChecker(program: Program): Checker {
derivedModels: [],
sourceModels: [],
});
linkMapper(type, mapper);
checkModelProperties(node, properties, type, mapper);
return finishType(type);
}

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

@ -45,6 +45,36 @@ describe("compiler: type-utils", () => {
ok(isTemplateInstance(Foo), "Should BE a template instance");
ok(!isTemplateDeclaration(Foo), "Should NOT be a template declaration");
});
it("check model expression inside a template instance is also a template instance", async () => {
const { Bar } = (await runner.compile(`
model Foo<T> {a: { b: T }};
@test model Bar {
foo: Foo<string>
}
`)) as { Bar: Model };
const Foo = Bar.properties.get("foo")!.type as Model;
const expr = Foo.properties.get("a")!.type;
ok(isTemplateInstance(expr), "Should BE a template instance");
ok(!isTemplateDeclaration(expr), "Should NOT be a template declaration");
});
it("check union expression inside a template instance is also a template instance", async () => {
const { Bar } = (await runner.compile(`
model Foo<T> {a: int32 | T};
@test model Bar {
foo: Foo<string>
}
`)) as { Bar: Model };
const Foo = Bar.properties.get("foo")!.type as Model;
const expr = Foo.properties.get("a")!.type;
ok(isTemplateInstance(expr), "Should BE a template instance");
ok(!isTemplateDeclaration(expr), "Should NOT be a template declaration");
});
});
describe("definition utils", () => {

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

@ -208,6 +208,48 @@ describe("versioning: reference versioned library", () => {
"The provided version 'v2' from 'TestServiceVersions' is not declared as a version enum. Use '@versioned(TestServiceVersions)' on the containing namespace.",
});
});
it("doesn't emit diagnostic when library template with model expression instantiated with user model", async () => {
const diagnostics = await runner.diagnose(`
namespace Library {
model Template<T> {
a: {
b: T;
};
}
}
@versioned(Versions)
namespace Api {
enum Versions { v1 }
model Model {}
model Issue is Library.Template<Model>;
}
`);
expectDiagnosticEmpty(diagnostics);
});
it("doesn't emit diagnostic when library template with union expression instantiated with user model", async () => {
const diagnostics = await runner.diagnose(`
namespace Library {
model Template<T> {
a: string | T;
}
}
@versioned(Versions)
namespace Api {
enum Versions { v1 }
model Model {}
model Issue is Library.Template<Model>;
}
`);
expectDiagnosticEmpty(diagnostics);
});
});
describe("when using versioned library without @useDependency", () => {