Centralize C# type attribute back-compat merging in TypeProvider#11237
Centralize C# type attribute back-compat merging in TypeProvider#11237jorgerangel-msft with Copilot wants to merge 32 commits into
Conversation
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>
… attributes, perf Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
commit: |
…p internalize gating, add tests Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
…tions Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
…pe-attribute-merging # Conflicts: # packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ModelReaderWriterContextDefinition.cs # packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/TestHelpers/MockHelpers.cs Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Centralizes attribute back-compat handling in the C# generator’s TypeProvider so attribute restoration/merging from the last contract happens through the same back-compat pipeline as other members, and adds targeted ClientModel filtering for generator-owned attributes that must be recomputed.
Changes:
- Added
TypeProvider.BuildAttributesForBackCompatibility(...)and wired attribute restoration intoProcessTypeForBackCompatibility(). - Added ClientModel-specific filtering to drop recomputed generator-owned attributes (e.g., proxy/buildable attributes) after restoration.
- Added/expanded unit tests + golden test data for restore/skip/dedup scenarios.
Reviewed changes
Copilot reviewed 36 out of 36 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/TestHelpers/TestTypeProvider.cs | Extends test provider to supply attributes for back-compat tests. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TypeProviderTests.cs | Adds unit tests covering attribute back-compat restore/skip/dedup behavior. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/BuildAttributesForBackCompatibilitySkipsExperimentalAttribute/BackCompatAttributeType.cs | Last-contract input for Experimental attribute skip scenario. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/BuildAttributesForBackCompatibilitySkipsExperimentalAttribute.cs | Expected generated output for Experimental attribute skip scenario. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/BuildAttributesForBackCompatibilitySkipsEditorBrowsableAttribute/BackCompatAttributeType.cs | Last-contract input for EditorBrowsable attribute skip scenario. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/BuildAttributesForBackCompatibilitySkipsEditorBrowsableAttribute.cs | Expected generated output for EditorBrowsable attribute skip scenario. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/BuildAttributesForBackCompatibilitySkipsDefaultMemberAttribute/BackCompatAttributeType.cs | Last-contract input for DefaultMember attribute skip scenario. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/BuildAttributesForBackCompatibilitySkipsDefaultMemberAttribute.cs | Expected generated output for DefaultMember attribute skip scenario. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/BuildAttributesForBackCompatibilitySkipsCodeGenAttributes/BackCompatAttributeType.cs | Last-contract input for CodeGen attribute skip scenario. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/BuildAttributesForBackCompatibilitySkipsCodeGenAttributes.cs | Expected generated output for CodeGen attribute skip scenario. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/BuildAttributesForBackCompatibilitySkipsAttributesAlreadyInCustomCode/BackCompatAttributeType.cs | Last-contract input where an attribute exists in custom code already. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/BuildAttributesForBackCompatibilitySkipsAttributesAlreadyInCustomCode(Custom)/BackCompatAttributeType.cs | Custom-code input for “already in custom code” scenario. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/BuildAttributesForBackCompatibilitySkipsAttributesAlreadyInCustomCode.cs | Expected generated output for “already in custom code” scenario. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/BuildAttributesForBackCompatibilitySkipsAllCodeGenPrefixedAttributes/BackCompatAttributeType.cs | Last-contract input for CodeGen-prefixed attribute skip scenario. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/BuildAttributesForBackCompatibilitySkipsAllCodeGenPrefixedAttributes.cs | Expected generated output for CodeGen-prefixed attribute skip scenario. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/BuildAttributesForBackCompatibilityReturnsGeneratedAttributesWhenNoLastContract.cs | Expected output when no last contract is present. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/BuildAttributesForBackCompatibilityDoesNotDuplicateExistingAttribute/BackCompatAttributeType.cs | Last-contract input for duplicate-prevention scenario. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/BuildAttributesForBackCompatibilityDoesNotDuplicateExistingAttribute.cs | Expected output for duplicate-prevention scenario. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/BuildAttributesForBackCompatibilityAddsAttributeFromLastContract/BackCompatAttributeType.cs | Last-contract input for add-new-attribute scenario. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/BuildAttributesForBackCompatibilityAddsAttributeFromLastContract.cs | Expected output for add-new-attribute scenario. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/SourceInput/CodeGenAttributes.cs | Adds shared CodeGen prefix constant for filtering. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs | Implements attribute back-compat restore logic and integrates it into processing/update. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/TestHelpers/MockHelpers.cs | Extends generator mock setup to allow injecting serialization providers in tests. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ScmModelProvider/TestData/ScmModelProviderTests/BuildAttributesForBackCompatibilityDoesNotRestoreProxyAttribute/Pet.cs | Last-contract input for proxy-attribute filtering in ScmModelProvider. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ScmModelProvider/TestData/ScmModelProviderTests/BuildAttributesForBackCompatibilityDoesNotRestoreProxyAttribute.cs | Expected output verifying proxy attribute is not restored. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ScmModelProvider/ScmModelProviderTests.cs | Adds test ensuring proxy attributes aren’t restored for models. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/TestData/BackCompatibilityTests/BuildAttributesForBackCompatibilityDoesNotRestoreProxyAttribute/Pet.cs | Last-contract input for proxy-attribute filtering in MRW serialization provider. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/TestData/BackCompatibilityTests/BuildAttributesForBackCompatibilityDoesNotRestoreProxyAttribute.cs | Expected output verifying proxy attribute is not restored in MRW serialization provider. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/BackCompatibilityTests.cs | Adds MRW serialization-provider back-compat attribute filtering test. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/TestData/ModelReaderWriterContextDefinitionTests/BuildAttributesForBackCompatibilityDoesNotRestoreBuildableAttribute/SampleContext.cs | Last-contract input for buildable-attribute filtering in MRW context definition. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/TestData/ModelReaderWriterContextDefinitionTests/BuildAttributesForBackCompatibilityDoesNotRestoreBuildableAttribute.cs | Expected output verifying buildable attribute is not restored. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/ModelReaderWriterContextDefinitionTests.cs | Adds test ensuring buildable attributes aren’t restored for MRW context definition. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Utilities/ScmBackCompatibilityHelpers.cs | Adds helper to remove newly-restored generator-owned attributes. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmModelProvider.cs | Overrides attribute back-compat to drop restored proxy attribute for models. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs | Overrides attribute back-compat to drop restored proxy attribute for serialization providers. |
| packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ModelReaderWriterContextDefinition.cs | Overrides attribute back-compat to drop restored buildable attribute for contexts. |
|
@copilot there was a crash with our changes: |
…butes with integral literal args Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
…ic exception types Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
... Fixed. Root cause: back-compat restoration renders each last-contract attribute via Two changes:
Added unit tests: |
…tected types Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
…ibute display string 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 I'd like to see some unit tests where a type has attributes in back compat, custom code, and current generated source. We should validate there are no duplicates and things work as expected
…; drop comment Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
Added |
Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
| if (!DeclarationModifiers.HasFlag(TypeSignatureModifiers.Public) | ||
| && !DeclarationModifiers.HasFlag(TypeSignatureModifiers.Protected)) | ||
| { | ||
| return original; | ||
| } |
There was a problem hiding this comment.
The accurate wording is: attribute restoration only applies to externally visible types (public / protected), while generated and custom-code attributes are still merged and generator-owned / CodeGen attributes are skipped. I can’t edit the PR body directly from this environment, but that is the text that should replace the old “non-public types only” wording.
I checked the link, but it currently redirects to |
|
@copilot address this comment #11237 (comment) |
The referenced thread is about the PR description, not the implementation. The correct wording is: attribute restoration only applies to externally visible types ( |
Attribute back-compat merging (generated + last-contract + custom-code) was owned locally by
CanonicalTypeProvider.BuildAttributes(). This moves that logic into a sharedTypeProviderAPI so it follows the existing centralized back-compat pattern (Build*ForBackCompatibility).Changes
TypeProvider: AddedBuildAttributesForBackCompatibility()that:Attributes) and custom-code (CustomCodeView.Attributes) attributes,CodeGenSuppress/CodeGenMember/CodeGenType/CodeGenSerialization) that should not be preserved,CanonicalTypeProvider:BuildAttributes()now delegates to the shared API instead of owning merge/dedup logic.Because the method reads
Attributes,CustomCodeView,LastContractView, andDeclarationModifiersfrom the provider, invoking it on the generated provider reproduces the previous merge exactly: