Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[tcgc] add disableUsageAccessPropagationToBase flag and separate exception usage from output usage #1834

Merged
merged 10 commits into from
Nov 13, 2024
7 changes: 7 additions & 0 deletions .chronus/changes/add_usage_helper-2024-10-11-17-1-36.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 `disableUsageAccessPropagationToBase` to support language that does not generate base model
3 changes: 3 additions & 0 deletions packages/typespec-client-generator-core/src/decorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,7 @@ export function createTCGCContext(program: Program, emitterName: string): TCGCCo
__tspTypeToApiVersions: new Map(),
__clientToApiVersionClientDefaultValue: new Map(),
previewStringRegex: /-preview$/,
disableUsageAccessPropagationToBase: false,
};
}

Expand All @@ -626,6 +627,7 @@ interface VersioningStrategy {
export interface CreateSdkContextOptions {
readonly versioning?: VersioningStrategy;
additionalDecorators?: string[];
disableUsageAccessPropagationToBase?: boolean; // this flag is for some languages that has no need to generate base model, but generate model with composition
}

export async function createSdkContext<
Expand Down Expand Up @@ -658,6 +660,7 @@ export async function createSdkContext<
examplesDir: context.options["examples-dir"] ?? context.options["examples-directory"],
decoratorsAllowList: [...defaultDecoratorsAllowList, ...(options?.additionalDecorators ?? [])],
previewStringRegex: options?.versioning?.previewStringRegex || tcgcContext.previewStringRegex,
disableUsageAccessPropagationToBase: options?.disableUsageAccessPropagationToBase ?? false,
};
sdkContext.sdkPackage = diagnostics.pipe(getSdkPackage(sdkContext));
for (const client of sdkContext.sdkPackage.clients) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export interface TCGCContext {
examplesDir?: string;
decoratorsAllowList?: string[];
previewStringRegex: RegExp;
disableUsageAccessPropagationToBase: boolean;
}

export interface SdkContext<
Expand Down
5 changes: 3 additions & 2 deletions packages/typespec-client-generator-core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1446,7 +1446,6 @@ function updateUsageOrAccess(
}

if (type.kind === "enum") return diagnostics.wrap(undefined);
if (!options.propagation) return diagnostics.wrap(undefined);
if (type.kind === "union") {
for (const unionType of type.variantTypes) {
diagnostics.pipe(updateUsageOrAccess(context, value, unionType, options));
Expand All @@ -1457,7 +1456,9 @@ function updateUsageOrAccess(
diagnostics.pipe(updateUsageOrAccess(context, value, type.type, options));
return diagnostics.wrap(undefined);
}
if (type.baseModel) {

if (!options.propagation) return diagnostics.wrap(undefined);
if (type.baseModel && !context.disableUsageAccessPropagationToBase) {
options.ignoreSubTypeStack.push(true);
diagnostics.pipe(updateUsageOrAccess(context, value, type.baseModel, options));
options.ignoreSubTypeStack.pop();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -730,4 +730,62 @@ describe("typespec-client-generator-core: @access", () => {
code: "@azure-tools/typespec-client-generator-core/conflict-access-override",
});
});

it("disableUsageAccessPropagationToBase true with override", async () => {
runner = await createSdkTestRunner(
{ emitterName: "@azure-tools/typespec-python" },
{ disableUsageAccessPropagationToBase: true },
);
await runner.compileWithBuiltInService(
`
model BaseClassThatsPruned {
id: int32;
}
model DerivedOne extends BaseClassThatsPruned {
name: string;
prop: UsedByProperty;
}
model UsedByProperty {
prop: string;
}
@@usage(DerivedOne, Usage.output);
@@access(DerivedOne, Access.public);
`,
);
const models = runner.context.sdkPackage.models;
strictEqual(models.length, 2);
strictEqual(models[0].access, "public");
strictEqual(models[0].name, "DerivedOne");
strictEqual(models[1].access, "public");
strictEqual(models[1].name, "UsedByProperty");
});

it("disableUsageAccessPropagationToBase true", async () => {
runner = await createSdkTestRunner(
{ emitterName: "@azure-tools/typespec-python" },
{ disableUsageAccessPropagationToBase: true },
);
await runner.compileWithBuiltInService(
`
model BaseClassThatsPruned {
id: int32;
}
model DerivedOne extends BaseClassThatsPruned {
name: string;
prop: UsedByProperty;
}
model UsedByProperty {
prop: string;
}

op test(): DerivedOne;
`,
);
const models = runner.context.sdkPackage.models;
strictEqual(models.length, 2);
strictEqual(models[0].access, "public");
strictEqual(models[0].name, "DerivedOne");
strictEqual(models[1].access, "public");
strictEqual(models[1].name, "UsedByProperty");
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -459,4 +459,61 @@ describe("typespec-client-generator-core: @usage", () => {
strictEqual(models[1].usage, UsageFlags.Output);
strictEqual(models[1].access, "public");
});

it("disableUsageAccessPropagationToBase true with override", async () => {
runner = await createSdkTestRunner(
{ emitterName: "@azure-tools/typespec-python" },
{ disableUsageAccessPropagationToBase: true },
);
await runner.compileWithBuiltInService(
`
model BaseClassThatsPruned {
id: int32;
}
model DerivedOne extends BaseClassThatsPruned {
name: string;
prop: UsedByProperty;
}
model UsedByProperty {
prop: string;
}
@@usage(DerivedOne, Usage.output);
`,
);
const models = runner.context.sdkPackage.models;
strictEqual(models.length, 2);
strictEqual(models[0].usage, UsageFlags.Output);
strictEqual(models[0].name, "DerivedOne");
strictEqual(models[1].usage, UsageFlags.Output);
strictEqual(models[1].name, "UsedByProperty");
});

it("disableUsageAccessPropagationToBase true", async () => {
runner = await createSdkTestRunner(
{ emitterName: "@azure-tools/typespec-python" },
{ disableUsageAccessPropagationToBase: true },
);
await runner.compileWithBuiltInService(
`
model BaseClassThatsPruned {
id: int32;
}
model DerivedOne extends BaseClassThatsPruned {
name: string;
prop: UsedByProperty;
}
model UsedByProperty {
prop: string;
}

op test(): DerivedOne;
`,
);
const models = runner.context.sdkPackage.models;
strictEqual(models.length, 2);
strictEqual(models[0].usage, UsageFlags.Output | UsageFlags.Json);
strictEqual(models[0].name, "DerivedOne");
strictEqual(models[1].usage, UsageFlags.Output | UsageFlags.Json);
strictEqual(models[1].name, "UsedByProperty");
});
});
Loading