Skip to content

Commit 6e554b8

Browse files
Fix: Property getting wrongly finished when used inside union expression or operation inside interface template (#7183)
fix #7181
1 parent db65b12 commit 6e554b8

File tree

5 files changed

+73
-54
lines changed

5 files changed

+73
-54
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
3+
changeKind: fix
4+
packages:
5+
- "@typespec/compiler"
6+
---
7+
8+
Fix decorators on model properties getting wrongly called when checking the template declaration in the following cases
9+
- inside a union expression
10+
- under an non templated operation under a templated interface

packages/compiler/src/core/type-utils.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,22 @@ export function getParentTemplateNode(node: Node): (Node & TemplateDeclarationNo
7474
switch (node.kind) {
7575
case SyntaxKind.ModelStatement:
7676
case SyntaxKind.ScalarStatement:
77-
case SyntaxKind.OperationStatement:
7877
case SyntaxKind.UnionStatement:
7978
case SyntaxKind.InterfaceStatement:
8079
return node.templateParameters.length > 0 ? node : undefined;
80+
case SyntaxKind.OperationStatement:
81+
return node.templateParameters.length > 0
82+
? node
83+
: node.parent?.kind === SyntaxKind.InterfaceStatement
84+
? node.parent.templateParameters.length > 0
85+
? node.parent
86+
: undefined
87+
: undefined;
8188
case SyntaxKind.OperationSignatureDeclaration:
8289
case SyntaxKind.ModelProperty:
90+
case SyntaxKind.UnionVariant:
8391
case SyntaxKind.ModelExpression:
92+
case SyntaxKind.UnionExpression:
8493
return node.parent ? getParentTemplateNode(node.parent) : undefined;
8594
default:
8695
return undefined;

packages/compiler/test/checker/interface.test.ts

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -250,26 +250,6 @@ describe("compiler: interfaces", () => {
250250
});
251251
});
252252

253-
it("doesn't invoke decorators on uninstantiated templates", async () => {
254-
const blues = new WeakSet();
255-
let calls = 0;
256-
testHost.addJsFile("dec.js", {
257-
$blue(p: any, t: Type) {
258-
calls++;
259-
blues.add(t);
260-
},
261-
});
262-
testHost.addTypeSpecFile(
263-
"main.tsp",
264-
`
265-
import "./dec.js";
266-
@blue interface A<T> { @blue foo(): int32}
267-
`,
268-
);
269-
await testHost.compile("./");
270-
strictEqual(calls, 0);
271-
});
272-
273253
describe("templated operations", () => {
274254
it("can instantiate template operation inside non-templated interface", async () => {
275255
const { Foo, bar } = (await runner.compile(`

packages/compiler/test/checker/model.test.ts

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -68,26 +68,6 @@ describe("compiler: models", () => {
6868
match(diagnostics[0].message, /Model already has a property/);
6969
});
7070

71-
it("doesn't invoke decorators on uninstantiated templates", async () => {
72-
const blues = new WeakSet();
73-
let calls = 0;
74-
testHost.addJsFile("dec.js", {
75-
$blue(p: any, t: Type) {
76-
calls++;
77-
blues.add(t);
78-
},
79-
});
80-
testHost.addTypeSpecFile(
81-
"main.tsp",
82-
`
83-
import "./dec.js";
84-
@blue model A<T> { @blue x: int32}
85-
`,
86-
);
87-
await testHost.compile("./");
88-
strictEqual(calls, 0);
89-
});
90-
9171
it("emit single error when there is an invalid ref in a templated type", async () => {
9272
testHost.addTypeSpecFile(
9373
"main.tsp",

packages/compiler/test/checker/templates.test.ts

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,7 @@ describe("compiler: templates", () => {
624624
});
625625
});
626626

627-
describe("doesn't run decorators on model properties when projecting template declarations", () => {
627+
describe("doesn't run decorators when checking template declarations", () => {
628628
async function expectMarkDecoratorNotCalled(code: string) {
629629
testHost.addJsFile("mark.js", {
630630
$mark: () => fail("Should not have called decorator"),
@@ -643,40 +643,80 @@ describe("compiler: templates", () => {
643643

644644
it("on model", async () => {
645645
await expectMarkDecoratorNotCalled(`
646-
model Foo<T> {
647-
@mark(T)
648-
prop: string;
649-
}
650-
`);
646+
@mark(T)
647+
model Foo<T> {}
648+
`);
649+
});
650+
651+
it("on interface", async () => {
652+
await expectMarkDecoratorNotCalled(`
653+
@mark(T)
654+
interface Foo<T> {}
655+
`);
656+
});
657+
658+
it("on operation", async () => {
659+
await expectMarkDecoratorNotCalled(`
660+
@mark(T)
661+
op foo<T>(): void;
662+
`);
651663
});
652664

653-
it("on model properties", async () => {
665+
it("on union", async () => {
654666
await expectMarkDecoratorNotCalled(`
667+
@mark(T)
668+
union Foo<T> {}
669+
`);
670+
});
671+
672+
describe("on model properties", () => {
673+
it("under model", async () => {
674+
await expectMarkDecoratorNotCalled(`
655675
model Foo<T> {
656676
@mark(T)
657677
prop: string;
658678
}
659679
`);
660-
});
680+
});
661681

662-
it("on model properties (on operation)", async () => {
663-
await expectMarkDecoratorNotCalled(`
682+
it("under operation returnType", async () => {
683+
await expectMarkDecoratorNotCalled(`
664684
op foo<T>(): {
665685
@mark(T)
666686
prop: string;
667687
};
668688
`);
669-
});
689+
});
670690

671-
it("on model properties (nested)", async () => {
672-
await expectMarkDecoratorNotCalled(`
691+
it("in operation in interface", async () => {
692+
await expectMarkDecoratorNotCalled(`
693+
interface Test<T> {
694+
foo(@mark(T) prop: string;): void;
695+
}
696+
`);
697+
});
698+
699+
it("nested", async () => {
700+
await expectMarkDecoratorNotCalled(`
673701
model Foo<T> {
674702
nested: {
675703
@mark(T)
676704
prop: string;
677705
}
678706
}
679707
`);
708+
});
709+
710+
it("nested in union", async () => {
711+
await expectMarkDecoratorNotCalled(`
712+
model Foo<T> {
713+
nested: string | {
714+
@mark(T)
715+
prop: string;
716+
}
717+
}
718+
`);
719+
});
680720
});
681721
});
682722

0 commit comments

Comments
 (0)