Skip to content

Commit

Permalink
support @clientName for extensible enum variant (#314)
Browse files Browse the repository at this point in the history
fix: #309

add a fix for operation group path does not adopt `@clientName`

---------

Co-authored-by: iscai-msft <[email protected]>
  • Loading branch information
tadelesh and iscai-msft committed Feb 28, 2024
1 parent ff7726f commit 560be86
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 13 deletions.
7 changes: 7 additions & 0 deletions .chronus/changes/fix_client_name-2024-1-26-23-27-21.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: fix
packages:
- "@azure-tools/typespec-client-generator-core"
---

support @clientName for extensible enum variant
3 changes: 2 additions & 1 deletion packages/typespec-client-generator-core/src/decorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
} from "./interfaces.js";
import { TCGCContext, createTCGCContext, parseEmitterName } from "./internal-utils.js";
import { createStateSymbol, reportDiagnostic } from "./lib.js";
import { getLibraryName } from "./public-utils.js";
import { getAllModels, getSdkEnum, getSdkModel } from "./types.js";

export const namespace = "Azure.ClientGenerator.Core";
Expand Down Expand Up @@ -310,7 +311,7 @@ function buildOperationGroupPath(context: TCGCContext, type: Namespace | Interfa
break;
}
if (isOperationGroup(context, type)) {
path.push(type.name);
path.push(getLibraryName(context, type));
}
if (type.namespace) {
type = type.namespace;
Expand Down
7 changes: 5 additions & 2 deletions packages/typespec-client-generator-core/src/public-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,10 @@ export function getPropertyNames(context: TCGCContext, property: ModelProperty):
* @param type
* @returns the library name for a typespec type
*/
export function getLibraryName(context: TCGCContext, type: Type & { name?: string }): string {
export function getLibraryName(
context: TCGCContext,
type: Type & { name?: string | symbol }
): string {
// 1. check if there's a client name
let emitterSpecificName = getClientNameOverride(context, type);
if (emitterSpecificName) return emitterSpecificName;
Expand All @@ -190,7 +193,7 @@ export function getLibraryName(context: TCGCContext, type: Type & { name?: strin
if (clientSpecificName) return clientSpecificName;

// 4. check if there's a friendly name, if so return friendly name, otherwise return undefined
return getFriendlyName(context.program, type) ?? type.name;
return getFriendlyName(context.program, type) ?? (typeof type.name === "string" ? type.name : "");
}

export function capitalize(name: string): string {
Expand Down
9 changes: 5 additions & 4 deletions packages/typespec-client-generator-core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ export function getSdkUnion(
}
return diagnostics.wrap({
...getSdkTypeBaseHelper(context, type, "union"),
name: type.name,
name: getLibraryName(context, type),
generatedName: type.name ? undefined : getGeneratedName(context, type),
values: nonNullOptions.map((x) =>
diagnostics.pipe(getClientTypeWithDiagnostics(context, x, operation))
Expand Down Expand Up @@ -595,11 +595,12 @@ function getSdkUnionEnumValues(
enumType: SdkEnumType
): SdkEnumValueType[] {
const values: SdkEnumValueType[] = [];
for (const [name, member] of type.flattenedMembers.entries()) {
for (const member of type.flattenedMembers.values()) {
const docWrapper = getDocHelper(context, member.type);
const name = getLibraryName(context, member.type);
values.push({
kind: "enumvalue",
name: typeof name === "string" ? name : `${member.value}`,
name: name ? name : `${member.value}`,
description: docWrapper.description,
details: docWrapper.details,
value: member.value,
Expand Down Expand Up @@ -654,7 +655,7 @@ function getKnownValuesEnum(
const docWrapper = getDocHelper(context, type);
sdkType = {
...getSdkTypeBaseHelper(context, type, "enum"),
name: type.name,
name: getLibraryName(context, type),
description: docWrapper.description,
details: docWrapper.details,
valueType: getSdkEnumValueType(context, knownValues.members.values().next().value),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -826,11 +826,12 @@ describe("typespec-client-generator-core: decorators", () => {
);
});

it("nested namespace and interface", async () => {
it("nested namespace and interface with naming change", async () => {
await runner.compile(`
@service({})
namespace Test1Client {
@route("/b")
@clientName("BRename")
namespace B {
op x(): void;
Expand All @@ -855,7 +856,7 @@ describe("typespec-client-generator-core: decorators", () => {
ok(b);
strictEqual(b.subOperationGroups?.length, 1);
strictEqual(listOperationGroups(runner.context, b).length, 1);
strictEqual(b.groupPath, "Test1Client.B");
strictEqual(b.groupPath, "Test1Client.BRename");
deepStrictEqual(
listOperationsInOperationGroup(runner.context, b).map((x) => x.name),
["x"]
Expand All @@ -865,7 +866,7 @@ describe("typespec-client-generator-core: decorators", () => {
ok(c);
strictEqual(c.subOperationGroups, undefined);
strictEqual(listOperationGroups(runner.context, c).length, 0);
strictEqual(c.groupPath, "Test1Client.B.C");
strictEqual(c.groupPath, "Test1Client.BRename.C");
deepStrictEqual(
listOperationsInOperationGroup(runner.context, c).map((x) => x.name),
["y"]
Expand Down
42 changes: 39 additions & 3 deletions packages/typespec-client-generator-core/test/types.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { AzureCoreTestLibrary } from "@azure-tools/typespec-azure-core/testing";
import { Enum, UsageFlags } from "@typespec/compiler";
import { Enum, Union, UsageFlags } from "@typespec/compiler";
import { expectDiagnostics } from "@typespec/compiler/testing";
import { deepEqual, deepStrictEqual, strictEqual } from "assert";
import { beforeEach, describe, it } from "vitest";
Expand All @@ -13,7 +13,13 @@ import {
SdkUnionType,
} from "../src/interfaces.js";
import { isErrorOrChildOfError } from "../src/public-utils.js";
import { getAllModels, getAllModelsWithDiagnostics, getSdkEnum, isReadOnly } from "../src/types.js";
import {
getAllModels,
getAllModelsWithDiagnostics,
getClientType,
getSdkEnum,
isReadOnly,
} from "../src/types.js";
import { SdkTestRunner, createSdkTestRunner, createTcgcTestRunnerForEmitter } from "./test-host.js";

describe("typespec-client-generator-core: types", () => {
Expand Down Expand Up @@ -444,7 +450,7 @@ describe("typespec-client-generator-core: types", () => {
);
const sdkType = getSdkTypeHelper(runner);
strictEqual(sdkType.kind, "union");
strictEqual(sdkType.name, undefined);
strictEqual(sdkType.name, "");
const values = sdkType.values;
strictEqual(values.length, 2);
strictEqual(values[0].kind, "string");
Expand Down Expand Up @@ -931,7 +937,37 @@ describe("typespec-client-generator-core: types", () => {
await helper("@azure-tools/typespec-csharp", "Enum1", "One");
await helper("@azure-tools/typespec-java", "JavaEnum1", "JavaOne");
});

it("union as enum rename", async () => {
const { TestUnion } = (await runner.compileWithCustomization(
`
@service({})
namespace N {
@test
union TestUnion{
@clientName("ARename")
"A",
"B": "B_v",
string
}
op x(body: TestUnion): void;
}
`,
`
namespace Customizations;
@@clientName(N.TestUnion, "TestUnionRename");
@@clientName(N.TestUnion.B, "BRename");
`
)) as { TestUnion: Union };

const enumType = getClientType(runner.context, TestUnion) as SdkEnumType;
strictEqual(enumType.name, "TestUnionRename");
strictEqual(enumType.values[0].name, "ARename");
strictEqual(enumType.values[1].name, "BRename");
});
});

describe("SdkBodyModelPropertyType", () => {
it("required", async function () {
await runner.compileWithBuiltInService(`
Expand Down

0 comments on commit 560be86

Please sign in to comment.