diff --git a/.chronus/changes/prevent-carry-over-2024-2-13-14-34-30.md b/.chronus/changes/prevent-carry-over-2024-2-13-14-34-30.md new file mode 100644 index 0000000000..aca50ecb89 --- /dev/null +++ b/.chronus/changes/prevent-carry-over-2024-2-13-14-34-30.md @@ -0,0 +1,7 @@ +--- +changeKind: fix +packages: + - "@azure-tools/typespec-client-generator-core" +--- + +prevent carry over for `@clientName` \ No newline at end of file diff --git a/packages/typespec-client-generator-core/src/decorators.ts b/packages/typespec-client-generator-core/src/decorators.ts index 279975806f..32a3c7f7bf 100644 --- a/packages/typespec-client-generator-core/src/decorators.ts +++ b/packages/typespec-client-generator-core/src/decorators.ts @@ -1,5 +1,7 @@ import { + AugmentDecoratorStatementNode, DecoratorContext, + DecoratorExpressionNode, DecoratorFunction, EmitContext, Enum, @@ -16,6 +18,7 @@ import { Union, getNamespaceFullName, getProjectedName, + ignoreDiagnostics, isService, isTemplateDeclaration, isTemplateDeclarationOrInstance, @@ -818,6 +821,27 @@ export function $clientName( value: string, scope?: LanguageScopes ) { + // workaround for current lack of functionality in compiler + // https://github.com/microsoft/typespec/issues/2717 + if (entity.kind === "Model" || entity.kind === "Operation") { + if ((context.decoratorTarget as Node).kind === SyntaxKind.AugmentDecoratorStatement) { + if ( + ignoreDiagnostics( + context.program.checker.resolveTypeReference( + (context.decoratorTarget as AugmentDecoratorStatementNode).targetType + ) + ) !== entity + ) { + return; + } + } + if ((context.decoratorTarget as Node).kind === SyntaxKind.DecoratorExpression) { + if ((context.decoratorTarget as DecoratorExpressionNode).parent !== entity.node) { + return; + } + } + } + setScopedDecoratorData(context, $clientName, clientNameKey, entity, value, scope); } diff --git a/packages/typespec-client-generator-core/test/decorators.test.ts b/packages/typespec-client-generator-core/test/decorators.test.ts index 592e0fe0eb..e31fa3b73f 100644 --- a/packages/typespec-client-generator-core/test/decorators.test.ts +++ b/packages/typespec-client-generator-core/test/decorators.test.ts @@ -13,6 +13,7 @@ import { beforeEach, describe, it } from "vitest"; import { getAccess, getClient, + getClientNameOverride, getOperationGroup, getUsage, listClients, @@ -2350,4 +2351,68 @@ describe("typespec-client-generator-core: decorators", () => { }); }); }); + + describe("@clientName", () => { + it("carry over", async () => { + const { Test1, Test2, func1, func2 } = (await runner.compile(` + @service({}) + @test namespace MyService { + @test + @clientName("Test1Rename") + model Test1{} + + @test + model Test2 is Test1{} + + @test + @route("/func1") + @clientName("func1Rename") + op func1(): void; + + @test + @route("/func2") + op func2 is func1; + } + `)) as { Test1: Model; Test2: Model; func1: Operation; func2: Operation }; + + strictEqual(getClientNameOverride(runner.context, Test1), "Test1Rename"); + strictEqual(getClientNameOverride(runner.context, Test2), undefined); + strictEqual(getClientNameOverride(runner.context, func1), "func1Rename"); + strictEqual(getClientNameOverride(runner.context, func2), undefined); + }); + + it("augment carry over", async () => { + const { Test1, Test2, func1, func2 } = (await runner.compileWithCustomization( + ` + @service({}) + @test namespace MyService { + @test + model Test1{} + + @test + model Test2 is Test1{} + + @test + @route("/func1") + op func1(): void; + + @test + @route("/func2") + op func2 is func1; + } + `, + ` + namespace Customizations; + + @@clientName(MyService.Test1, "Test1Rename"); + @@clientName(MyService.func1, "func1Rename"); + ` + )) as { Test1: Model; Test2: Model; func1: Operation; func2: Operation }; + + strictEqual(getClientNameOverride(runner.context, Test1), "Test1Rename"); + strictEqual(getClientNameOverride(runner.context, Test2), undefined); + strictEqual(getClientNameOverride(runner.context, func1), "func1Rename"); + strictEqual(getClientNameOverride(runner.context, func2), undefined); + }); + }); });