Support back-compat model constructors in the C# generator - #11503
Support back-compat model constructors in the C# generator#11503jorgerangel-msft with Copilot wants to merge 12 commits into
Conversation
|
Azure Pipelines: Successfully started running 1 pipeline(s). 1 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
jorgerangel-msft
left a comment
There was a problem hiding this comment.
@copilot please add robust unit tests to test our changes. We should use TestData to validate the changes, and follow the existing pattern for validating back compat scenarios
commit: |
…ructors Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
Added robust TestData-based tests in c2f7d78: |
jorgerangel-msft
left a comment
There was a problem hiding this comment.
@copilot I"d like to see some unit tests where there are ctors in the back compat view, but also the ctor is replaced with custom code.
…ithName, TestData snapshots Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
Added in 255c02e — the new |
…p dict, ctor baseline tests Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
…RestorableProperty Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR enhances the http-client-csharp generator’s LastContractView back-compat mechanism to restore previously-published public model constructors that the current spec would otherwise drop (notably when a required property becomes optional), preventing source-breaking changes for positional construction.
Changes:
- Added
ModelProvider.BuildConstructorsForBackCompatibilitylogic to reconstruct missing public constructors from the last contract by chaining to the closest current public constructor and assigning extra properties. - Added new back-compat diagnostic categories for constructor restoration and skipped restorations.
- Added unit tests + ApiCompat baseline updates to cover constructor suppression matching and multiple restoration/skip scenarios.
Reviewed changes
Copilot reviewed 26 out of 26 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/SourceInput/TestData/ApiCompatBaselineTests/Baseline.xml | Adds CP0002 suppressions for constructor removals (including parameterless). |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/SourceInput/TestData/ApiCompatBaselineTests/Baseline.txt | Adds text-baseline entries for missing constructors. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/SourceInput/ApiCompatBaselineTests.cs | Adds tests verifying baseline suppression matching for constructor signatures. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/** | New expected-output and last-contract inputs for constructor back-compat scenarios (restore/skip/rename/baseline/custom code). |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/ModelProviderTests.cs | Adds unit tests validating constructor restoration behavior and skip conditions. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Utilities/BackCompatHelper.cs | Adds helper to check baseline-accepted constructor removals (.ctor) to prevent resurrection. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/PartialMethodCustomization.cs | Makes CloneParameterWithName internal for reuse by model back-compat ctor reconstruction. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs | Implements restored-constructor generation/chaining + property assignment logic. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/EmitterRpc/BackCompatibilityChangeCategory.cs | Adds constructor-related back-compat diagnostic categories. |
Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
…rams Derive the restored dropped parameter's validation from the current property (property.AsParameter.Validation) instead of restoring the last contract's null-check. A dropped parameter maps to a now-optional property, so its validation is relaxed to match the current model. Also fix an ApiCompatBaselineTests assertion so it verifies the parameterless-vs-overload constructor case its comment describes. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: e815ae8d-8fc2-4c43-982e-1e98f84f4f54
|
No changes needing a change description found. |
Build the restored dropped parameter from property.AsParameter instead of the last contract's parameter, so its type, validation, and wire info all follow the current (now-optional) property automatically. This removes the per-field overrides and the now-unused wireInfo parameter on CloneParameterWithName. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: e815ae8d-8fc2-4c43-982e-1e98f84f4f54
Replace the ContainsKey guard with Dictionary.TryAdd when registering a property's pre-rename name, so a duplicate key can never throw. The direct (current) parameter name still uses an indexer assignment so it keeps precedence over another property's pre-rename name. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: e815ae8d-8fc2-4c43-982e-1e98f84f4f54
When a previously-required model property is relaxed to optional, the generator drops the corresponding parameter from the model's initialization constructor — a source-breaking change for callers that construct the model positionally (issue #11460). This restores the previously-published public constructor via the
LastContractViewback-compat mechanism.Changes
ModelProvider.BuildConstructorsForBackCompatibility(new override) — For each public constructor inLastContractViewthat has no current equivalent, reconstructs it as a public overload that chains to the closest current public constructor (: this(...)) and assigns the extra properties in its body.OriginalNamefor codegen renames. If any dropped parameter cannot be mapped, restoration is skipped.AssertNotNullcheck.BackCompatibilityChangeCategory— AddsConstructorAddedFromLastContractandConstructorAddedFromLastContractSkippedfor emitter diagnostics.Example
Given a model where
resourceswas required and is now optional, the restored overload:Tests
Added unit tests covering the restore case (required→optional), and the negative cases where the property was removed entirely or no last contract exists.