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] Fix judge logic how to distinguish model is referred both in common content-type and multipart content-type #1511

Merged
merged 13 commits into from
Sep 20, 2024
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: fix
packages:
- "@azure-tools/typespec-client-generator-core"
---

Fix logic to check conflicting usage for model of multipart body and regular body
41 changes: 21 additions & 20 deletions packages/typespec-client-generator-core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1630,26 +1630,6 @@ function updateTypesFromOperation(
}

const multipartOperation = isMultipartOperation(context, operation);
// this part should be put before setting current body's usage because it is based on the previous usage
if (
sdkType.kind === "model" &&
((!multipartOperation && (sdkType.usage & UsageFlags.MultipartFormData) > 0) ||
(multipartOperation &&
(sdkType.usage & UsageFlags.Input) > 0 &&
(sdkType.usage & UsageFlags.Input & UsageFlags.MultipartFormData) === 0))
) {
// This means we have a model that is used both for formdata input and for regular body input
diagnostics.add(
createDiagnostic({
code: "conflicting-multipart-model-usage",
target: httpBody.type,
format: {
modelName: sdkType.name,
},
})
);
}

if (generateConvenient) {
if (spread) {
updateUsageOrAccessOfModel(context, UsageFlags.Spread, sdkType, { propagation: false });
Expand Down Expand Up @@ -1677,6 +1657,27 @@ function updateTypesFromOperation(
}
const access = getAccessOverride(context, operation) ?? "public";
diagnostics.pipe(updateUsageOrAccessOfModel(context, access, sdkType));

// after completion of usage calculation for httpBody, check whether it has
// conflicting usage between multipart and regular body
if (
sdkType.kind === "model" &&
((!multipartOperation && (sdkType.usage & UsageFlags.MultipartFormData) > 0) ||
(multipartOperation &&
(sdkType.usage & UsageFlags.MultipartFormData) > 0 &&
((sdkType.usage & UsageFlags.Json) | (sdkType.usage & UsageFlags.Xml)) > 0))
tadelesh marked this conversation as resolved.
Show resolved Hide resolved
) {
// This means we have a model that is used both for formdata input and for regular body input
diagnostics.add(
createDiagnostic({
code: "conflicting-multipart-model-usage",
target: httpBody.type,
format: {
modelName: sdkType.name,
},
})
);
}
}
for (const response of httpOperation.responses) {
for (const innerResponse of response.responses) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,22 @@ describe("typespec-client-generator-core: multipart types", () => {
code: "@azure-tools/typespec-client-generator-core/conflicting-multipart-model-usage",
});
});
it("multipart conflicting model usage for only multipart operations", async function () {
await runner.compile(
`
@service({title: "Test Service"}) namespace TestService;

model MultiPartRequest {
id: string;
profileImage: bytes;
}
weidongxu-microsoft marked this conversation as resolved.
Show resolved Hide resolved

@post op basic1(@header contentType: "multipart/form-data", @body body: MultiPartRequest): NoContentResponse;
@put op basic2(@header contentType: "multipart/form-data", @body body: MultiPartRequest): NoContentResponse;
`
);
deepEqual(runner.context.diagnostics.length, 0);
});
it("multipart resolving conflicting model usage with spread", async function () {
await runner.compileWithBuiltInService(
`
Expand Down
Loading