Fix C# reference-map accessibility for hidden union types#11288
Fix C# reference-map accessibility for hidden union types#11288live1206 wants to merge 5 commits into
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c4b68173-2f2b-467d-9a94-9be9d14b5e17
commit: |
|
No changes needing a change description found. |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c4b68173-2f2b-467d-9a94-9be9d14b5e17
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c4b68173-2f2b-467d-9a94-9be9d14b5e17
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c4b68173-2f2b-467d-9a94-9be9d14b5e17
Expected Azure SDK regeneration diffThe combined
There are no GA public API changes. The only accessibility change is the VoiceLive preview-only surface that was not present in GA 1.1.0. |
There was a problem hiding this comment.
Pull request overview
This PR updates the C# generator’s provider reference-map analysis to preserve established public API surface (including last GA contract/public nested types) while preventing BinaryData-erased unions from incorrectly “publicizing” internal/abstract union members, and it fixes request-header helper retention by deriving collection-header helper dependencies from the selected HttpRequestApi.
Changes:
- Extend reference-map graph construction to distinguish union item references that affect public surface vs metadata-only union items (erased to
BinaryData) and to root types that were public in the last contract. - Improve discriminator-derived reachability handling for “known variant” cases (including intermediate bases and nested scenarios).
- Make collection-header helper retention conditional on
HttpRequestApicapabilities, avoiding generation/retention of unusedPipelineRequestHeadersExtensionsfor non-pipeline request APIs; add positive/negative test coverage.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/ReferenceMap/ProviderReferenceMapAnalyzerTests.cs | Adds coverage for BinaryData/metadata-only unions, discriminator/nested accessibility, and last-contract rooting. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/ModelProviderTests.cs | Verifies unverifiable additional-properties types are treated as metadata-only unions. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/ReferenceMap/ProviderReferenceMapAnalyzer.Helpers.cs | Adds last-contract public rooting helpers and threads union-item exclusions into custom-code rooting. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/ReferenceMap/ProviderReferenceMapAnalyzer.cs | Integrates union-item exclusions into public graph analysis and roots last-contract public types. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/ReferenceMap/ProviderReferenceMapAnalyzer.Candidates.cs | Roots last-contract public types during removal; refines discriminator reachability propagation. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/ReferenceMap/ProviderReferenceMapAnalyzer.BodyReferences.cs | Adds union-item exclusion handling and respects UnionItemTypeReferenceKind during reference traversal. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs | Marks unverifiable types as metadata-only unions (to avoid retaining them as real dependencies). |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/CSharpType.cs | Introduces UnionItemTypeReferenceKind and plumbs it through union construction/cloning. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/TestHelpers/MockHelpers.cs | Allows injecting a custom HttpRequestApi in ClientModel tests. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/ReferenceMap/ClientBodyDependencyReferenceMapTests.cs | Adds negative test ensuring scalar headers don’t retain PipelineRequestHeadersExtensions. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/RestClientProviders/RestClientProviderTests.cs | Adds coverage for request-API-dependent collection-header helper retention. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/RestClientProvider.cs | Uses HttpRequestApi capability to decide which collection-header helper type (if any) to retain. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/PipelineRequestProvider.cs | Implements the request-API helper capability for the default pipeline request API. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/Abstractions/HttpRequestApi.cs | Adds GetCollectionHeaderHelperType() capability hook (default: none). |
| unionItemTypeExclusions.UnionWith(generatedInternalDeclarations); | ||
| AddAbstractModelDeclarations(generatedProviders, unionItemTypeExclusions, graph.Nodes); | ||
| var publicGraph = BuildGraph(generatedProviders, publicOnly: true, unionItemTypeExclusions); | ||
|
|
There was a problem hiding this comment.
This syntax is valid in C# 7.2 and later when the named argument appears in its correct parameter position and the following positional arguments remain in order. This project uses a current C# language version, and the package build plus the full generator test suites pass with this call, so no change is needed.
| unionItemTypeExclusions.UnionWith(generatedInternalDeclarations); | ||
| AddAbstractModelDeclarations(generatedProviders, unionItemTypeExclusions, graph.Nodes); | ||
| var publicGraph = BuildGraph(generatedProviders, publicOnly: true, unionItemTypeExclusions); | ||
| var customPublicRoots = GetCustomCodePublicGeneratedTypeRoots(generatedProviders, graph.Nodes, unionItemTypeExclusions); |
There was a problem hiding this comment.
This syntax is valid in C# 7.2 and later when the named argument appears in its correct parameter position and the following positional arguments remain in order. This project uses a current C# language version, and the package build plus the full generator test suites pass with this call, so no change is needed.
|
|
||
| AddCustomCodeViewGeneratedTypeRoot(roots, customCodeView, generatedTypeNames); | ||
| AddCustomCodeViewRoots(roots, customCodeView, generatedTypeNames, publicOnly: true); | ||
| AddCustomCodeViewRoots(roots, customCodeView, generatedTypeNames, publicOnly: true, unionItemTypeExclusions); | ||
| } |
There was a problem hiding this comment.
This syntax is valid in C# 7.2 and later when the named argument appears in its correct parameter position and the following positional arguments remain in order. This project uses a current C# language version, and the package build plus the full generator test suites pass with this call, so no change is needed.
| var roots = new HashSet<string>(StringComparer.Ordinal); | ||
| foreach (var provider in providers) | ||
| { | ||
| if (!IsPublicInLastContract(provider)) |
There was a problem hiding this comment.
These models may no longer be reachable from the current public API and are not required for the SDK to build. However, because they were shipped as public surface in a previous GA release, reachability alone is insufficient. LastContractView is the compatibility signal we need here to keep those types public and generated.
Co-authored-by: jolov <jolov@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c4b68173-2f2b-467d-9a94-9be9d14b5e17
|
Revalidated the combined Azure/unbranded regeneration from a fresh worktree at latest |
Summary
BinaryDatafrom real public or implementation dependenciesHttpRequestApi; avoid reflecting helper capabilities into every request body and generating unusedPipelineRequestHeadersExtensionsfilesFixes #11291.
Validation
RegenPreview.ps1: 5 passed, 0 failedRegenPreview.ps1: 46 passed, 0 failed, with no untracked files or unexpected request helpers