Skip to content

Commit

Permalink
[tcgc] add xml usage and fix generic decorator issue (#1204)
Browse files Browse the repository at this point in the history
  • Loading branch information
tadelesh committed Jul 19, 2024
1 parent bbbfe20 commit c521e6f
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 34 deletions.
7 changes: 7 additions & 0 deletions .chronus/changes/xml_usage-2024-6-19-15-33-55.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 xml usage and change enumvalue arg representation in generic decorators
2 changes: 2 additions & 0 deletions packages/typespec-client-generator-core/src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -603,4 +603,6 @@ export enum UsageFlags {
Error = 1 << 7,
// Set when model is used in conjunction with an application/json content type.
Json = 1 << 8,
// Set when model is used in conjunction with an application/xml content type.
Xml = 1 << 8,
}
11 changes: 9 additions & 2 deletions packages/typespec-client-generator-core/src/internal-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import {
getHttpOperationWithCache,
isApiVersion,
} from "./public-utils.js";
import { getClientTypeWithDiagnostics } from "./types.js";

export const AllScopes = Symbol.for("@azure-core/typespec-client-generator-core/all-scopes");

Expand Down Expand Up @@ -301,7 +302,7 @@ export function getTypeDecorators(
};
for (let i = 0; i < decorator.args.length; i++) {
decoratorInfo.arguments[decorator.definition.parameters[i].name] = diagnostics.pipe(
getDecoratorArgValue(decorator.args[i].jsValue, type, decoratorName)
getDecoratorArgValue(context, decorator.args[i].jsValue, type, decoratorName)
);
}
retval.push(decoratorInfo);
Expand All @@ -312,6 +313,7 @@ export function getTypeDecorators(
}

function getDecoratorArgValue(
context: TCGCContext,
arg:
| Type
| Record<string, unknown>
Expand All @@ -328,7 +330,7 @@ function getDecoratorArgValue(
const diagnostics = createDiagnosticCollector();
if (typeof arg === "object" && arg !== null && "kind" in arg) {
if (arg.kind === "EnumMember") {
return diagnostics.wrap(arg.value ?? arg.name);
return diagnostics.wrap(diagnostics.pipe(getClientTypeWithDiagnostics(context, arg)));
}
if (arg.kind === "String" || arg.kind === "Number" || arg.kind === "Boolean") {
return diagnostics.wrap(arg.value);
Expand Down Expand Up @@ -573,3 +575,8 @@ export function isJsonContentType(contentType: string): boolean {
const regex = new RegExp(/^(application|text)\/(.+\+)?json$/);
return regex.test(contentType);
}

export function isXmlContentType(contentType: string): boolean {
const regex = new RegExp(/^(application|text)\/(.+\+)?xml$/);
return regex.test(contentType);
}
4 changes: 4 additions & 0 deletions packages/typespec-client-generator-core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ import {
isMultipartFormData,
isMultipartOperation,
isNeverOrVoidType,
isXmlContentType,
updateWithApiVersionInformation,
} from "./internal-utils.js";
import { createDiagnostic } from "./lib.js";
Expand Down Expand Up @@ -1335,6 +1336,9 @@ function updateTypesFromOperation(
if (httpBody.contentTypes.some((x) => isJsonContentType(x))) {
updateUsageOfModel(context, UsageFlags.Json, sdkType);
}
if (httpBody.contentTypes.some((x) => isXmlContentType(x))) {
updateUsageOfModel(context, UsageFlags.Json, sdkType);
}
if (httpBody.contentTypes.includes("application/merge-patch+json")) {
// will also have Json type
updateUsageOfModel(context, UsageFlags.JsonMergePatch, sdkType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { expectDiagnostics } from "@typespec/compiler/testing";
import { XmlTestLibrary } from "@typespec/xml/testing";
import { deepStrictEqual, strictEqual } from "assert";
import { beforeEach, describe, it } from "vitest";
import { SdkEnumValueType } from "../../src/interfaces.js";
import { SdkTestRunner, createSdkTestRunner } from "../test-host.js";

describe("typespec-client-generator-core: general decorators list", () => {
Expand Down Expand Up @@ -72,14 +73,11 @@ describe("typespec-client-generator-core: general decorators list", () => {

const models = runner.context.sdkPackage.models;
strictEqual(models.length, 1);
deepStrictEqual(models[0].properties[0].decorators, [
{
name: "TypeSpec.@encode",
arguments: {
encoding: "base64url",
},
},
]);
strictEqual(models[0].properties[0].decorators[0].name, "TypeSpec.@encode");
const encodeInfo = models[0].properties[0].decorators[0].arguments[
"encoding"
] as SdkEnumValueType;
strictEqual(encodeInfo.value, "base64url");
expectDiagnostics(runner.context.diagnostics, []);
});

Expand Down Expand Up @@ -266,30 +264,17 @@ describe("typespec-client-generator-core: general decorators list", () => {

const models = runner.context.sdkPackage.models;
strictEqual(models.length, 1);
deepStrictEqual(models[0].decorators, [
{
name: "TypeSpec.Xml.@ns",
arguments: {
ns: "https://example.com/ns1",
},
},
]);
deepStrictEqual(models[0].properties[0].decorators, [
{
name: "TypeSpec.Xml.@ns",
arguments: {
ns: "https://example.com/ns1",
},
},
]);
deepStrictEqual(models[0].properties[1].decorators, [
{
name: "TypeSpec.Xml.@ns",
arguments: {
ns: "https://example.com/ns2",
},
},
]);
strictEqual(models[0].decorators[0].name, "TypeSpec.Xml.@ns");
const modelArg = models[0].decorators[0].arguments["ns"] as SdkEnumValueType;
strictEqual(modelArg.value, "https://example.com/ns1");

strictEqual(models[0].properties[0].decorators[0].name, "TypeSpec.Xml.@ns");
let propArg = models[0].properties[0].decorators[0].arguments["ns"] as SdkEnumValueType;
strictEqual(propArg.value, "https://example.com/ns1");

strictEqual(models[0].properties[1].decorators[0].name, "TypeSpec.Xml.@ns");
propArg = models[0].properties[1].decorators[0].arguments["ns"] as SdkEnumValueType;
strictEqual(propArg.value, "https://example.com/ns2");
});

it("@unwrapped", async function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1467,4 +1467,22 @@ describe("typespec-client-generator-core: model types", () => {
strictEqual(models[0].name, "Test");
strictEqual(models[0].properties.length, 0);
});

it("xml usage", async () => {
await runner.compileAndDiagnose(`
@service({})
namespace MyService {
model Test {
prop: string;
}
op test(@header("content-type") contentType: "application/xml", @body body: Test): Test;
}
`);

const models = runner.context.sdkPackage.models;
strictEqual(models.length, 1);
strictEqual(models[0].name, "Test");
strictEqual(models[0].usage, UsageFlags.Input | UsageFlags.Output | UsageFlags.Xml);
});
});

0 comments on commit c521e6f

Please sign in to comment.