Skip to content

feat: back compat support for method param types - #11296

Merged
jorgerangel-msft merged 3 commits into
microsoft:mainfrom
jorgerangel-msft:back-compat-service-params
Jul 31, 2026
Merged

feat: back compat support for method param types#11296
jorgerangel-msft merged 3 commits into
microsoft:mainfrom
jorgerangel-msft:back-compat-service-params

Conversation

@jorgerangel-msft

@jorgerangel-msft jorgerangel-msft commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Extends method back-compat to preserve source + binary compatibility when a service method's parameters evolve. For each public/protected last-contract method that changed in a recoverable way, a hidden (EditorBrowsable.Never) overload reproducing the previous signature is generated that delegates to the current method.

Scenarios now supported:

  • Value-type parameter nullability removed (T?T) — adds a hidden overload with the previous nullable signature that forwards via .Value, guarded by Argument.AssertNotNull (also covers extensible enums, matched by name).
  • Nullable optional parameter became required — adds a hidden reduced-arity overload that drops the parameter and delegates with its previous default, so omit-callers still compile.

fixes: #11223

@microsoft-github-policy-service microsoft-github-policy-service Bot added the emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp label Jul 17, 2026
@jorgerangel-msft
jorgerangel-msft force-pushed the back-compat-service-params branch from 44edb35 to 547a347 Compare July 17, 2026 17:22
@github-actions

Copy link
Copy Markdown
Contributor

No changes needing a change description found.

@pkg-pr-new

pkg-pr-new Bot commented Jul 17, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@typespec/http-client-csharp@11296

commit: 4f250b2

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the C# generator’s method back-compat logic to handle additional signature evolution cases (beyond “new optional parameters”), specifically around nullable value-type parameters becoming non-nullable and nullable optional parameters becoming required, while adding targeted unit/golden tests and logging categories.

Changes:

  • Add generation of hidden back-compat overloads for T? -> T value-type parameter nullability removal and for nullable parameters that changed from optional to required (via reduced-arity overloads).
  • Introduce signature comparison that can optionally include nullability, and use it to avoid duplicate/incorrect overload classification.
  • Add/extend tests and expected outputs covering the new back-compat scenarios and cross-pass interactions.

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/Utilities/BackCompatHelperTests.cs New unit tests for the new back-compat detection helpers.
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TypeProviderTests.cs New integration/golden-style tests validating emitted overloads for the new scenarios.
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/BuildMethodsForBackCompatibilityUnwrapsRelaxedNullableSharedParameterInOptionalOverload/NullabilityAndOptionalChangeType.cs Last-contract source stub used by the new cross-pass test.
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/BuildMethodsForBackCompatibilityUnwrapsRelaxedNullableSharedParameterInOptionalOverload.cs Expected generated output for the cross-pass case (unwrap .Value forwarding).
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/BuildMethodsForBackCompatibilityAddsOverloadForRelaxedNullableValueTypeParameter/NullabilityChangeType.cs Last-contract source stub for the T? -> T overload case.
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/BuildMethodsForBackCompatibilityAddsOverloadForRelaxedNullableValueTypeParameter.cs Expected generated output for the nullability-change overload.
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/BuildMethodsForBackCompatibilityAddsOverloadForNullableParameterThatBecameRequired/OptionalityChangeType.cs Last-contract source stub for the optional-to-required nullable parameter case.
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/BuildMethodsForBackCompatibilityAddsOverloadForNullableParameterThatBecameRequired.cs Expected generated output for the reduced-arity optionality-restoration overload.
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Utilities/BackCompatHelper.cs Core implementation: unified overload selection + new detection/build helpers + improved logging.
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs Switch to the new unified back-compat overload entrypoint.
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/MethodSignatureBase.cs Add a comparer variant that includes nullability in parameter type matching.
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/CSharpType.cs Add AreNamesEqual(..., checkNullability) helper to support nullability-aware comparisons.
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/EmitterRpc/Emitter.cs Map new back-compat categories to readable debug strings.
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/EmitterRpc/BackCompatibilityChangeCategory.cs Add new categories for nullability-change and optionality-restoration overload additions.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

