From a61b35162f2002a3fdd5e0ac47efa8b6e9bebc23 Mon Sep 17 00:00:00 2001 From: Chenjie Shi Date: Sat, 24 Feb 2024 03:29:56 +0800 Subject: [PATCH] Add usage calculation for additional properties with model type (#301) --- ...additional_properties-2024-1-23-18-7-29.md | 7 ++++ .../src/types.ts | 12 +++++++ .../test/types.test.ts | 33 +++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 .chronus/changes/fix_usage_for_additional_properties-2024-1-23-18-7-29.md diff --git a/.chronus/changes/fix_usage_for_additional_properties-2024-1-23-18-7-29.md b/.chronus/changes/fix_usage_for_additional_properties-2024-1-23-18-7-29.md new file mode 100644 index 0000000000..c94b8f2e7c --- /dev/null +++ b/.chronus/changes/fix_usage_for_additional_properties-2024-1-23-18-7-29.md @@ -0,0 +1,7 @@ +--- +changeKind: fix +packages: + - "@azure-tools/typespec-client-generator-core" +--- + +Add usage calculation for additional properties with model type \ No newline at end of file diff --git a/packages/typespec-client-generator-core/src/types.ts b/packages/typespec-client-generator-core/src/types.ts index 887227daec..f381b9a1a0 100644 --- a/packages/typespec-client-generator-core/src/types.ts +++ b/packages/typespec-client-generator-core/src/types.ts @@ -931,6 +931,7 @@ function updateModelsMap(context: SdkContext, type: Type, sdkType: SdkType, oper } else { context.operationModelsMap.set(operation, new Map([[type, sdkType]])); } + // TODO: it seems duplicate calculation, need to optimize later if (sdkType.kind === "model") { for (const prop of sdkType.properties) { if (prop.type.kind === "model" || prop.type.kind === "enum") { @@ -953,6 +954,14 @@ function updateModelsMap(context: SdkContext, type: Type, sdkType: SdkType, oper if (sdkType.baseModel) { updateModelsMap(context, sdkType.baseModel.__raw as any, sdkType.baseModel, operation); } + if (sdkType.additionalProperties) { + updateModelsMap( + context, + sdkType.additionalProperties.__raw as any, + sdkType.additionalProperties, + operation + ); + } if (sdkType.discriminatedSubtypes) { for (const subtype of Object.values(sdkType.discriminatedSubtypes)) { updateModelsMap(context, subtype.__raw as any, subtype, operation); @@ -1020,6 +1029,9 @@ function updateUsageOfModel( updateUsageOfModel(context, discriminatedSubtype, usage, seenModelNames); } } + if (type.additionalProperties) { + updateUsageOfModel(context, type.additionalProperties, usage, seenModelNames); + } for (const property of type.properties) { updateUsageOfModel(context, property.type, usage, seenModelNames); } diff --git a/packages/typespec-client-generator-core/test/types.test.ts b/packages/typespec-client-generator-core/test/types.test.ts index c4bab9c57f..a3ca9c6253 100644 --- a/packages/typespec-client-generator-core/test/types.test.ts +++ b/packages/typespec-client-generator-core/test/types.test.ts @@ -1907,6 +1907,39 @@ describe("typespec-client-generator-core: types", () => { strictEqual(AdditionalPropertiesModel2.baseModel, undefined); strictEqual(NonAdditionalPropertiesModel.additionalProperties, undefined); }); + it("additionalProperties usage", async () => { + await runner.compileWithBuiltInService(` + @service({}) + namespace MyService { + model AdditionalPropertiesModel extends Record { + } + + model AdditionalPropertiesModel2 is Record { + } + + model Test { + } + + op test(@body input: AdditionalPropertiesModel): AdditionalPropertiesModel2; + } + `); + const models = getAllModelsAssertNoDiagnostics(runner.context); + strictEqual(models.length, 3); + const AdditionalPropertiesModel = models.find( + (x) => x.name === "AdditionalPropertiesModel" + )! as SdkModelType; + const AdditionalPropertiesModel2 = models.find( + (x) => x.name === "AdditionalPropertiesModel2" + )! as SdkModelType; + const Test = models.find((x) => x.name === "Test")! as SdkModelType; + strictEqual(AdditionalPropertiesModel.additionalProperties?.kind, "model"); + strictEqual(AdditionalPropertiesModel.baseModel, undefined); + strictEqual(AdditionalPropertiesModel.usage, UsageFlags.Input); + strictEqual(AdditionalPropertiesModel2.additionalProperties?.kind, "model"); + strictEqual(AdditionalPropertiesModel2.baseModel, undefined); + strictEqual(AdditionalPropertiesModel2.usage, UsageFlags.Output); + strictEqual(Test.usage, UsageFlags.Input | UsageFlags.Output); + }); it("crossLanguageDefinitionId", async () => { await runner.compile(` @service({})