diff --git a/.chronus/changes/refine_tcgc_logic-2024-3-2-16-27-30.md b/.chronus/changes/refine_tcgc_logic-2024-3-2-16-27-30.md new file mode 100644 index 0000000000..00d61508ea --- /dev/null +++ b/.chronus/changes/refine_tcgc_logic-2024-3-2-16-27-30.md @@ -0,0 +1,7 @@ +--- +changeKind: fix +packages: + - "@azure-tools/typespec-client-generator-core" +--- + +Set spread model with none usage \ No newline at end of file diff --git a/.chronus/changes/refine_tcgc_logic-2024-3-2-16-27-52.md b/.chronus/changes/refine_tcgc_logic-2024-3-2-16-27-52.md new file mode 100644 index 0000000000..aed6e18e77 --- /dev/null +++ b/.chronus/changes/refine_tcgc_logic-2024-3-2-16-27-52.md @@ -0,0 +1,7 @@ +--- +changeKind: feature +packages: + - "@azure-tools/typespec-client-generator-core" +--- + +Workaround for arm provider method parameter \ No newline at end of file diff --git a/packages/typespec-client-generator-core/package.json b/packages/typespec-client-generator-core/package.json index 1a94180ad2..bb637cd39a 100644 --- a/packages/typespec-client-generator-core/package.json +++ b/packages/typespec-client-generator-core/package.json @@ -57,6 +57,7 @@ "pluralize": "^8.0.0" }, "peerDependencies": { + "@azure-tools/typespec-azure-core": "workspace:~", "@typespec/compiler": "workspace:~", "@typespec/http": "workspace:~", "@typespec/rest": "workspace:~", diff --git a/packages/typespec-client-generator-core/src/internal-utils.ts b/packages/typespec-client-generator-core/src/internal-utils.ts index c1bfa84955..f8d8d0007e 100644 --- a/packages/typespec-client-generator-core/src/internal-utils.ts +++ b/packages/typespec-client-generator-core/src/internal-utils.ts @@ -205,9 +205,7 @@ export function isAzureCoreModel(t: Type): boolean { return ( t.kind === "Model" && t.namespace !== undefined && - ["Azure.Core", "Azure.Core.Foundations", "Azure.ResourceManager"].includes( - getNamespaceFullName(t.namespace) - ) + ["Azure.Core", "Azure.Core.Foundations"].includes(getNamespaceFullName(t.namespace)) ); } diff --git a/packages/typespec-client-generator-core/src/package.ts b/packages/typespec-client-generator-core/src/package.ts index db315af026..01f306ee62 100644 --- a/packages/typespec-client-generator-core/src/package.ts +++ b/packages/typespec-client-generator-core/src/package.ts @@ -234,9 +234,9 @@ function getSdkBasicServiceMethod< ); } } else { - const methodParameter = diagnostics.pipe(getSdkMethodParameter(context, prop)); - if (methodParameter.kind === "method") { - methodParameters.push(methodParameter); + // workaround for the provider parameter in arm, need to refine method design in tcgc later + if (!context.arm || prop.name !== "provider") { + methodParameters.push(diagnostics.pipe(getSdkMethodParameter(context, prop))); } } } diff --git a/packages/typespec-client-generator-core/src/public-utils.ts b/packages/typespec-client-generator-core/src/public-utils.ts index 42f76c76f5..e006bb489f 100644 --- a/packages/typespec-client-generator-core/src/public-utils.ts +++ b/packages/typespec-client-generator-core/src/public-utils.ts @@ -1,5 +1,6 @@ import { Diagnostic, + Enum, Interface, Model, ModelProperty, @@ -175,7 +176,7 @@ export function getLibraryName( type.name + type.templateMapper.args .filter( - (arg): arg is Model => + (arg): arg is Model | Enum => (arg.kind === "Model" || arg.kind === "Enum") && arg.name.length > 0 ) .map((arg) => pascalCase(arg.name)) diff --git a/packages/typespec-client-generator-core/src/types.ts b/packages/typespec-client-generator-core/src/types.ts index 85f27c8a5a..397190c9c6 100644 --- a/packages/typespec-client-generator-core/src/types.ts +++ b/packages/typespec-client-generator-core/src/types.ts @@ -1127,7 +1127,7 @@ function checkAndGetClientType( interface ModelUsageOptions { seenModelNames?: Set; - recurseThroughProperties?: boolean; + propagation?: boolean; } function updateUsageOfModel( @@ -1137,7 +1137,7 @@ function updateUsageOfModel( options?: ModelUsageOptions ): void { options = options ?? {}; - options.recurseThroughProperties = options?.recurseThroughProperties ?? true; + options.propagation = options?.propagation ?? true; if (!type || !["model", "enum", "array", "dict", "union", "enumvalue"].includes(type.kind)) return; if (options?.seenModelNames === undefined) { @@ -1168,10 +1168,7 @@ function updateUsageOfModel( } if (type.kind === "enum") return; - if (type.baseModel && (type.baseModel.usage & usage) === 0) { - // if it has a base model and the base model doesn't currently have that usage - type.baseModel.usage |= usage; - } + if (!options.propagation) return; if (type.baseModel) { updateUsageOfModel(context, usage, type.baseModel, options); } @@ -1180,13 +1177,11 @@ function updateUsageOfModel( updateUsageOfModel(context, usage, discriminatedSubtype, options); } } - if (type.additionalProperties && options.recurseThroughProperties) { + if (type.additionalProperties) { updateUsageOfModel(context, usage, type.additionalProperties, options); } - if (options.recurseThroughProperties) { - for (const property of type.properties) { - updateUsageOfModel(context, usage, property.type, options); - } + for (const property of type.properties) { + updateUsageOfModel(context, usage, property.type, options); } } @@ -1221,6 +1216,8 @@ function updateTypesFromOperation( const bodies = diagnostics.pipe(checkAndGetClientType(context, httpBody.type, operation)); if (generateConvenient) { bodies.forEach((body) => { + // spread body model should be none usage + if (body.kind === "model" && body.isGeneratedName) return; updateUsageOfModel(context, UsageFlags.Input, body); }); if (httpBody.contentTypes.includes("application/merge-patch+json")) { @@ -1232,7 +1229,7 @@ function updateTypesFromOperation( if (isMultipartFormData(context, httpBody.type, operation)) { bodies.forEach((body) => { updateUsageOfModel(context, UsageFlags.MultipartFormData, body, { - recurseThroughProperties: false, + propagation: false, }); }); } diff --git a/packages/typespec-client-generator-core/test/package.test.ts b/packages/typespec-client-generator-core/test/package.test.ts index 4d36e7b44a..2a94ac0b34 100644 --- a/packages/typespec-client-generator-core/test/package.test.ts +++ b/packages/typespec-client-generator-core/test/package.test.ts @@ -2757,7 +2757,7 @@ describe("typespec-client-generator-core: package", () => { `); const sdkPackage = runner.context.experimental_sdkPackage; const method = getServiceMethodOfClient(sdkPackage); - strictEqual(sdkPackage.models.length, 1); + strictEqual(sdkPackage.models.length, 0); strictEqual(method.name, "myOp"); strictEqual(method.kind, "basic"); strictEqual(method.parameters.length, 2); diff --git a/packages/typespec-client-generator-core/test/public-utils.test.ts b/packages/typespec-client-generator-core/test/public-utils.test.ts index ef107cac16..f79953660f 100644 --- a/packages/typespec-client-generator-core/test/public-utils.test.ts +++ b/packages/typespec-client-generator-core/test/public-utils.test.ts @@ -1284,8 +1284,7 @@ describe("typespec-client-generator-core: public-utils", () => { ` ); const models = runner.context.experimental_sdkPackage.models; - strictEqual(models.length, 1); - ok(models.find((x) => x.name === "TestRequest" && x.isGeneratedName)); + strictEqual(models.length, 0); }); it("anonymous model for body parameter", async () => { @@ -1295,8 +1294,7 @@ describe("typespec-client-generator-core: public-utils", () => { ` ); const models = runner.context.experimental_sdkPackage.models; - strictEqual(models.length, 1); - ok(models.find((x) => x.name === "TestRequest" && x.isGeneratedName)); + strictEqual(models.length, 0); }); it("anonymous union in response header", async () => { diff --git a/packages/typespec-client-generator-core/test/types.test.ts b/packages/typespec-client-generator-core/test/types.test.ts index 2fb3e72019..6977f894b9 100644 --- a/packages/typespec-client-generator-core/test/types.test.ts +++ b/packages/typespec-client-generator-core/test/types.test.ts @@ -2025,17 +2025,14 @@ describe("typespec-client-generator-core: types", () => { interface StringExtensible extends GetAndSend {} `); const sdkPackage = runner.context.experimental_sdkPackage; - strictEqual(sdkPackage.models.length, 2); + strictEqual(sdkPackage.models.length, 1); strictEqual(sdkPackage.enums.length, 1); const prop = sdkPackage.enums.find((x) => x.name === "GetResponseProp" && x.isGeneratedName); ok(prop); strictEqual(prop.isFixed, false); strictEqual(prop.valueType.kind, "string"); - const req = sdkPackage.models.find((x) => x.name === "SendRequest" && x.isGeneratedName); const resp = sdkPackage.models.find((x) => x.name === "GetResponse" && x.isGeneratedName); - ok(req); ok(resp); - strictEqual(req.properties[0].type, prop); strictEqual(resp.properties[0].type, prop); });