From 928dce2ccc8c9d246022b52c8d9dae8eb9e2c1d1 Mon Sep 17 00:00:00 2001 From: Wei Hu Date: Mon, 10 Feb 2025 15:43:46 +0800 Subject: [PATCH 01/12] Add abstraction for setting namespace of Model and Enum. --- .../src/Providers/EnumProvider.cs | 4 +--- .../src/Providers/ModelProvider.cs | 4 +--- .../src/TypeFactory.cs | 16 ++++++++++++++++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/EnumProvider.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/EnumProvider.cs index 9401402899b..ca255c6827d 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/EnumProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/EnumProvider.cs @@ -55,9 +55,7 @@ protected override TypeProvider[] BuildSerializationProviders() { return [.. CodeModelPlugin.Instance.TypeFactory.CreateSerializations(_inputType, this)]; } - protected override string BuildNamespace() => string.IsNullOrEmpty(_inputType.Namespace) ? - CodeModelPlugin.Instance.TypeFactory.RootNamespace : // we default to this model namespace when the namespace is empty - CodeModelPlugin.Instance.TypeFactory.GetCleanNameSpace(_inputType.Namespace); + protected override string BuildNamespace() => CodeModelPlugin.Instance.TypeFactory.GetEnumNamespace(_inputType); protected override bool GetIsEnum() => true; protected override CSharpType BuildEnumUnderlyingType() => CodeModelPlugin.Instance.TypeFactory.CreateCSharpType(_inputType.ValueType) ?? throw new InvalidOperationException($"Failed to create CSharpType for {_inputType.ValueType}"); diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ModelProvider.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ModelProvider.cs index 9a6bca9c4c5..cccab614756 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ModelProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ModelProvider.cs @@ -86,9 +86,7 @@ public ModelProvider? BaseModelProvider internal bool SupportsBinaryDataAdditionalProperties => AdditionalPropertyProperties.Any(p => p.Type.ElementType.Equals(_additionalPropsUnknownType)); public ConstructorProvider FullConstructor => _fullConstructor ??= BuildFullConstructor(); - protected override string BuildNamespace() => string.IsNullOrEmpty(_inputModel.Namespace) ? - CodeModelPlugin.Instance.TypeFactory.RootNamespace : - CodeModelPlugin.Instance.TypeFactory.GetCleanNameSpace(_inputModel.Namespace); + protected override string BuildNamespace() => CodeModelPlugin.Instance.TypeFactory.GetModelNamespace(_inputModel); protected override CSharpType? GetBaseType() { diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/TypeFactory.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/TypeFactory.cs index 2349193e87d..59811f9ba8c 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/TypeFactory.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/TypeFactory.cs @@ -37,6 +37,22 @@ public class TypeFactory private HashSet? _unionTypes; internal HashSet UnionTypes => _unionTypes ??= []; + /// + /// Get namespace for the input model. + /// + /// The input model + /// Output namespace of the input model. + public virtual string GetModelNamespace(InputModelType inputModel) + => string.IsNullOrEmpty(inputModel.Namespace) ? RootNamespace : GetCleanNameSpace(inputModel.Namespace); + + /// + /// Get namespace for the input enum. + /// + /// The input enum. + /// Output namespace of the input enum. + public virtual string GetEnumNamespace(InputEnumType inputEnum) + => string.IsNullOrEmpty(inputEnum.Namespace) ? RootNamespace : GetCleanNameSpace(inputEnum.Namespace); // we default to this model namespace when the namespace is empty + protected internal TypeFactory() { } From 15efe67f464827928f4a56e452ff3df76e02839c Mon Sep 17 00:00:00 2001 From: Wei Hu Date: Mon, 10 Feb 2025 16:44:00 +0800 Subject: [PATCH 02/12] Add abstrction to set model factory namespace --- .../src/Providers/ModelFactoryProvider.cs | 2 +- .../generator/Microsoft.Generator.CSharp/src/TypeFactory.cs | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ModelFactoryProvider.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ModelFactoryProvider.cs index fcbeaf0cef2..7584746c8ef 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ModelFactoryProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ModelFactoryProvider.cs @@ -54,7 +54,7 @@ protected override string BuildName() protected override TypeSignatureModifiers BuildDeclarationModifiers() => TypeSignatureModifiers.Static | TypeSignatureModifiers.Partial | TypeSignatureModifiers.Class; - protected override string BuildNamespace() => CodeModelPlugin.Instance.TypeFactory.GetCleanNameSpace(CodeModelPlugin.Instance.InputLibrary.InputNamespace.Name); + protected override string BuildNamespace() => CodeModelPlugin.Instance.TypeFactory.GetModelFactoryNamespace(); protected override XmlDocProvider BuildXmlDocs() { diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/TypeFactory.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/TypeFactory.cs index 59811f9ba8c..f319ee2b545 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/TypeFactory.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/TypeFactory.cs @@ -53,6 +53,12 @@ public virtual string GetModelNamespace(InputModelType inputModel) public virtual string GetEnumNamespace(InputEnumType inputEnum) => string.IsNullOrEmpty(inputEnum.Namespace) ? RootNamespace : GetCleanNameSpace(inputEnum.Namespace); // we default to this model namespace when the namespace is empty + /// + /// Get namespace for the model factory. + /// + /// Output namespace for the model factory. + public virtual string GetModelFactoryNamespace() => GetCleanNameSpace(CodeModelPlugin.Instance.InputLibrary.InputNamespace.Name); + protected internal TypeFactory() { } From b3477668db265d22371d7f6502d504f5ae32c4a6 Mon Sep 17 00:00:00 2001 From: Wei Hu Date: Tue, 11 Feb 2025 09:29:15 +0800 Subject: [PATCH 03/12] revert namespace abstraction, add public setter instead --- .../src/Primitives/CSharpType.cs | 2 +- .../src/Providers/EnumProvider.cs | 4 +++- .../src/Providers/ModelFactoryProvider.cs | 2 +- .../src/Providers/ModelProvider.cs | 4 +++- .../src/Providers/TypeProvider.cs | 12 +++++++++- .../src/TypeFactory.cs | 22 ------------------- 6 files changed, 19 insertions(+), 27 deletions(-) diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Primitives/CSharpType.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Primitives/CSharpType.cs index edd203be450..086eb373df1 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Primitives/CSharpType.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Primitives/CSharpType.cs @@ -180,7 +180,7 @@ internal CSharpType( _underlyingType = underlyingEnumType; } - public string Namespace { get; private init; } + public string Namespace { get; set; } public string Name { get; private init; } public CSharpType? DeclaringType { get; private init; } public bool IsValueType { get; private init; } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/EnumProvider.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/EnumProvider.cs index ca255c6827d..9401402899b 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/EnumProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/EnumProvider.cs @@ -55,7 +55,9 @@ protected override TypeProvider[] BuildSerializationProviders() { return [.. CodeModelPlugin.Instance.TypeFactory.CreateSerializations(_inputType, this)]; } - protected override string BuildNamespace() => CodeModelPlugin.Instance.TypeFactory.GetEnumNamespace(_inputType); + protected override string BuildNamespace() => string.IsNullOrEmpty(_inputType.Namespace) ? + CodeModelPlugin.Instance.TypeFactory.RootNamespace : // we default to this model namespace when the namespace is empty + CodeModelPlugin.Instance.TypeFactory.GetCleanNameSpace(_inputType.Namespace); protected override bool GetIsEnum() => true; protected override CSharpType BuildEnumUnderlyingType() => CodeModelPlugin.Instance.TypeFactory.CreateCSharpType(_inputType.ValueType) ?? throw new InvalidOperationException($"Failed to create CSharpType for {_inputType.ValueType}"); diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ModelFactoryProvider.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ModelFactoryProvider.cs index 7584746c8ef..fcbeaf0cef2 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ModelFactoryProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ModelFactoryProvider.cs @@ -54,7 +54,7 @@ protected override string BuildName() protected override TypeSignatureModifiers BuildDeclarationModifiers() => TypeSignatureModifiers.Static | TypeSignatureModifiers.Partial | TypeSignatureModifiers.Class; - protected override string BuildNamespace() => CodeModelPlugin.Instance.TypeFactory.GetModelFactoryNamespace(); + protected override string BuildNamespace() => CodeModelPlugin.Instance.TypeFactory.GetCleanNameSpace(CodeModelPlugin.Instance.InputLibrary.InputNamespace.Name); protected override XmlDocProvider BuildXmlDocs() { diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ModelProvider.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ModelProvider.cs index cccab614756..9a6bca9c4c5 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ModelProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ModelProvider.cs @@ -86,7 +86,9 @@ public ModelProvider? BaseModelProvider internal bool SupportsBinaryDataAdditionalProperties => AdditionalPropertyProperties.Any(p => p.Type.ElementType.Equals(_additionalPropsUnknownType)); public ConstructorProvider FullConstructor => _fullConstructor ??= BuildFullConstructor(); - protected override string BuildNamespace() => CodeModelPlugin.Instance.TypeFactory.GetModelNamespace(_inputModel); + protected override string BuildNamespace() => string.IsNullOrEmpty(_inputModel.Namespace) ? + CodeModelPlugin.Instance.TypeFactory.RootNamespace : + CodeModelPlugin.Instance.TypeFactory.GetCleanNameSpace(_inputModel.Namespace); protected override CSharpType? GetBaseType() { diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/TypeProvider.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/TypeProvider.cs index 05a365cd387..df69648a2c0 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/TypeProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/TypeProvider.cs @@ -90,7 +90,17 @@ private IReadOnlyList BuildAllCustomFields() private string? _name; - public string Namespace => _namespace ??= BuildNamespace(); + public string Namespace + { + get + { + return _namespace ??= BuildNamespace(); + } + set + { + _namespace = value; + } + } private string? _namespace; protected virtual FormattableString Description { get; } = FormattableStringHelpers.Empty; diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/TypeFactory.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/TypeFactory.cs index f319ee2b545..2349193e87d 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/TypeFactory.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/TypeFactory.cs @@ -37,28 +37,6 @@ public class TypeFactory private HashSet? _unionTypes; internal HashSet UnionTypes => _unionTypes ??= []; - /// - /// Get namespace for the input model. - /// - /// The input model - /// Output namespace of the input model. - public virtual string GetModelNamespace(InputModelType inputModel) - => string.IsNullOrEmpty(inputModel.Namespace) ? RootNamespace : GetCleanNameSpace(inputModel.Namespace); - - /// - /// Get namespace for the input enum. - /// - /// The input enum. - /// Output namespace of the input enum. - public virtual string GetEnumNamespace(InputEnumType inputEnum) - => string.IsNullOrEmpty(inputEnum.Namespace) ? RootNamespace : GetCleanNameSpace(inputEnum.Namespace); // we default to this model namespace when the namespace is empty - - /// - /// Get namespace for the model factory. - /// - /// Output namespace for the model factory. - public virtual string GetModelFactoryNamespace() => GetCleanNameSpace(CodeModelPlugin.Instance.InputLibrary.InputNamespace.Name); - protected internal TypeFactory() { } From 4d1e781ebb40cf4051e0e001dfc4c08f2c77f2c9 Mon Sep 17 00:00:00 2001 From: Wei Hu Date: Tue, 11 Feb 2025 09:33:47 +0800 Subject: [PATCH 04/12] expose EnumProvider to let sub-plugin identify --- .../Microsoft.Generator.CSharp/src/Providers/EnumProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/EnumProvider.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/EnumProvider.cs index 9401402899b..4f4f4143d45 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/EnumProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/EnumProvider.cs @@ -9,7 +9,7 @@ namespace Microsoft.Generator.CSharp.Providers { - internal abstract class EnumProvider : TypeProvider + public abstract class EnumProvider : TypeProvider { private readonly InputEnumType _inputType; From cc4d3780461473db569029cdedd85cbae3120f3d Mon Sep 17 00:00:00 2001 From: Wei Hu Date: Tue, 11 Feb 2025 09:34:47 +0800 Subject: [PATCH 05/12] expose ModelFactoryProvider --- .../src/Providers/ModelFactoryProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ModelFactoryProvider.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ModelFactoryProvider.cs index fcbeaf0cef2..81d425b9fb3 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ModelFactoryProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ModelFactoryProvider.cs @@ -14,7 +14,7 @@ namespace Microsoft.Generator.CSharp.Providers { - internal class ModelFactoryProvider : TypeProvider + public class ModelFactoryProvider : TypeProvider { private const string ModelFactorySuffix = "ModelFactory"; private const string AdditionalBinaryDataParameterName = "additionalBinaryDataProperties"; From d9798a6101dcbce89dbdc1dfb6fb04120f02c854 Mon Sep 17 00:00:00 2001 From: Wei Hu Date: Tue, 11 Feb 2025 10:13:20 +0800 Subject: [PATCH 06/12] remove Namespace from TypeProvider, use TypeProvider.Type.Namespace for all the usages. --- .../src/Providers/RestClientProvider.cs | 2 +- .../src/PostProcessing/GeneratedCodeWorkspace.cs | 2 +- .../src/Providers/CanonicalTypeProvider.cs | 2 +- .../src/Providers/TypeProvider.cs | 13 ------------- .../test/Providers/CanonicalTypeProviderTests.cs | 2 +- 5 files changed, 4 insertions(+), 17 deletions(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/RestClientProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/RestClientProvider.cs index 3dda3d0d452..0b3e8c42443 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/RestClientProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/RestClientProvider.cs @@ -46,7 +46,7 @@ public RestClientProvider(InputClient inputClient, ClientProvider clientProvider protected override string BuildName() => _inputClient.Name.ToCleanName(); - protected override string BuildNamespace() => ClientProvider.Namespace; + protected override string BuildNamespace() => ClientProvider.Type.Namespace; protected override PropertyProvider[] BuildProperties() { diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/PostProcessing/GeneratedCodeWorkspace.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/PostProcessing/GeneratedCodeWorkspace.cs index 5250deed1da..414e6c28da8 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/PostProcessing/GeneratedCodeWorkspace.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/PostProcessing/GeneratedCodeWorkspace.cs @@ -214,7 +214,7 @@ public async Task PostProcessAsync() var modelFactory = ModelFactoryProvider.FromInputLibrary(); var postProcessor = new PostProcessor( [.. CodeModelPlugin.Instance.TypeFactory.UnionTypes, .. CodeModelPlugin.Instance.TypesToKeep], - modelFactoryFullName: $"{modelFactory.Namespace}.{modelFactory.Name}"); + modelFactoryFullName: $"{modelFactory.Type.Namespace}.{modelFactory.Name}"); switch (Configuration.UnreferencedTypesHandling) { case Configuration.UnreferencedTypesHandlingOption.KeepAll: diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/CanonicalTypeProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/CanonicalTypeProvider.cs index 23c97415594..627d0c523ef 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/CanonicalTypeProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/CanonicalTypeProvider.cs @@ -35,7 +35,7 @@ public CanonicalTypeProvider(TypeProvider generatedTypeProvider, InputType? inpu protected override string BuildName() => _generatedTypeProvider.Name; - protected override string BuildNamespace() => _generatedTypeProvider.Namespace; + protected override string BuildNamespace() => _generatedTypeProvider.Type.Namespace; protected override TypeSignatureModifiers BuildDeclarationModifiers() => _generatedTypeProvider.DeclarationModifiers; diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs index 41fc3a48669..9b70050fd8a 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs @@ -90,19 +90,6 @@ private IReadOnlyList BuildAllCustomFields() private string? _name; - public string Namespace - { - get - { - return _namespace ??= BuildNamespace(); - } - set - { - _namespace = value; - } - } - private string? _namespace; - protected virtual FormattableString Description { get; } = FormattableStringHelpers.Empty; private XmlDocProvider? _xmlDocs; diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/CanonicalTypeProviderTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/CanonicalTypeProviderTests.cs index d81080b5f1c..b3540d4217e 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/CanonicalTypeProviderTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/CanonicalTypeProviderTests.cs @@ -49,7 +49,7 @@ public void ValidateName() [Test] public void ValidateNamespace() { - Assert.AreEqual(_typeProvider.Namespace, _typeProvider.CanonicalView.Namespace); + Assert.AreEqual(_typeProvider.Type.Namespace, _typeProvider.CanonicalView.Type.Namespace); } [Test] From b058ac6c1c83b2c3caecd6cabde6167bf5608b55 Mon Sep 17 00:00:00 2001 From: Wei Hu Date: Wed, 12 Feb 2025 08:47:42 +0800 Subject: [PATCH 07/12] expose ExtensibleEnumSerializationProvider and FixedEnumSerializationProvider --- .../src/Providers/ExtensibleEnumSerializationProvider.cs | 2 +- .../src/Providers/FixedEnumSerializationProvider.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ExtensibleEnumSerializationProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ExtensibleEnumSerializationProvider.cs index f8ac6b12782..f3c5a792c95 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ExtensibleEnumSerializationProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ExtensibleEnumSerializationProvider.cs @@ -12,7 +12,7 @@ namespace Microsoft.TypeSpec.Generator.ClientModel.Providers /// /// This defines a class with extension methods for enums to convert an enum to its underlying value, or from its underlying value to an instance of the enum /// - internal partial class ExtensibleEnumSerializationProvider : TypeProvider + public partial class ExtensibleEnumSerializationProvider : TypeProvider { private readonly InputEnumType _enumType; private TypeProvider _enumProvider; diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/FixedEnumSerializationProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/FixedEnumSerializationProvider.cs index 9d75698eb18..0393c977fd7 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/FixedEnumSerializationProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/FixedEnumSerializationProvider.cs @@ -18,7 +18,7 @@ namespace Microsoft.TypeSpec.Generator.ClientModel.Providers /// /// This defines a class with extension methods for enums to convert an enum to its underlying value, or from its underlying value to an instance of the enum /// - internal class FixedEnumSerializationProvider : TypeProvider + public class FixedEnumSerializationProvider : TypeProvider { private readonly InputEnumType _enumType; private TypeProvider _enumProvider; From 98b25011130d684d025244b6773d5ee7e0fe2dd8 Mon Sep 17 00:00:00 2001 From: Wei Hu Date: Wed, 12 Feb 2025 10:27:11 +0800 Subject: [PATCH 08/12] remove duplicate instances of model factory --- .../src/Providers/ModelFactoryProvider.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs index 5d21c412c57..de4149c66fc 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs @@ -21,7 +21,8 @@ public class ModelFactoryProvider : TypeProvider private readonly IEnumerable _models; - public static ModelFactoryProvider FromInputLibrary() => new ModelFactoryProvider(CodeModelPlugin.Instance.InputLibrary.InputNamespace.Models); + private static ModelFactoryProvider? _modelFactoryProvider; + public static ModelFactoryProvider FromInputLibrary() => _modelFactoryProvider ??= new ModelFactoryProvider(CodeModelPlugin.Instance.InputLibrary.InputNamespace.Models); private ModelFactoryProvider(IEnumerable models) { From 1972665128de7499fd2b3fa117446265f40234aa Mon Sep 17 00:00:00 2001 From: Wei Hu Date: Wed, 12 Feb 2025 10:35:07 +0800 Subject: [PATCH 09/12] remove GenerateModelFactory from configuration --- .../Microsoft.TypeSpec.Generator/src/Configuration.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Configuration.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Configuration.cs index 6961687b4e4..d1e12baece0 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Configuration.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Configuration.cs @@ -89,12 +89,6 @@ private static class Options /// internal bool ClearOutputFolder { get; private set; } - /// - /// Whether we will generate model factory for this library. - /// If true (default), the model factory will be generated. If false, the model factory will not be generated. - /// - internal bool GenerateModelFactory { get; private set; } - /// /// True if a sample project should be generated. /// From 28df98ad67d6dcaea88772a2e54fc1fd5763860b Mon Sep 17 00:00:00 2001 From: Wei Hu Date: Wed, 12 Feb 2025 11:46:21 +0800 Subject: [PATCH 10/12] lift ModelFactoryProvider instance to TypeProvider instead of the static cache. --- .../src/OutputLibrary.cs | 2 +- .../src/PostProcessing/GeneratedCodeWorkspace.cs | 2 +- .../src/Providers/ModelFactoryProvider.cs | 6 +++--- .../src/TypeFactory.cs | 2 ++ .../ModelFactories/ModelFactoryProviderTests.cs | 15 ++++++++------- 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/OutputLibrary.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/OutputLibrary.cs index a87529e586d..26ca4d07cfb 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/OutputLibrary.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/OutputLibrary.cs @@ -81,7 +81,7 @@ .. BuildModelFactory() private static TypeProvider[] BuildModelFactory() { - var modelFactory = ModelFactoryProvider.FromInputLibrary(); + var modelFactory = CodeModelPlugin.Instance.TypeFactory.ModelFactory.Value; return modelFactory.Methods.Count > 0 ? [modelFactory] : []; } } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/PostProcessing/GeneratedCodeWorkspace.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/PostProcessing/GeneratedCodeWorkspace.cs index 414e6c28da8..117ac8446a9 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/PostProcessing/GeneratedCodeWorkspace.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/PostProcessing/GeneratedCodeWorkspace.cs @@ -211,7 +211,7 @@ internal static Project AddDirectory(Project project, string directory, Func public async Task PostProcessAsync() { - var modelFactory = ModelFactoryProvider.FromInputLibrary(); + var modelFactory = CodeModelPlugin.Instance.TypeFactory.ModelFactory.Value; var postProcessor = new PostProcessor( [.. CodeModelPlugin.Instance.TypeFactory.UnionTypes, .. CodeModelPlugin.Instance.TypesToKeep], modelFactoryFullName: $"{modelFactory.Type.Namespace}.{modelFactory.Name}"); diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs index de4149c66fc..0fa4b8c6a56 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs @@ -21,10 +21,10 @@ public class ModelFactoryProvider : TypeProvider private readonly IEnumerable _models; - private static ModelFactoryProvider? _modelFactoryProvider; - public static ModelFactoryProvider FromInputLibrary() => _modelFactoryProvider ??= new ModelFactoryProvider(CodeModelPlugin.Instance.InputLibrary.InputNamespace.Models); + //private static ModelFactoryProvider? _modelFactoryProvider; + //public static ModelFactoryProvider FromInputLibrary() => _modelFactoryProvider ??= new ModelFactoryProvider(CodeModelPlugin.Instance.InputLibrary.InputNamespace.Models); - private ModelFactoryProvider(IEnumerable models) + internal ModelFactoryProvider(IEnumerable models) { _models = models; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/TypeFactory.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/TypeFactory.cs index 35ce76bb8e1..72a8389513b 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/TypeFactory.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/TypeFactory.cs @@ -37,6 +37,8 @@ public class TypeFactory private HashSet? _unionTypes; internal HashSet UnionTypes => _unionTypes ??= []; + internal Lazy ModelFactory { get; } = new(() => new ModelFactoryProvider(CodeModelPlugin.Instance.InputLibrary.InputNamespace.Models)); + protected internal TypeFactory() { } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelFactories/ModelFactoryProviderTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelFactories/ModelFactoryProviderTests.cs index d2f8569d6b5..1340bfeb489 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelFactories/ModelFactoryProviderTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelFactories/ModelFactoryProviderTests.cs @@ -15,23 +15,24 @@ namespace Microsoft.TypeSpec.Generator.Tests.Providers.ModelFactories public class ModelFactoryProviderTests { private static readonly InputModelType[] ModelList = GetTestModels(); + private CodeModelPlugin _instance; public ModelFactoryProviderTests() { - MockHelpers.LoadMockPlugin(inputModelTypes: ModelList); + _instance = MockHelpers.LoadMockPlugin(inputModelTypes: ModelList).Object; } [Test] public void SkipInternalModels() { - var modelFactory = ModelFactoryProvider.FromInputLibrary(); + var modelFactory = _instance.TypeFactory.ModelFactory.Value; Assert.AreEqual(ModelList.Length - ModelList.Where(m => m.Access == "internal").Count(), modelFactory.Methods.Count); } [Test] public void ListParamShape() { - var modelFactory = ModelFactoryProvider.FromInputLibrary(); + var modelFactory = _instance.TypeFactory.ModelFactory.Value; var models = ModelList.Select(CodeModelPlugin.Instance.TypeFactory.CreateModel); foreach (var model in models) { @@ -54,7 +55,7 @@ public void ListParamShape() [Test] public void DictionaryParamShape() { - var modelFactory = ModelFactoryProvider.FromInputLibrary(); + var modelFactory = _instance.TypeFactory.ModelFactory.Value; var models = ModelList.Select(CodeModelPlugin.Instance.TypeFactory.CreateModel); foreach (var model in models) { @@ -77,7 +78,7 @@ public void DictionaryParamShape() [Test] public void DiscriminatorEnumParamShape() { - var modelFactory = ModelFactoryProvider.FromInputLibrary(); + var modelFactory = _instance.TypeFactory.ModelFactory.Value; var models = ModelList.Select(CodeModelPlugin.Instance.TypeFactory.CreateModel); foreach (var model in models) { @@ -99,7 +100,7 @@ public void DiscriminatorEnumParamShape() [Test] public void AdditionalPropertiesParamShape() { - var modelFactory = ModelFactoryProvider.FromInputLibrary(); + var modelFactory = _instance.TypeFactory.ModelFactory.Value; var models = ModelList.Select(CodeModelPlugin.Instance.TypeFactory.CreateModel); foreach (var model in models) { @@ -123,7 +124,7 @@ public void AdditionalPropertiesParamShape() [Test] public void ModelFactoryName() { - var modelFactory = ModelFactoryProvider.FromInputLibrary(); + var modelFactory = _instance.TypeFactory.ModelFactory.Value; Assert.AreEqual("SampleNamespaceModelFactory", modelFactory.Name); } From 2040566a230c589b3702be88b8dbef36a420569c Mon Sep 17 00:00:00 2001 From: Wei Hu Date: Wed, 12 Feb 2025 11:49:05 +0800 Subject: [PATCH 11/12] cleanup --- .../src/Providers/ModelFactoryProvider.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs index 0fa4b8c6a56..7908605d8d8 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs @@ -21,9 +21,6 @@ public class ModelFactoryProvider : TypeProvider private readonly IEnumerable _models; - //private static ModelFactoryProvider? _modelFactoryProvider; - //public static ModelFactoryProvider FromInputLibrary() => _modelFactoryProvider ??= new ModelFactoryProvider(CodeModelPlugin.Instance.InputLibrary.InputNamespace.Models); - internal ModelFactoryProvider(IEnumerable models) { _models = models; From f54b2f3701bd70f1414d2d470647ab3735b753e1 Mon Sep 17 00:00:00 2001 From: Wei Hu Date: Wed, 12 Feb 2025 13:56:24 +0800 Subject: [PATCH 12/12] move ModelFactoryProvider instance to OutputLibrary --- .../src/OutputLibrary.cs | 7 +++++-- .../src/PostProcessing/GeneratedCodeWorkspace.cs | 2 +- .../Microsoft.TypeSpec.Generator/src/TypeFactory.cs | 2 -- .../ModelFactories/ModelFactoryProviderTests.cs | 12 ++++++------ 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/OutputLibrary.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/OutputLibrary.cs index 26ca4d07cfb..13b27c7c858 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/OutputLibrary.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/OutputLibrary.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using System; using System.Collections.Generic; using System.Linq; using Microsoft.TypeSpec.Generator.Providers; @@ -16,6 +17,8 @@ public IReadOnlyList TypeProviders internal set => _typeProviders = value; } + internal Lazy ModelFactory { get; } = new(() => new ModelFactoryProvider(CodeModelPlugin.Instance.InputLibrary.InputNamespace.Models)); + private static TypeProvider[] BuildEnums() { var input = CodeModelPlugin.Instance.InputLibrary.InputNamespace; @@ -79,9 +82,9 @@ .. BuildModelFactory() ]; } - private static TypeProvider[] BuildModelFactory() + private TypeProvider[] BuildModelFactory() { - var modelFactory = CodeModelPlugin.Instance.TypeFactory.ModelFactory.Value; + var modelFactory = ModelFactory.Value; return modelFactory.Methods.Count > 0 ? [modelFactory] : []; } } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/PostProcessing/GeneratedCodeWorkspace.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/PostProcessing/GeneratedCodeWorkspace.cs index 117ac8446a9..9d7ecd53f1f 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/PostProcessing/GeneratedCodeWorkspace.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/PostProcessing/GeneratedCodeWorkspace.cs @@ -211,7 +211,7 @@ internal static Project AddDirectory(Project project, string directory, Func public async Task PostProcessAsync() { - var modelFactory = CodeModelPlugin.Instance.TypeFactory.ModelFactory.Value; + var modelFactory = CodeModelPlugin.Instance.OutputLibrary.ModelFactory.Value; var postProcessor = new PostProcessor( [.. CodeModelPlugin.Instance.TypeFactory.UnionTypes, .. CodeModelPlugin.Instance.TypesToKeep], modelFactoryFullName: $"{modelFactory.Type.Namespace}.{modelFactory.Name}"); diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/TypeFactory.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/TypeFactory.cs index 72a8389513b..35ce76bb8e1 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/TypeFactory.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/TypeFactory.cs @@ -37,8 +37,6 @@ public class TypeFactory private HashSet? _unionTypes; internal HashSet UnionTypes => _unionTypes ??= []; - internal Lazy ModelFactory { get; } = new(() => new ModelFactoryProvider(CodeModelPlugin.Instance.InputLibrary.InputNamespace.Models)); - protected internal TypeFactory() { } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelFactories/ModelFactoryProviderTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelFactories/ModelFactoryProviderTests.cs index 1340bfeb489..9155406a6f6 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelFactories/ModelFactoryProviderTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelFactories/ModelFactoryProviderTests.cs @@ -25,14 +25,14 @@ public ModelFactoryProviderTests() [Test] public void SkipInternalModels() { - var modelFactory = _instance.TypeFactory.ModelFactory.Value; + var modelFactory = _instance.OutputLibrary.ModelFactory.Value; Assert.AreEqual(ModelList.Length - ModelList.Where(m => m.Access == "internal").Count(), modelFactory.Methods.Count); } [Test] public void ListParamShape() { - var modelFactory = _instance.TypeFactory.ModelFactory.Value; + var modelFactory = _instance.OutputLibrary.ModelFactory.Value; var models = ModelList.Select(CodeModelPlugin.Instance.TypeFactory.CreateModel); foreach (var model in models) { @@ -55,7 +55,7 @@ public void ListParamShape() [Test] public void DictionaryParamShape() { - var modelFactory = _instance.TypeFactory.ModelFactory.Value; + var modelFactory = _instance.OutputLibrary.ModelFactory.Value; var models = ModelList.Select(CodeModelPlugin.Instance.TypeFactory.CreateModel); foreach (var model in models) { @@ -78,7 +78,7 @@ public void DictionaryParamShape() [Test] public void DiscriminatorEnumParamShape() { - var modelFactory = _instance.TypeFactory.ModelFactory.Value; + var modelFactory = _instance.OutputLibrary.ModelFactory.Value; var models = ModelList.Select(CodeModelPlugin.Instance.TypeFactory.CreateModel); foreach (var model in models) { @@ -100,7 +100,7 @@ public void DiscriminatorEnumParamShape() [Test] public void AdditionalPropertiesParamShape() { - var modelFactory = _instance.TypeFactory.ModelFactory.Value; + var modelFactory = _instance.OutputLibrary.ModelFactory.Value; var models = ModelList.Select(CodeModelPlugin.Instance.TypeFactory.CreateModel); foreach (var model in models) { @@ -124,7 +124,7 @@ public void AdditionalPropertiesParamShape() [Test] public void ModelFactoryName() { - var modelFactory = _instance.TypeFactory.ModelFactory.Value; + var modelFactory = _instance.OutputLibrary.ModelFactory.Value; Assert.AreEqual("SampleNamespaceModelFactory", modelFactory.Name); }