From ffef21580b34dc0f9b47c5f171f7c395d9a326b5 Mon Sep 17 00:00:00 2001 From: Wei Hu Date: Wed, 12 Feb 2025 15:07:48 +0800 Subject: [PATCH] Expose public setter of namespace (#5928) After the tsp namespace feature implementation in https://github.com/microsoft/typespec/pull/5443, the namespace of model, enum and modelFactory have been changed from previous `XXX.Models` to `XXX`. For Azure plugin, we would like the namespace for model and enum to be `XXX.Models`. - Expose public setter of namespace, use visitor to update namespace of TypeProvider in Azure plugin. https://github.com/Azure/azure-sdk-for-net/pull/48197/files#diff-a6219e0492ffcf33fd4bb03be26f1e6bc04a84ee1e2723b4d58d5adbcdb031ef - Expose provider types to let sub-plugin identify. - Remove duplicated instance of ModelFactoryProvider - Remove Namespace property from CSharp --- .../ExtensibleEnumSerializationProvider.cs | 2 +- .../Providers/FixedEnumSerializationProvider.cs | 2 +- .../src/Providers/RestClientProvider.cs | 2 +- .../src/Configuration.cs | 6 ------ .../src/OutputLibrary.cs | 7 +++++-- .../src/PostProcessing/GeneratedCodeWorkspace.cs | 4 ++-- .../src/Primitives/CSharpType.cs | 2 +- .../src/Providers/CanonicalTypeProvider.cs | 2 +- .../src/Providers/EnumProvider.cs | 2 +- .../src/Providers/ModelFactoryProvider.cs | 6 ++---- .../src/Providers/TypeProvider.cs | 3 --- .../test/Providers/CanonicalTypeProviderTests.cs | 2 +- .../ModelFactories/ModelFactoryProviderTests.cs | 15 ++++++++------- 13 files changed, 24 insertions(+), 31 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; 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/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. /// 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..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 = ModelFactoryProvider.FromInputLibrary(); + 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 5250deed1da..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,10 +211,10 @@ internal static Project AddDirectory(Project project, string directory, Func public async Task PostProcessAsync() { - var modelFactory = ModelFactoryProvider.FromInputLibrary(); + var modelFactory = CodeModelPlugin.Instance.OutputLibrary.ModelFactory.Value; 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/Primitives/CSharpType.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/CSharpType.cs index d77d9b129d1..264a1ce2f36 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/CSharpType.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/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.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/EnumProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/EnumProvider.cs index e1bcc3cdf2d..70df3d311a2 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/EnumProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/EnumProvider.cs @@ -9,7 +9,7 @@ namespace Microsoft.TypeSpec.Generator.Providers { - internal abstract class EnumProvider : TypeProvider + public abstract class EnumProvider : TypeProvider { private readonly InputEnumType _inputType; 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 63ff88ec0dd..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 @@ -14,16 +14,14 @@ namespace Microsoft.TypeSpec.Generator.Providers { - internal class ModelFactoryProvider : TypeProvider + public class ModelFactoryProvider : TypeProvider { private const string ModelFactorySuffix = "ModelFactory"; private const string AdditionalBinaryDataParameterName = "additionalBinaryDataProperties"; private readonly IEnumerable _models; - public static ModelFactoryProvider FromInputLibrary() => 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/Providers/TypeProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs index 0d781a2cf1e..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,9 +90,6 @@ private IReadOnlyList BuildAllCustomFields() private string? _name; - public string Namespace => _namespace ??= BuildNamespace(); - 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] 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..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 @@ -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.OutputLibrary.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.OutputLibrary.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.OutputLibrary.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.OutputLibrary.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.OutputLibrary.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.OutputLibrary.ModelFactory.Value; Assert.AreEqual("SampleNamespaceModelFactory", modelFactory.Name); }