From 4e421a3ef82d08dc1391d92b9c7d4172ffe7f7a1 Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Wed, 24 Apr 2024 09:06:47 -0700 Subject: [PATCH 1/3] Fix stop running decorators on partially instantiated operations --- packages/compiler/src/core/checker.ts | 2 +- packages/compiler/src/core/projector.ts | 4 ++- .../compiler/test/checker/interface.test.ts | 25 +++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/packages/compiler/src/core/checker.ts b/packages/compiler/src/core/checker.ts index 0a57dd3e69..0ac906ca26 100644 --- a/packages/compiler/src/core/checker.ts +++ b/packages/compiler/src/core/checker.ts @@ -2865,7 +2865,7 @@ export function createChecker(program: Program): Checker { } // Some of the mapper args are still template parameter so we shouldn't create the type. - return mapper.args.every((t) => t.kind !== "TemplateParameter"); + return !mapper.partial && mapper.args.every((t) => t.kind !== "TemplateParameter"); } function checkModelExpression(node: ModelExpressionNode, mapper: TypeMapper | undefined) { diff --git a/packages/compiler/src/core/projector.ts b/packages/compiler/src/core/projector.ts index 4716174afe..b33e3e19b9 100644 --- a/packages/compiler/src/core/projector.ts +++ b/packages/compiler/src/core/projector.ts @@ -416,7 +416,9 @@ export function createProjector( projectedOp.namespace = projectedNamespaceScope(); } - finishTypeForProgram(projectedProgram, projectedOp); + if (op.isFinished) { + finishTypeForProgram(projectedProgram, projectedOp); + } if (op.interface) { projectedOp.interface = projectType(op.interface) as Interface; } diff --git a/packages/compiler/test/checker/interface.test.ts b/packages/compiler/test/checker/interface.test.ts index 47b396e52b..65799efd29 100644 --- a/packages/compiler/test/checker/interface.test.ts +++ b/packages/compiler/test/checker/interface.test.ts @@ -410,6 +410,31 @@ describe("compiler: interfaces", () => { strictEqual(returnType.name, "int32"); }); + it("instantiating an templated interface doesn't finish template operation inside", async () => { + const blues = new WeakSet(); + let calls = 0; + testHost.addJsFile("dec.js", { + $blue(p: any, t: Type) { + calls++; + blues.add(t); + }, + }); + testHost.addTypeSpecFile( + "main.tsp", + ` + import "./dec.js"; + + interface Base { + @blue bar(input: A): B; + } + + alias My = Base; + ` + ); + await testHost.compile("./"); + strictEqual(calls, 0); + }); + it("emit warning if shadowing parent templated type", async () => { const diagnostics = await runner.diagnose(` interface Base { From c1587113ec2cf932888f01458dd4fc7f07db7b6c Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Wed, 24 Apr 2024 09:10:39 -0700 Subject: [PATCH 2/3] cleaner test --- .../compiler/test/checker/interface.test.ts | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/packages/compiler/test/checker/interface.test.ts b/packages/compiler/test/checker/interface.test.ts index 65799efd29..5b3b4b5bd9 100644 --- a/packages/compiler/test/checker/interface.test.ts +++ b/packages/compiler/test/checker/interface.test.ts @@ -1,5 +1,5 @@ import { deepStrictEqual, notStrictEqual, ok, strictEqual } from "assert"; -import { beforeEach, describe, it } from "vitest"; +import { beforeEach, describe, expect, it, vi } from "vitest"; import { isTemplateDeclaration } from "../../src/core/type-utils.js"; import { Interface, Model, Operation, Type } from "../../src/core/types.js"; import { getDoc } from "../../src/index.js"; @@ -411,28 +411,22 @@ describe("compiler: interfaces", () => { }); it("instantiating an templated interface doesn't finish template operation inside", async () => { - const blues = new WeakSet(); - let calls = 0; - testHost.addJsFile("dec.js", { - $blue(p: any, t: Type) { - calls++; - blues.add(t); - }, - }); + const $track = vi.fn(); + testHost.addJsFile("dec.js", { $track }); testHost.addTypeSpecFile( "main.tsp", ` import "./dec.js"; - interface Base { - @blue bar(input: A): B; + interface Base { + @track bar(input: A): B; } alias My = Base; ` ); await testHost.compile("./"); - strictEqual(calls, 0); + expect($track).not.toHaveBeenCalled(); }); it("emit warning if shadowing parent templated type", async () => { From cba373b750b259e88c40b64dbc69c805ba8edb4f Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Wed, 24 Apr 2024 09:11:13 -0700 Subject: [PATCH 3/3] Create fix-unfinished-partial-ops-2024-3-24-16-10-25.md --- .../fix-unfinished-partial-ops-2024-3-24-16-10-25.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .chronus/changes/fix-unfinished-partial-ops-2024-3-24-16-10-25.md diff --git a/.chronus/changes/fix-unfinished-partial-ops-2024-3-24-16-10-25.md b/.chronus/changes/fix-unfinished-partial-ops-2024-3-24-16-10-25.md new file mode 100644 index 0000000000..fa9e1307e6 --- /dev/null +++ b/.chronus/changes/fix-unfinished-partial-ops-2024-3-24-16-10-25.md @@ -0,0 +1,8 @@ +--- +# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking +changeKind: fix +packages: + - "@typespec/compiler" +--- + +Stop running decorators on partially instantiated operations(When interface is instantiated but not the operation)