@jorgerangel-msft
jorgerangel-msft force-pushed the back-compat-service-params branch 2 times, most recently from cfdda3d to 6545e48 Compare July 17, 2026 20:01
@jorgerangel-msft
jorgerangel-msft requested a review from Copilot July 17, 2026 20:02

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

@jorgerangel-msft
jorgerangel-msft force-pushed the back-compat-service-params branch 3 times, most recently from de5576d to 1b0fe92 Compare July 20, 2026 17:32
@jorgerangel-msft
jorgerangel-msft requested a review from Copilot July 20, 2026 19:27

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 23 out of 23 changed files in this pull request and generated 2 comments.

@jorgerangel-msft
jorgerangel-msft force-pushed the back-compat-service-params branch 2 times, most recently from a633f67 to 36c4c3e Compare July 21, 2026 15:55
@jorgerangel-msft
jorgerangel-msft force-pushed the back-compat-service-params branch 2 times, most recently from 739515f to 7947cde Compare July 28, 2026 22:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 32 out of 32 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Utilities/BackCompatHelper.cs:376

  • Same accessibility check issue for candidates: candidateIsAccessible doesn’t exclude Private-flagged modifiers. Use MethodProviderHelpers.IsPublicApi so private protected candidates don’t participate in match selection.
                    var candidateSignature = candidate.Signature;
                    bool candidateIsAccessible = (candidateSignature.Modifiers & (MethodSignatureModifiers.Public | MethodSignatureModifiers.Protected)) != 0;

packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Utilities/BackCompatHelper.cs:362

  • AddBackCompatOverloads treats any method with Public or Protected flags as eligible, but it doesn’t exclude Private (e.g. private protected), unlike the new centralized MethodProviderHelpers.IsPublicApi check used elsewhere. This can cause back-compat overloads to be generated for non-public-API methods.
                if ((previousSignature.Modifiers & (MethodSignatureModifiers.Public | MethodSignatureModifiers.Protected)) == 0 ||
                    !currentMethodsByName.TryGetValue(previousSignature.Name, out var candidates))

packages/http-client-csharp/generator/docs/backward-compatibility.md:968

  • This statement is no longer accurate now that some back-compat overloads intentionally preserve defaults (e.g., when the current method makes all previous parameters required, or for certain nullability/optionality shims). Consider rewording to indicate defaults are stripped only when needed to avoid ambiguity.

@jorgerangel-msft
jorgerangel-msft force-pushed the back-compat-service-params branch from 7947cde to b950ce2 Compare July 29, 2026 21:50
@jorgerangel-msft
jorgerangel-msft force-pushed the back-compat-service-params branch from b950ce2 to df62996 Compare July 30, 2026 16:23
@jorgerangel-msft
jorgerangel-msft marked this pull request as ready for review July 30, 2026 19:44
…ract service methods

Reject back-compat overload candidates whose static modifier differs from the
previous signature (a previous static method could otherwise match a current
instance method and emit `this.Method(...)` inside a static shim, CS0026), and
skip restoring abstract methods entirely since a delegating shim requires a body
that an abstract method cannot have. Map IMethodSymbol.IsAbstract onto the method
signature so the model faithfully represents abstract methods.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 52760796-5a02-48e0-a9c2-9f8dc95a87f5
@jorgerangel-msft
jorgerangel-msft added this pull request to the merge queue Jul 31, 2026
Merged via the queue into microsoft:main with commit 14feb1d Jul 31, 2026
29 checks passed
@jorgerangel-msft
jorgerangel-msft deleted the back-compat-service-params branch July 31, 2026 22:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Handle Parameter Type Changes in Service Methods

3 participants