-
Notifications
You must be signed in to change notification settings - Fork 329
Update http-client-csharp generation to write ModelReaderWriterBuildableAttributes for all IPersistableModels #7908
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
Merged
Merged
Changes from all commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
483df56
Initial plan
Copilot bd6ae2f
Update System.ClientModel to 1.5.1 and add ModelReaderWriterBuildable…
Copilot 92abab4
Complete implementation of ModelReaderWriterBuildableAttribute genera…
Copilot b8ae844
Revert global.json to original .NET SDK version 9.0.102
Copilot d972d7d
Resolve merge conflict in Packages.Data.props - keep System.ClientMod…
Copilot 8cb6c8a
Resolve merge conflicts and fix SDK version compatibility
Copilot c748252
Revert global.json changes and add comprehensive ModelReaderWriterCon…
Copilot b18e0b0
Fix ModelReaderWriterBuildableAttribute generation to ensure proper u…
Copilot 7c1c995
Update ModelReaderWriterContextDefinition tests with exact count asse…
Copilot b96b301
Fix compilation error by replacing non-existent IsGenericTypeDefiniti…
Copilot b5dc1dd
Merge branch 'main' of https://github.com/microsoft/typespec into cop…
JoshLove-msft ec49c32
Fix duplicate handling
JoshLove-msft 2da1546
fix script and visitor
JoshLove-msft b784c2a
remove invalid attributes
JoshLove-msft f59e15a
working
JoshLove-msft c36c26c
fix
JoshLove-msft 861e842
force deps
JoshLove-msft 3ec0fed
Merge latest changes from main
Copilot 8f5dd17
Fix TypeOfExpression to ensure proper using statements are generated
Copilot e87c0ba
Revert TypeOfExpression.cs changes as requested
Copilot 5e78717
regen
JoshLove-msft 0ef418f
update perf for algorithm
m-nash b5878b6
update perf for algorithm (#7962)
m-nash fd1eb65
regen
m-nash 5d6afea
Merge branch 'copilot/fix-7893' of https://github.com/Microsoft/types…
m-nash File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 2 additions & 1 deletion
3
...-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Properties/AssemblyInfo.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT License. | ||
|
|
||
| using System.Runtime.CompilerServices; | ||
|
|
||
| [assembly: InternalsVisibleTo("Microsoft.TypeSpec.Generator.ClientModel.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010041df4fe80c5af6ff9a410db5a173b0ce24ad68764c623e308b1584a88b1d1d82277f746c1cccba48997e13db3366d5ed676576ffd293293baf42c643f008ba2e8a556e25e529c0407a38506555340749559f5100e6fd78cc935bb6c82d2af303beb0d3c6563400659610759b4ed5cb2e0faf36b17e6842f04cdc544c74e051ba")] | ||
| [assembly: InternalsVisibleTo("Microsoft.TypeSpec.Generator.Tests.Perf, PublicKey=002400000480000094000000060200000024000052534131000400000100010041df4fe80c5af6ff9a410db5a173b0ce24ad68764c623e308b1584a88b1d1d82277f746c1cccba48997e13db3366d5ed676576ffd293293baf42c643f008ba2e8a556e25e529c0407a38506555340749559f5100e6fd78cc935bb6c82d2af303beb0d3c6563400659610759b4ed5cb2e0faf36b17e6842f04cdc544c74e051ba")] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 6 additions & 0 deletions
6
...csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Properties/AssemblyInfo.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT License. | ||
|
|
||
| using System.Runtime.CompilerServices; | ||
|
|
||
| [assembly: InternalsVisibleTo("Microsoft.TypeSpec.Generator.Tests.Perf, PublicKey=002400000480000094000000060200000024000052534131000400000100010041df4fe80c5af6ff9a410db5a173b0ce24ad68764c623e308b1584a88b1d1d82277f746c1cccba48997e13db3366d5ed676576ffd293293baf42c643f008ba2e8a556e25e529c0407a38506555340749559f5100e6fd78cc935bb6c82d2af303beb0d3c6563400659610759b4ed5cb2e0faf36b17e6842f04cdc544c74e051ba")] |
219 changes: 219 additions & 0 deletions
219
...nerator.ClientModel/test/Providers/Definitions/ModelReaderWriterContextDefinitionTests.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,219 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT License. | ||
|
|
||
| using System; | ||
| using System.ClientModel.Primitives; | ||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
| using System.Text.Json; | ||
| using Microsoft.TypeSpec.Generator.ClientModel.Providers; | ||
| using Microsoft.TypeSpec.Generator.Input; | ||
| using Microsoft.TypeSpec.Generator.Primitives; | ||
| using Microsoft.TypeSpec.Generator.Tests.Common; | ||
| using NUnit.Framework; | ||
|
|
||
| namespace Microsoft.TypeSpec.Generator.ClientModel.Tests.Providers.Definitions | ||
| { | ||
| public class ModelReaderWriterContextDefinitionTests | ||
| { | ||
| [Test] | ||
| public void ValidateModelReaderWriterContextIsGenerated() | ||
| { | ||
| MockHelpers.LoadMockGenerator(); | ||
|
|
||
| var contextDefinition = new ModelReaderWriterContextDefinition(); | ||
|
|
||
| Assert.IsNotNull(contextDefinition); | ||
| Assert.IsNotNull(contextDefinition.Name); | ||
| Assert.IsTrue(contextDefinition.Name.EndsWith("Context")); | ||
| Assert.IsNotNull(contextDefinition.DeclarationModifiers); | ||
| Assert.IsTrue(contextDefinition.DeclarationModifiers.HasFlag(TypeSignatureModifiers.Public)); | ||
| Assert.IsTrue(contextDefinition.DeclarationModifiers.HasFlag(TypeSignatureModifiers.Partial)); | ||
| Assert.IsTrue(contextDefinition.DeclarationModifiers.HasFlag(TypeSignatureModifiers.Class)); | ||
| Assert.IsNotNull(contextDefinition.Implements); | ||
| Assert.IsTrue(contextDefinition.Implements.Contains(typeof(ModelReaderWriterContext))); | ||
| } | ||
|
|
||
| [Test] | ||
| public void ValidateModelReaderWriterBuildableAttributesAreGenerated() | ||
| { | ||
| var mockGenerator = MockHelpers.LoadMockGenerator( | ||
| inputModels: () => new List<InputModelType> | ||
| { | ||
| InputFactory.Model("TestModel", properties: | ||
| [ | ||
| InputFactory.Property("StringProperty", InputPrimitiveType.String), | ||
| InputFactory.Property("IntProperty", InputPrimitiveType.Int32) | ||
| ]) | ||
| }); | ||
|
|
||
| var contextDefinition = new ModelReaderWriterContextDefinition(); | ||
| var attributes = contextDefinition.Attributes; | ||
|
|
||
| Assert.IsNotNull(attributes); | ||
| Assert.IsTrue(attributes.Count > 0); | ||
|
|
||
| // Check that exactly one ModelReaderWriterBuildableAttribute exists since TestModel has only primitive properties | ||
| var buildableAttributes = attributes.Where(a => a.Type.IsFrameworkType && a.Type.FrameworkType == typeof(ModelReaderWriterBuildableAttribute)); | ||
| Assert.AreEqual(1, buildableAttributes.Count(), "Exactly one ModelReaderWriterBuildableAttribute should be generated for TestModel"); | ||
| } | ||
|
|
||
| [Test] | ||
| public void ValidateModelReaderWriterBuildableAttributesIncludeNestedModels() | ||
m-nash marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| { | ||
| // Create a model with a property that references another model | ||
| var nestedModel = InputFactory.Model("NestedModel", properties: | ||
| [ | ||
| InputFactory.Property("NestedValue", InputPrimitiveType.String) | ||
| ]); | ||
|
|
||
| var parentModel = InputFactory.Model("ParentModel", properties: | ||
| [ | ||
| InputFactory.Property("NestedProperty", nestedModel), | ||
| InputFactory.Property("SimpleProperty", InputPrimitiveType.String) | ||
| ]); | ||
|
|
||
| var mockGenerator = MockHelpers.LoadMockGenerator( | ||
| inputModels: () => [parentModel, nestedModel]); | ||
|
|
||
| var contextDefinition = new ModelReaderWriterContextDefinition(); | ||
| var attributes = contextDefinition.Attributes; | ||
|
|
||
| Assert.IsNotNull(attributes); | ||
| Assert.IsTrue(attributes.Count > 0); | ||
|
|
||
| // Check that exactly two ModelReaderWriterBuildableAttribute exist for both models | ||
| var buildableAttributes = attributes.Where(a => a.Type.IsFrameworkType && a.Type.FrameworkType == typeof(ModelReaderWriterBuildableAttribute)); | ||
| Assert.AreEqual(2, buildableAttributes.Count(), "Exactly two ModelReaderWriterBuildableAttributes should be generated for nested models"); | ||
| } | ||
|
|
||
| [Test] | ||
| public void ValidateModelReaderWriterBuildableAttributesHandleCollectionProperties() | ||
| { | ||
| // Create a model with a collection property containing another model | ||
| var itemModel = InputFactory.Model("ItemModel", properties: | ||
| [ | ||
| InputFactory.Property("ItemValue", InputPrimitiveType.String) | ||
| ]); | ||
|
|
||
| var collectionModel = InputFactory.Model("CollectionModel", properties: | ||
| [ | ||
| InputFactory.Property("Items", InputFactory.Array(itemModel)) | ||
| ]); | ||
|
|
||
| var mockGenerator = MockHelpers.LoadMockGenerator( | ||
| inputModels: () => [collectionModel, itemModel]); | ||
|
|
||
| var contextDefinition = new ModelReaderWriterContextDefinition(); | ||
| var attributes = contextDefinition.Attributes; | ||
|
|
||
| Assert.IsNotNull(attributes); | ||
| Assert.IsTrue(attributes.Count > 0); | ||
|
|
||
| // Check that exactly two ModelReaderWriterBuildableAttribute exist for both models | ||
| var buildableAttributes = attributes.Where(a => a.Type.IsFrameworkType && a.Type.FrameworkType == typeof(ModelReaderWriterBuildableAttribute)); | ||
| Assert.AreEqual(2, buildableAttributes.Count(), "Exactly two ModelReaderWriterBuildableAttributes should be generated for collection item models"); | ||
| } | ||
|
|
||
| [Test] | ||
| public void ValidateModelReaderWriterBuildableAttributesAvoidDuplicates() | ||
| { | ||
| // Create models with circular references to test duplicate handling | ||
| var modelA = InputFactory.Model("ModelA", properties: | ||
| [ | ||
| InputFactory.Property("PropertyA", InputPrimitiveType.String) | ||
| ]); | ||
|
|
||
| var modelB = InputFactory.Model("ModelB", properties: | ||
| [ | ||
| InputFactory.Property("PropertyB", InputPrimitiveType.String), | ||
| InputFactory.Property("ModelARef", modelA) | ||
| ]); | ||
|
|
||
| // Add a property to ModelA that references ModelB to create a circular reference | ||
| var modelAWithCircularRef = InputFactory.Model("ModelA", properties: | ||
| [ | ||
| InputFactory.Property("PropertyA", InputPrimitiveType.String), | ||
| InputFactory.Property("ModelBRef", modelB) | ||
| ]); | ||
|
|
||
| var mockGenerator = MockHelpers.LoadMockGenerator( | ||
| inputModels: () => [modelAWithCircularRef, modelB]); | ||
|
|
||
| var contextDefinition = new ModelReaderWriterContextDefinition(); | ||
| var attributes = contextDefinition.Attributes; | ||
|
|
||
| Assert.IsNotNull(attributes); | ||
|
|
||
| // Check that no duplicate attributes exist | ||
| var buildableAttributes = attributes.Where(a => a.Type.IsFrameworkType && a.Type.FrameworkType == typeof(ModelReaderWriterBuildableAttribute)); | ||
| var uniqueTypes = buildableAttributes.Select(a => a.Arguments.First().ToString()).Distinct().ToList(); | ||
|
|
||
| Assert.AreEqual(buildableAttributes.Count(), uniqueTypes.Count, | ||
| "No duplicate ModelReaderWriterBuildableAttributes should be generated"); | ||
| } | ||
|
|
||
| [Test] | ||
| public void ValidateModelReaderWriterBuildableAttributesIncludeDependencyModels() | ||
| { | ||
| // Create a model with a property that references a model from a dependency library | ||
| // The dependency model won't have a model provider in the current library | ||
| var dependencyModel = InputFactory.Model("DependencyModel"); | ||
|
|
||
| var parentModel = InputFactory.Model("ParentModel", properties: | ||
| [ | ||
| InputFactory.Property("DependencyProperty", dependencyModel), | ||
| InputFactory.Property("SimpleProperty", InputPrimitiveType.String) | ||
| ]); | ||
|
|
||
| // Only include the parentModel in the mock generator, simulating that | ||
| // dependencyModel is from a dependency library | ||
| var mockGenerator = MockHelpers.LoadMockGenerator( | ||
| inputModels: () => [parentModel], | ||
| createCSharpTypeCore: input => | ||
| { | ||
| return new CSharpType(typeof(DependencyModel)); | ||
| }, | ||
| createCSharpTypeCoreFallback: input => input.Name == "DependencyModel"); | ||
|
|
||
| var contextDefinition = new ModelReaderWriterContextDefinition(); | ||
| var attributes = contextDefinition.Attributes; | ||
|
|
||
| Assert.IsNotNull(attributes); | ||
| Assert.IsTrue(attributes.Count > 0); | ||
|
|
||
| // Check that exactly two ModelReaderWriterBuildableAttribute exist: | ||
| // one for ParentModel and one for the dependency model | ||
| var buildableAttributes = attributes.Where(a => a.Type.IsFrameworkType && a.Type.FrameworkType == typeof(ModelReaderWriterBuildableAttribute)); | ||
| Assert.AreEqual(2, buildableAttributes.Count(), "Exactly two ModelReaderWriterBuildableAttributes should be generated for models with dependency references"); | ||
| } | ||
|
|
||
| private class DependencyModel : IJsonModel<DependencyModel> | ||
| { | ||
| DependencyModel? IJsonModel<DependencyModel>.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) | ||
| { | ||
| throw new NotImplementedException(); | ||
| } | ||
|
|
||
| DependencyModel? IPersistableModel<DependencyModel>.Create(BinaryData data, ModelReaderWriterOptions options) | ||
| { | ||
| throw new NotImplementedException(); | ||
| } | ||
|
|
||
| string IPersistableModel<DependencyModel>.GetFormatFromOptions(ModelReaderWriterOptions options) | ||
| { | ||
| throw new NotImplementedException(); | ||
| } | ||
|
|
||
| void IJsonModel<DependencyModel>.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) | ||
| { | ||
| throw new NotImplementedException(); | ||
| } | ||
|
|
||
| BinaryData IPersistableModel<DependencyModel>.Write(ModelReaderWriterOptions options) | ||
| { | ||
| throw new NotImplementedException(); | ||
| } | ||
| } | ||
| } | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.