diff --git a/.chronus/changes/json-converter-2024-6-24-16-48-41.md b/.chronus/changes/json-converter-2024-6-24-16-48-41.md new file mode 100644 index 0000000000..0fea7df5b8 --- /dev/null +++ b/.chronus/changes/json-converter-2024-6-24-16-48-41.md @@ -0,0 +1,7 @@ +--- +changeKind: feature +packages: + - "@azure-tools/typespec-client-generator-core" +--- + +Add `@hasJsonConverter` for csharp only to indicate if JSON converter is needed diff --git a/docs/libraries/typespec-client-generator-core/reference/decorators.md b/docs/libraries/typespec-client-generator-core/reference/decorators.md index fee0493ac5..374487dcdb 100644 --- a/docs/libraries/typespec-client-generator-core/reference/decorators.md +++ b/docs/libraries/typespec-client-generator-core/reference/decorators.md @@ -617,3 +617,30 @@ model Origin { @get op getModel(): Fish; ``` + +### `@useSystemTextJsonConverter` {#@Azure.ClientGenerator.Core.useSystemTextJsonConverter} + +Whether a model needs the custom JSON converter, this is only used for backward compatibility for csharp. + +```typespec +@Azure.ClientGenerator.Core.useSystemTextJsonConverter(scope?: valueof string) +``` + +#### Target + +`Model` + +#### Parameters + +| Name | Type | Description | +| ----- | ---------------- | ------------------------------------------------------------------------------------------------------------- | +| scope | `valueof string` | The language scope you want this decorator to apply to. If not specified, will apply to all language emitters | + +#### Examples + +```typespec +@useSystemTextJsonConverter +model MyModel { + prop: string; +} +``` diff --git a/docs/libraries/typespec-client-generator-core/reference/index.mdx b/docs/libraries/typespec-client-generator-core/reference/index.mdx index 49522d3657..d504e45c31 100644 --- a/docs/libraries/typespec-client-generator-core/reference/index.mdx +++ b/docs/libraries/typespec-client-generator-core/reference/index.mdx @@ -52,3 +52,4 @@ npm install --save-peer @azure-tools/typespec-client-generator-core - [`@override`](./decorators.md#@Azure.ClientGenerator.Core.override) - [`@protocolAPI`](./decorators.md#@Azure.ClientGenerator.Core.protocolAPI) - [`@usage`](./decorators.md#@Azure.ClientGenerator.Core.usage) +- [`@useSystemTextJsonConverter`](./decorators.md#@Azure.ClientGenerator.Core.useSystemTextJsonConverter) diff --git a/packages/typespec-client-generator-core/README.md b/packages/typespec-client-generator-core/README.md index 9ccc9cdf08..479eb2cf9a 100644 --- a/packages/typespec-client-generator-core/README.md +++ b/packages/typespec-client-generator-core/README.md @@ -25,6 +25,7 @@ npm install @azure-tools/typespec-client-generator-core - [`@override`](#@override) - [`@protocolAPI`](#@protocolapi) - [`@usage`](#@usage) +- [`@useSystemTextJsonConverter`](#@usesystemtextjsonconverter) #### `@access` @@ -625,3 +626,30 @@ model Origin { @get op getModel(): Fish; ``` + +#### `@useSystemTextJsonConverter` + +Whether a model needs the custom JSON converter, this is only used for backward compatibility for csharp. + +```typespec +@Azure.ClientGenerator.Core.useSystemTextJsonConverter(scope?: valueof string) +``` + +##### Target + +`Model` + +##### Parameters + +| Name | Type | Description | +| ----- | ---------------- | ------------------------------------------------------------------------------------------------------------- | +| scope | `valueof string` | The language scope you want this decorator to apply to. If not specified, will apply to all language emitters | + +##### Examples + +```typespec +@useSystemTextJsonConverter +model MyModel { + prop: string; +} +``` diff --git a/packages/typespec-client-generator-core/generated-defs/Azure.ClientGenerator.Core.ts b/packages/typespec-client-generator-core/generated-defs/Azure.ClientGenerator.Core.ts index fdbb9f9126..7e83c78e80 100644 --- a/packages/typespec-client-generator-core/generated-defs/Azure.ClientGenerator.Core.ts +++ b/packages/typespec-client-generator-core/generated-defs/Azure.ClientGenerator.Core.ts @@ -483,3 +483,21 @@ export type OverrideDecorator = ( override: Operation, scope?: string ) => void; + +/** + * Whether a model needs the custom JSON converter, this is only used for backward compatibility for csharp. + * + * @param scope The language scope you want this decorator to apply to. If not specified, will apply to all language emitters + * @example + * ```typespec + * @useSystemTextJsonConverter + * model MyModel { + * prop: string; + * } + * ``` + */ +export type UseSystemTextJsonConverterDecorator = ( + context: DecoratorContext, + target: Model, + scope?: string +) => void; diff --git a/packages/typespec-client-generator-core/generated-defs/Azure.ClientGenerator.Core.ts-test.ts b/packages/typespec-client-generator-core/generated-defs/Azure.ClientGenerator.Core.ts-test.ts index 1fe5974bec..08aefaa0d8 100644 --- a/packages/typespec-client-generator-core/generated-defs/Azure.ClientGenerator.Core.ts-test.ts +++ b/packages/typespec-client-generator-core/generated-defs/Azure.ClientGenerator.Core.ts-test.ts @@ -13,6 +13,7 @@ import { $override, $protocolAPI, $usage, + $useSystemTextJsonConverter, } from "@azure-tools/typespec-client-generator-core"; import type { AccessDecorator, @@ -28,6 +29,7 @@ import type { OverrideDecorator, ProtocolAPIDecorator, UsageDecorator, + UseSystemTextJsonConverterDecorator, } from "./Azure.ClientGenerator.Core.js"; type Decorators = { @@ -44,6 +46,7 @@ type Decorators = { $access: AccessDecorator; $flattenProperty: FlattenPropertyDecorator; $override: OverrideDecorator; + $useSystemTextJsonConverter: UseSystemTextJsonConverterDecorator; }; /** An error here would mean that the exported decorator is not using the same signature. Make sure to have export const $decName: DecNameDecorator = (...) => ... */ @@ -61,4 +64,5 @@ const _: Decorators = { $access, $flattenProperty, $override, + $useSystemTextJsonConverter, }; diff --git a/packages/typespec-client-generator-core/lib/decorators.tsp b/packages/typespec-client-generator-core/lib/decorators.tsp index e88fd4f8c0..46f1560311 100644 --- a/packages/typespec-client-generator-core/lib/decorators.tsp +++ b/packages/typespec-client-generator-core/lib/decorators.tsp @@ -467,3 +467,17 @@ extern dec flattenProperty(target: ModelProperty, scope?: valueof string); * ``` */ extern dec override(original: Operation, override: Operation, scope?: valueof string); + +/** + * Whether a model needs the custom JSON converter, this is only used for backward compatibility for csharp. + * @param scope The language scope you want this decorator to apply to. If not specified, will apply to all language emitters + * + * @example + * ```typespec + * @useSystemTextJsonConverter + * model MyModel { + * prop: string; + * } + * ``` + */ +extern dec useSystemTextJsonConverter(target: Model, scope?: valueof string); diff --git a/packages/typespec-client-generator-core/src/decorators.ts b/packages/typespec-client-generator-core/src/decorators.ts index 932fcda251..296c5a56cd 100644 --- a/packages/typespec-client-generator-core/src/decorators.ts +++ b/packages/typespec-client-generator-core/src/decorators.ts @@ -1135,3 +1135,9 @@ export function getOverriddenClientMethod( ): Operation | undefined { return getScopedDecoratorData(context, overrideKey, entity); } + +export const $useSystemTextJsonConverter: DecoratorFunction = ( + context: DecoratorContext, + entity: Model, + scope?: LanguageScopes +) => {}; diff --git a/packages/typespec-client-generator-core/test/types/general-decorators-list.test.ts b/packages/typespec-client-generator-core/test/types/general-decorators-list.test.ts index 57ad1517e4..8608236957 100644 --- a/packages/typespec-client-generator-core/test/types/general-decorators-list.test.ts +++ b/packages/typespec-client-generator-core/test/types/general-decorators-list.test.ts @@ -327,4 +327,32 @@ describe("typespec-client-generator-core: general decorators list", () => { ]); }); }); + + describe("csharp only decorator", () => { + it("@useSystemTextJsonConverter", async function () { + runner = await createSdkTestRunner( + {}, + { additionalDecorators: ["Azure\\.ClientGenerator\\.Core\\.@useSystemTextJsonConverter"] } + ); + + await runner.compileWithBuiltInService(` + @useSystemTextJsonConverter("csharp") + model A { + id: string; + } + + op test(): A; + `); + + const models = runner.context.sdkPackage.models; + strictEqual(models.length, 1); + deepStrictEqual(models[0].decorators, [ + { + name: "Azure.ClientGenerator.Core.@useSystemTextJsonConverter", + arguments: { scope: "csharp" }, + }, + ]); + expectDiagnostics(runner.context.diagnostics, []); + }); + }); });