Skip to content

Commit

Permalink
Merge branch 'main' into fix-tcgc
Browse files Browse the repository at this point in the history
  • Loading branch information
iscai-msft authored Mar 13, 2024
2 parents 3161ca1 + 4e37bca commit 4db0890
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 1 deletion.
7 changes: 7 additions & 0 deletions .chronus/changes/discriminator-property-2024-2-12-14-10-27.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: feature
packages:
- "@azure-tools/typespec-client-generator-core"
---

add `discriminatorProperty` ref to discriminated model
7 changes: 7 additions & 0 deletions .chronus/changes/prevent-carry-over-2024-2-13-14-34-30.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: fix
packages:
- "@azure-tools/typespec-client-generator-core"
---

prevent carry over for `@clientName`
2 changes: 2 additions & 0 deletions packages/typespec-client-generator-core/doc/types.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ model SdkUnionType extends SdkType {
* @property additionalProperties: Model's additional properties type, if no additional properties, then undefined
* @property discriminatorValue: Value of the discriminator if this is a discriminated subtype. Will be undefined if not.
* @property discriminatedSubtypes: Mapping of discriminator value to this models discriminated subtypes if there are any.
* @property discriminatorProperty: The property that is the discriminator for this model if it's a discriminated subtype. Will be undefined if not.
* @property baseModel: The base model class of this model type if one exists.
*/
model SdkModelType extends SdkType {
Expand All @@ -236,6 +237,7 @@ model SdkModelType extends SdkType {
additionalProperties?: SdkType;
discriminatorValue?: string;
discriminatedSubtypes?: Record<SdkModelType>;
discriminatorProperty?: SdkModelPropertyType;
baseModel?: SdkModelType;
nameSpace: string;
}
Expand Down
24 changes: 24 additions & 0 deletions packages/typespec-client-generator-core/src/decorators.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {
AugmentDecoratorStatementNode,
DecoratorContext,
DecoratorExpressionNode,
DecoratorFunction,
EmitContext,
Enum,
Expand All @@ -16,6 +18,7 @@ import {
Union,
getNamespaceFullName,
getProjectedName,
ignoreDiagnostics,
isService,
isTemplateDeclaration,
isTemplateDeclarationOrInstance,
Expand Down Expand Up @@ -827,6 +830,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);
}

Expand Down
1 change: 1 addition & 0 deletions packages/typespec-client-generator-core/src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ export interface SdkModelType extends SdkTypeBase {
additionalProperties?: SdkType;
discriminatorValue?: string;
discriminatedSubtypes?: Record<string, SdkModelType>;
discriminatorProperty?: SdkModelPropertyType;
baseModel?: SdkModelType;
crossLanguageDefinitionId: string;
apiVersions: string[];
Expand Down
2 changes: 2 additions & 0 deletions packages/typespec-client-generator-core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,7 @@ function addDiscriminatorToModelType(
const property = model.properties[i];
if (property.kind === "property" && property.serializedName === discriminator.propertyName) {
property.discriminator = true;
model.discriminatorProperty = property;
return diagnostics.wrap(undefined);
}
}
Expand Down Expand Up @@ -480,6 +481,7 @@ function addDiscriminatorToModelType(
isMultipartFileInput: false, // discriminator property cannot be a file
flatten: false, // discriminator properties can not be flattened
});
model.discriminatorProperty = model.properties[model.properties.length - 1];
}
return diagnostics.wrap(undefined);
}
Expand Down
65 changes: 65 additions & 0 deletions packages/typespec-client-generator-core/test/decorators.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { beforeEach, describe, it } from "vitest";
import {
getAccess,
getClient,
getClientNameOverride,
getOperationGroup,
getUsage,
listClients,
Expand Down Expand Up @@ -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);
});
});
});
5 changes: 5 additions & 0 deletions packages/typespec-client-generator-core/test/types.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1573,13 +1573,15 @@ describe("typespec-client-generator-core: types", () => {
strictEqual(kindProperty.discriminator, true);
strictEqual(kindProperty.type.kind, "string");
strictEqual(kindProperty.__raw, undefined);
strictEqual(fish.discriminatorProperty, kindProperty);
const shark = models.find((x) => x.name === "Shark")! as SdkModelType;
strictEqual(shark.properties.length, 2);
const sharktypeProperty = shark.properties.find(
(x) => x.nameInClient === "sharktype"
)! as SdkBodyModelPropertyType;
strictEqual(sharktypeProperty.discriminator, true);
strictEqual(sharktypeProperty.type.kind, "string");
strictEqual(shark.discriminatorProperty, sharktypeProperty);
});

it("single discriminated model", async () => {
Expand All @@ -1602,6 +1604,7 @@ describe("typespec-client-generator-core: types", () => {
strictEqual(kindProperty.type.kind, "string");
strictEqual(kindProperty.__raw, undefined);
strictEqual(kindProperty.type.__raw, undefined);
strictEqual(fish.discriminatorProperty, kindProperty);
});

it("enum discriminator model", async () => {
Expand Down Expand Up @@ -1642,6 +1645,7 @@ describe("typespec-client-generator-core: types", () => {
(x) => (x as SdkBodyModelPropertyType).serializedName === "kind"
)! as SdkBodyModelPropertyType;
strictEqual(dogKindProperty.type, dogKind);
strictEqual(dog.discriminatorProperty, dogKindProperty);
});

it("union to extensible enum values", async () => {
Expand Down Expand Up @@ -1843,6 +1847,7 @@ describe("typespec-client-generator-core: types", () => {
const fish = models.find((x) => x.name === "Fish")!;
let kindTypeProperty = fish.properties.find((x) => x.nameInClient === "kind")!;
strictEqual(kindTypeProperty.type.kind, "enum");
strictEqual(fish.discriminatorProperty, kindTypeProperty);
const shark = models.find((x) => x.name === "Shark")!;
strictEqual(shark.discriminatorValue, "shark");
kindTypeProperty = shark.properties.find((x) => x.nameInClient === "kind")!;
Expand Down

0 comments on commit 4db0890

Please sign in to comment.