From 9fb60d69f0df191bb609713f045670f2e3c078fb Mon Sep 17 00:00:00 2001 From: tadelesh Date: Thu, 31 Oct 2024 18:01:53 +0800 Subject: [PATCH] remove useless path parameter from method --- .../fix_route_param-2024-9-31-18-1-39.md | 7 +++ .../src/http.ts | 26 ++++++++--- .../test/packages/parameters.test.ts | 44 +++++++++++++++++++ 3 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 .chronus/changes/fix_route_param-2024-9-31-18-1-39.md diff --git a/.chronus/changes/fix_route_param-2024-9-31-18-1-39.md b/.chronus/changes/fix_route_param-2024-9-31-18-1-39.md new file mode 100644 index 0000000000..d4ff2a14ef --- /dev/null +++ b/.chronus/changes/fix_route_param-2024-9-31-18-1-39.md @@ -0,0 +1,7 @@ +--- +changeKind: fix +packages: + - "@azure-tools/typespec-client-generator-core" +--- + +remove useless path parameter from method \ No newline at end of file diff --git a/packages/typespec-client-generator-core/src/http.ts b/packages/typespec-client-generator-core/src/http.ts index 05f37afa6a..a49bae7992 100644 --- a/packages/typespec-client-generator-core/src/http.ts +++ b/packages/typespec-client-generator-core/src/http.ts @@ -85,6 +85,7 @@ export function getSdkHttpOperation( const parameters = diagnostics.pipe( getSdkHttpParameters(context, httpOperation, methodParameters, responsesWithBodies[0]), ); + filterOutUselessPathParameters(context, httpOperation, methodParameters); return diagnostics.wrap({ __raw: httpOperation, kind: "http", @@ -408,12 +409,12 @@ function getSdkHttpResponseAndExceptions( context: TCGCContext, httpOperation: HttpOperation, ): [ - { - responses: SdkHttpResponse[]; - exceptions: SdkHttpErrorResponse[]; - }, - readonly Diagnostic[], -] { + { + responses: SdkHttpResponse[]; + exceptions: SdkHttpErrorResponse[]; + }, + readonly Diagnostic[], + ] { const diagnostics = createDiagnosticCollector(); const responses: SdkHttpResponse[] = []; const exceptions: SdkHttpErrorResponse[] = []; @@ -628,6 +629,19 @@ function findMapping( return undefined; } +function filterOutUselessPathParameters(context: TCGCContext, httpOperation: HttpOperation, methodParameters: SdkMethodParameter[]) { + // for autoroute with constant or singleton arm resource operation, + // some path parameters will be added to route directly with the constant value, + // so we will remove the method parameter for consistent + for (let i = 0; i < methodParameters.length; i++) { + const param = methodParameters[i]; + if (param.__raw && isPathParam(context.program, param.__raw) && httpOperation.parameters.parameters.filter(p => p.type === "path" && p.name === getWireName(context, param.__raw!)).length === 0) { + methodParameters.splice(i, 1); + i--; + } + } +} + function findRootSourceProperty(property: ModelProperty): ModelProperty { while (property.sourceProperty) { property = property.sourceProperty; diff --git a/packages/typespec-client-generator-core/test/packages/parameters.test.ts b/packages/typespec-client-generator-core/test/packages/parameters.test.ts index c2e64e935e..c7881bbdad 100644 --- a/packages/typespec-client-generator-core/test/packages/parameters.test.ts +++ b/packages/typespec-client-generator-core/test/packages/parameters.test.ts @@ -10,6 +10,8 @@ import { } from "../../src/interfaces.js"; import { SdkTestRunner, createSdkTestRunner } from "../test-host.js"; import { getServiceMethodOfClient, getServiceWithDefaultApiVersion } from "./utils.js"; +import { AzureResourceManagerTestLibrary } from "@azure-tools/typespec-azure-resource-manager/testing"; +import { OpenAPITestLibrary } from "@typespec/openapi/testing"; describe("typespec-client-generator-core: parameters", () => { let runner: SdkTestRunner; @@ -1087,4 +1089,46 @@ describe("typespec-client-generator-core: parameters", () => { strictEqual(method.operation.bodyParam?.serializedName, "body"); }); }); + + describe("method parameter not used in operation", () => { + it("autoroute with constant", async () => { + await runner.compileWithBuiltInService(` + @autoRoute + op test(@path param: "test"): void; + `); + const sdkPackage = runner.context.sdkPackage; + const method = getServiceMethodOfClient(sdkPackage); + strictEqual(method.parameters.length, 0); + strictEqual(method.operation.parameters.length, 0); + strictEqual(method.operation.uriTemplate, "/test"); + }); + + it("singleton resource", async () => { + const runnerWithArm = await createSdkTestRunner({ + librariesToAdd: [AzureResourceManagerTestLibrary, AzureCoreTestLibrary, OpenAPITestLibrary], + autoUsings: ["Azure.ResourceManager", "Azure.Core"], + emitterName: "@azure-tools/typespec-java", + }); + await runnerWithArm.compileWithBuiltInAzureResourceManagerService(` + @singleton("default") + model SingletonTrackedResource is TrackedResource { + ...ResourceNameParameter; + } + + model SingletonTrackedResourceProperties { + description?: string; + } + + @armResourceOperations + interface Singleton { + createOrUpdate is ArmResourceCreateOrReplaceAsync; + } + `); + + const sdkPackage = runnerWithArm.context.sdkPackage; + const method = getServiceMethodOfClient(sdkPackage); + deepStrictEqual(method.parameters.map(p => p.name), ["resourceGroupName", "resource", "contentType", "accept"]); + deepStrictEqual(method.operation.parameters.map(p => p.name), ["apiVersion", "subscriptionId", "resourceGroupName", "contentType", "accept"]); + }); + }); });