From ed82db32b4c079ab80bfb1c406dea0053b44e28c Mon Sep 17 00:00:00 2001 From: NKnusperer Date: Sun, 1 Sep 2024 01:33:51 +0200 Subject: [PATCH 1/8] Control generated class access modifier for C# - Add `--class-access-modifier` flag. --- CHANGELOG.md | 1 + .../Configuration/GenerationConfiguration.cs | 1 + src/Kiota.Builder/KiotaBuilder.cs | 2 +- src/Kiota.Builder/Lock/KiotaLock.cs | 6 ++++++ src/Kiota.Builder/Lock/KiotaLockComparer.cs | 2 ++ src/Kiota.Builder/Writers/CLI/CliWriter.cs | 4 ++-- src/Kiota.Builder/Writers/CSharp/CSharpWriter.cs | 4 ++-- .../Writers/CSharp/CodeClassDeclarationWriter.cs | 8 ++++++-- src/Kiota.Builder/Writers/LanguageWriter.cs | 6 +++--- src/kiota/Handlers/KiotaGenerateCommandHandler.cs | 6 ++++++ src/kiota/KiotaConfigurationExtensions.cs | 1 + src/kiota/KiotaHost.cs | 6 ++++++ .../Writers/CSharp/CSharpWriterTests.cs | 6 +++--- .../CSharp/CodeClassDeclarationWriterTests.cs | 15 ++++++++++++++- 14 files changed, 54 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b27641b28..819a17f5da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added the ability to export the CodeDom to a file showing the public APIs to be generated in a given language [#4627](https://github.com/microsoft/kiota/issues/4627) - Added composed type serialization in Typescript [2462](https://github.com/microsoft/kiota/issues/2462) - Use authentication information available in the source OpenAPI document when generating a plugin manifest. [#5070](https://github.com/microsoft/kiota/issues/5070) +- Control generated class access modifier for C# via `--class-access-modifier` flag. [#4788](https://github.com/microsoft/kiota/issues/4788) ### Changed diff --git a/src/Kiota.Builder/Configuration/GenerationConfiguration.cs b/src/Kiota.Builder/Configuration/GenerationConfiguration.cs index 6e81b63f23..64bc333ee3 100644 --- a/src/Kiota.Builder/Configuration/GenerationConfiguration.cs +++ b/src/Kiota.Builder/Configuration/GenerationConfiguration.cs @@ -38,6 +38,7 @@ public ConsumerOperation? Operation public string ApiManifestPath { get; set; } = "apimanifest.json"; public string OutputPath { get; set; } = "./output"; public string ClientClassName { get; set; } = "ApiClient"; + public string? ClientClassAccessModifier { get; set; } public string ClientNamespaceName { get; set; } = "ApiSdk"; public string NamespaceNameSeparator { get; set; } = "."; public bool ExportPublicApi diff --git a/src/Kiota.Builder/KiotaBuilder.cs b/src/Kiota.Builder/KiotaBuilder.cs index a9841f1fd9..7b1045d222 100644 --- a/src/Kiota.Builder/KiotaBuilder.cs +++ b/src/Kiota.Builder/KiotaBuilder.cs @@ -579,7 +579,7 @@ public async Task ApplyLanguageRefinementAsync(GenerationConfiguration config, C public async Task CreateLanguageSourceFilesAsync(GenerationLanguage language, CodeNamespace generatedCode, CancellationToken cancellationToken) { - var languageWriter = LanguageWriter.GetLanguageWriter(language, config.OutputPath, config.ClientNamespaceName, config.UsesBackingStore, config.ExcludeBackwardCompatible); + var languageWriter = LanguageWriter.GetLanguageWriter(language, config.OutputPath, config.ClientNamespaceName, config.ClientClassAccessModifier, config.UsesBackingStore, config.ExcludeBackwardCompatible); var stopwatch = new Stopwatch(); stopwatch.Start(); var codeRenderer = CodeRenderer.GetCodeRender(config); diff --git a/src/Kiota.Builder/Lock/KiotaLock.cs b/src/Kiota.Builder/Lock/KiotaLock.cs index a5d38c2fc4..42ea715212 100644 --- a/src/Kiota.Builder/Lock/KiotaLock.cs +++ b/src/Kiota.Builder/Lock/KiotaLock.cs @@ -31,6 +31,10 @@ public class KiotaLock /// public string ClientClassName { get; set; } = string.Empty; /// + /// The class access modifier to use for the client classes. + /// + public string? ClientClassAccessModifier { get; set; } + /// /// The main namespace for this client. /// public string ClientNamespaceName { get; set; } = string.Empty; @@ -102,6 +106,7 @@ public void UpdateGenerationConfigurationFromLock(GenerationConfiguration config { ArgumentNullException.ThrowIfNull(config); config.ClientClassName = ClientClassName; + config.ClientClassAccessModifier = ClientClassAccessModifier; config.ClientNamespaceName = ClientNamespaceName; if (Enum.TryParse(Language, out var parsedLanguage)) config.Language = parsedLanguage; @@ -132,6 +137,7 @@ public KiotaLock(GenerationConfiguration config) ArgumentNullException.ThrowIfNull(config); Language = config.Language.ToString(); ClientClassName = config.ClientClassName; + ClientClassAccessModifier = config.ClientClassAccessModifier; ClientNamespaceName = config.ClientNamespaceName; UsesBackingStore = config.UsesBackingStore; ExcludeBackwardCompatible = config.ExcludeBackwardCompatible; diff --git a/src/Kiota.Builder/Lock/KiotaLockComparer.cs b/src/Kiota.Builder/Lock/KiotaLockComparer.cs index 26f156f74a..b2f9c7333e 100644 --- a/src/Kiota.Builder/Lock/KiotaLockComparer.cs +++ b/src/Kiota.Builder/Lock/KiotaLockComparer.cs @@ -35,6 +35,7 @@ public bool Equals(KiotaLock? x, KiotaLock? y) && _stringComparer.Equals(x.ClientClassName, y.ClientClassName) && _stringComparer.Equals(x.ClientNamespaceName, y.ClientNamespaceName) && _stringComparer.Equals(x.Language, y.Language) + && _stringComparer.Equals(x.TypeAccessModifier, y.TypeAccessModifier) && _stringIEnumerableDeepComparer.Equals(x.DisabledValidationRules, y.DisabledValidationRules) && _stringIEnumerableDeepComparer.Equals(x.Serializers, y.Serializers) && _stringIEnumerableDeepComparer.Equals(x.Deserializers, y.Deserializers) @@ -56,6 +57,7 @@ public int GetHashCode([DisallowNull] KiotaLock obj) hash.Add(obj.ClientClassName, _stringComparer); hash.Add(obj.ClientNamespaceName, _stringComparer); hash.Add(obj.Language, _stringComparer); + hash.Add(obj.TypeAccessModifier, _stringComparer); hash.Add(obj.ExcludeBackwardCompatible); hash.Add(obj.UsesBackingStore); hash.Add(obj.IncludeAdditionalData); diff --git a/src/Kiota.Builder/Writers/CLI/CliWriter.cs b/src/Kiota.Builder/Writers/CLI/CliWriter.cs index ce03c5c07a..cb488e3aa6 100644 --- a/src/Kiota.Builder/Writers/CLI/CliWriter.cs +++ b/src/Kiota.Builder/Writers/CLI/CliWriter.cs @@ -3,10 +3,10 @@ namespace Kiota.Builder.Writers.Cli; class CliWriter : CSharpWriter { - public CliWriter(string rootPath, string clientNamespaceName) : base(rootPath, clientNamespaceName) + public CliWriter(string rootPath, string clientNamespaceName, string? clientClassAccessModifier) : base(rootPath, clientNamespaceName, clientClassAccessModifier) { var conventionService = new CSharpConventionService(); - AddOrReplaceCodeElementWriter(new CodeClassDeclarationWriter(conventionService)); + AddOrReplaceCodeElementWriter(new CodeClassDeclarationWriter(conventionService, clientClassAccessModifier)); AddOrReplaceCodeElementWriter(new CodeBlockEndWriter(conventionService)); AddOrReplaceCodeElementWriter(new CodeEnumWriter(conventionService)); AddOrReplaceCodeElementWriter(new CodeIndexerWriter(conventionService)); diff --git a/src/Kiota.Builder/Writers/CSharp/CSharpWriter.cs b/src/Kiota.Builder/Writers/CSharp/CSharpWriter.cs index 287b4db588..f963985d8e 100644 --- a/src/Kiota.Builder/Writers/CSharp/CSharpWriter.cs +++ b/src/Kiota.Builder/Writers/CSharp/CSharpWriter.cs @@ -3,11 +3,11 @@ namespace Kiota.Builder.Writers.CSharp; public class CSharpWriter : LanguageWriter { - public CSharpWriter(string rootPath, string clientNamespaceName) + public CSharpWriter(string rootPath, string clientNamespaceName, string? clientClassAccessModifier) { PathSegmenter = new CSharpPathSegmenter(rootPath, clientNamespaceName); var conventionService = new CSharpConventionService(); - AddOrReplaceCodeElementWriter(new CodeClassDeclarationWriter(conventionService)); + AddOrReplaceCodeElementWriter(new CodeClassDeclarationWriter(conventionService, clientClassAccessModifier)); AddOrReplaceCodeElementWriter(new CodeBlockEndWriter(conventionService)); AddOrReplaceCodeElementWriter(new CodeEnumWriter(conventionService)); AddOrReplaceCodeElementWriter(new CodeIndexerWriter(conventionService)); diff --git a/src/Kiota.Builder/Writers/CSharp/CodeClassDeclarationWriter.cs b/src/Kiota.Builder/Writers/CSharp/CodeClassDeclarationWriter.cs index f457430ec9..e7dbe68d0a 100644 --- a/src/Kiota.Builder/Writers/CSharp/CodeClassDeclarationWriter.cs +++ b/src/Kiota.Builder/Writers/CSharp/CodeClassDeclarationWriter.cs @@ -6,9 +6,13 @@ namespace Kiota.Builder.Writers.CSharp; public class CodeClassDeclarationWriter : BaseElementWriter { + private readonly string _clientClassAccessModifier; public static string AutoGenerationHeader => "// "; public static string GeneratedCodeAttribute { get; } = $"[global::System.CodeDom.Compiler.GeneratedCode(\"Kiota\", \"{Kiota.Generated.KiotaVersion.Current()}\")]"; - public CodeClassDeclarationWriter(CSharpConventionService conventionService) : base(conventionService) { } + public CodeClassDeclarationWriter(CSharpConventionService conventionService, string? clientClassAccessModifier) : base(conventionService) + { + _clientClassAccessModifier = string.IsNullOrWhiteSpace(clientClassAccessModifier) ? "public" : clientClassAccessModifier; + } public override void WriteCodeElement(ClassDeclaration codeElement, LanguageWriter writer) { ArgumentNullException.ThrowIfNull(codeElement); @@ -41,7 +45,7 @@ public override void WriteCodeElement(ClassDeclaration codeElement, LanguageWrit conventions.WriteDeprecationAttribute(parentClass, writer); writer.WriteLine(GeneratedCodeAttribute); if (!hasDescription) conventions.WritePragmaDisable(writer, CSharpConventionService.CS1591); - writer.WriteLine($"public partial class {codeElement.Name.ToFirstCharacterUpperCase()} {derivation}"); + writer.WriteLine($"{_clientClassAccessModifier} partial class {codeElement.Name.ToFirstCharacterUpperCase()} {derivation}"); if (!hasDescription) conventions.WritePragmaRestore(writer, CSharpConventionService.CS1591); writer.StartBlock(); } diff --git a/src/Kiota.Builder/Writers/LanguageWriter.cs b/src/Kiota.Builder/Writers/LanguageWriter.cs index 3a4a8886e0..82e4b8eeb1 100644 --- a/src/Kiota.Builder/Writers/LanguageWriter.cs +++ b/src/Kiota.Builder/Writers/LanguageWriter.cs @@ -179,18 +179,18 @@ protected void AddOrReplaceCodeElementWriter(ICodeElementWriter writer) wh Writers[typeof(T)] = writer; } private readonly Dictionary Writers = []; // we have to type as object because dotnet doesn't have type capture i.e eq for `? extends CodeElement` - public static LanguageWriter GetLanguageWriter(GenerationLanguage language, string outputPath, string clientNamespaceName, bool usesBackingStore = false, bool excludeBackwardCompatible = false) + public static LanguageWriter GetLanguageWriter(GenerationLanguage language, string outputPath, string clientNamespaceName, string? clientClassAccessModifier = null, bool usesBackingStore = false, bool excludeBackwardCompatible = false) { return language switch { - GenerationLanguage.CSharp => new CSharpWriter(outputPath, clientNamespaceName), + GenerationLanguage.CSharp => new CSharpWriter(outputPath, clientNamespaceName, clientClassAccessModifier), GenerationLanguage.Java => new JavaWriter(outputPath, clientNamespaceName), GenerationLanguage.TypeScript => new TypeScriptWriter(outputPath, clientNamespaceName), GenerationLanguage.Ruby => new RubyWriter(outputPath, clientNamespaceName), GenerationLanguage.PHP => new PhpWriter(outputPath, clientNamespaceName, usesBackingStore), GenerationLanguage.Python => new PythonWriter(outputPath, clientNamespaceName, usesBackingStore), GenerationLanguage.Go => new GoWriter(outputPath, clientNamespaceName, excludeBackwardCompatible), - GenerationLanguage.CLI => new CliWriter(outputPath, clientNamespaceName), + GenerationLanguage.CLI => new CliWriter(outputPath, clientNamespaceName, clientClassAccessModifier), GenerationLanguage.Swift => new SwiftWriter(outputPath, clientNamespaceName), _ => throw new InvalidEnumArgumentException($"{language} language currently not supported."), }; diff --git a/src/kiota/Handlers/KiotaGenerateCommandHandler.cs b/src/kiota/Handlers/KiotaGenerateCommandHandler.cs index a0442d81af..f83b065287 100644 --- a/src/kiota/Handlers/KiotaGenerateCommandHandler.cs +++ b/src/kiota/Handlers/KiotaGenerateCommandHandler.cs @@ -27,6 +27,10 @@ public required Option ClassOption { get; init; } + public required Option ClassAccessModifierOption + { + get; init; + } public required Option NamespaceOption { get; init; @@ -72,6 +76,7 @@ public override async Task InvokeAsync(InvocationContext context) bool disableSSLValidation = context.ParseResult.GetValueForOption(DisableSSLValidationOption); bool includeAdditionalData = context.ParseResult.GetValueForOption(AdditionalDataOption); string className = context.ParseResult.GetValueForOption(ClassOption) ?? string.Empty; + string? classAccessModifier = context.ParseResult.GetValueForOption(ClassAccessModifierOption); string namespaceName = context.ParseResult.GetValueForOption(NamespaceOption) ?? string.Empty; List serializer = context.ParseResult.GetValueForOption(SerializerOption) ?? []; List deserializer = context.ParseResult.GetValueForOption(DeserializerOption) ?? []; @@ -86,6 +91,7 @@ public override async Task InvokeAsync(InvocationContext context) AssignIfNotNullOrEmpty(manifest, (c, s) => c.ApiManifestPath = s); AssignIfNotNullOrEmpty(className, (c, s) => c.ClientClassName = s); AssignIfNotNullOrEmpty(namespaceName, (c, s) => c.ClientNamespaceName = s); + Configuration.Generation.ClientClassAccessModifier = classAccessModifier; Configuration.Generation.UsesBackingStore = backingStore; Configuration.Generation.ExcludeBackwardCompatible = excludeBackwardCompatible; Configuration.Generation.IncludeAdditionalData = includeAdditionalData; diff --git a/src/kiota/KiotaConfigurationExtensions.cs b/src/kiota/KiotaConfigurationExtensions.cs index a4e241847c..a4343cd0b1 100644 --- a/src/kiota/KiotaConfigurationExtensions.cs +++ b/src/kiota/KiotaConfigurationExtensions.cs @@ -54,6 +54,7 @@ public static void BindConfiguration(this KiotaConfiguration configObject, IConf configObject.Generation.OpenAPIFilePath = configuration[$"{nameof(configObject.Generation)}:{nameof(GenerationConfiguration.OpenAPIFilePath)}"] is string openApiFilePath && !string.IsNullOrEmpty(openApiFilePath) ? openApiFilePath : configObject.Generation.OpenAPIFilePath; configObject.Generation.OutputPath = configuration[$"{nameof(configObject.Generation)}:{nameof(GenerationConfiguration.OutputPath)}"] is string outputPath && !string.IsNullOrEmpty(outputPath) ? outputPath : configObject.Generation.OutputPath; configObject.Generation.ClientClassName = configuration[$"{nameof(configObject.Generation)}:{nameof(GenerationConfiguration.ClientClassName)}"] is string clientClassName && !string.IsNullOrEmpty(clientClassName) ? clientClassName : configObject.Generation.ClientClassName; + configObject.Generation.ClientClassAccessModifier = configuration[$"{nameof(configObject.Generation)}:{nameof(GenerationConfiguration.ClientClassAccessModifier)}"] is string clientClassAccessModifier && !string.IsNullOrEmpty(clientClassAccessModifier) ? clientClassAccessModifier : configObject.Generation.ClientClassAccessModifier; configObject.Generation.ClientNamespaceName = configuration[$"{nameof(configObject.Generation)}:{nameof(GenerationConfiguration.ClientNamespaceName)}"] is string clientNamespaceName && !string.IsNullOrEmpty(clientNamespaceName) ? clientNamespaceName : configObject.Generation.ClientNamespaceName; configObject.Generation.UsesBackingStore = bool.TryParse(configuration[$"{nameof(configObject.Generation)}:{nameof(GenerationConfiguration.UsesBackingStore)}"], out var usesBackingStore) && usesBackingStore; configObject.Generation.IncludeAdditionalData = bool.TryParse(configuration[$"{nameof(configObject.Generation)}:{nameof(GenerationConfiguration.IncludeAdditionalData)}"], out var includeAdditionalData) && includeAdditionalData; diff --git a/src/kiota/KiotaHost.cs b/src/kiota/KiotaHost.cs index 238406b020..67d52de17a 100644 --- a/src/kiota/KiotaHost.cs +++ b/src/kiota/KiotaHost.cs @@ -431,6 +431,10 @@ private static Command GetGenerateCommand() classOption.AddAlias("-c"); classOption.ArgumentHelpName = "name"; AddStringRegexValidator(classOption, classNameRegex(), "class name"); + + var classAccessModifierOption = new Option("--class-access-modifier", "The class access modifier to use for the client classes."); + classAccessModifierOption.AddAlias("-cam"); + classAccessModifierOption.ArgumentHelpName = "class accessibility"; var namespaceOption = GetNamespaceOption(defaultConfiguration.ClientNamespaceName); @@ -474,6 +478,7 @@ private static Command GetGenerateCommand() outputOption, languageOption, classOption, + classAccessModifierOption, namespaceOption, logLevelOption, backingStoreOption, @@ -496,6 +501,7 @@ private static Command GetGenerateCommand() OutputOption = outputOption, LanguageOption = languageOption, ClassOption = classOption, + ClassAccessModifierOption = classAccessModifierOption, NamespaceOption = namespaceOption, LogLevelOption = logLevelOption, BackingStoreOption = backingStoreOption, diff --git a/tests/Kiota.Builder.Tests/Writers/CSharp/CSharpWriterTests.cs b/tests/Kiota.Builder.Tests/Writers/CSharp/CSharpWriterTests.cs index 06dcbded3f..3350d95eb2 100644 --- a/tests/Kiota.Builder.Tests/Writers/CSharp/CSharpWriterTests.cs +++ b/tests/Kiota.Builder.Tests/Writers/CSharp/CSharpWriterTests.cs @@ -10,10 +10,10 @@ public class CSharpWriterTests [Fact] public void Instantiates() { - var writer = new CSharpWriter("./", "graph"); + var writer = new CSharpWriter("./", "graph", null); Assert.NotNull(writer); Assert.NotNull(writer.PathSegmenter); - Assert.Throws(() => new CSharpWriter(null, "graph")); - Assert.Throws(() => new CSharpWriter("./", null)); + Assert.Throws(() => new CSharpWriter(null, "graph", null)); + Assert.Throws(() => new CSharpWriter("./", null, null)); } } diff --git a/tests/Kiota.Builder.Tests/Writers/CSharp/CodeClassDeclarationWriterTests.cs b/tests/Kiota.Builder.Tests/Writers/CSharp/CodeClassDeclarationWriterTests.cs index 20d0b3df68..9768f17294 100644 --- a/tests/Kiota.Builder.Tests/Writers/CSharp/CodeClassDeclarationWriterTests.cs +++ b/tests/Kiota.Builder.Tests/Writers/CSharp/CodeClassDeclarationWriterTests.cs @@ -20,7 +20,7 @@ public sealed class CodeClassDeclarationWriterTests : IDisposable public CodeClassDeclarationWriterTests() { - codeElementWriter = new CodeClassDeclarationWriter(new CSharpConventionService()); + codeElementWriter = new CodeClassDeclarationWriter(new CSharpConventionService(), null); writer = LanguageWriter.GetLanguageWriter(GenerationLanguage.CSharp, DefaultPath, DefaultName); tw = new StringWriter(); writer.SetTextWriter(tw); @@ -53,6 +53,19 @@ public void WritesSimpleDeclaration() var result = tw.ToString(); Assert.Contains("public partial class", result); } + + [Theory] + [InlineData(null, "public")] + [InlineData("", "public")] + [InlineData(" ", "public")] + [InlineData("internal", "internal")] + public void WritesClassAccessModifier(string accessModifierSetting, string expectedAccessModifier) + { + var codeElementWriterWithAccessModifier = new CodeClassDeclarationWriter(new CSharpConventionService(), accessModifierSetting); + codeElementWriterWithAccessModifier.WriteCodeElement(parentClass.StartBlock, writer); + var result = tw.ToString(); + Assert.Contains($"{expectedAccessModifier} partial class", result); + } [Fact] public void WritesWarningDisableCs0618() From ca0dadb0824374d9797c938b33dd11d2b14ae732 Mon Sep 17 00:00:00 2001 From: NKnusperer Date: Tue, 3 Sep 2024 23:22:49 +0200 Subject: [PATCH 2/8] Review feedback - Rename `--class-access-modifier` to `--type-access-modifier`. - Use `AccessModifier` enum instead of string and extend to `Internal` value. - Add `Access` property to `CodeClass` and `CodeEnum`. - Use `CSharpRefiner` to set `Access` property from configuration. - Extend `CodeClassDeclarationWriter` and `CodeEnumWriter` to write actual type access modifier. --- CHANGELOG.md | 2 +- src/Kiota.Builder/CodeDOM/AccessModifier.cs | 1 + src/Kiota.Builder/CodeDOM/CodeClass.cs | 3 +++ src/Kiota.Builder/CodeDOM/CodeEnum.cs | 1 + .../Configuration/GenerationConfiguration.cs | 3 ++- src/Kiota.Builder/KiotaBuilder.cs | 2 +- src/Kiota.Builder/Lock/KiotaLock.cs | 12 +++++---- src/Kiota.Builder/Refiners/CSharpRefiner.cs | 16 ++++++++++++ src/Kiota.Builder/Writers/CLI/CliWriter.cs | 4 +-- .../Writers/CSharp/CSharpConventionService.cs | 1 + .../Writers/CSharp/CSharpWriter.cs | 4 +-- .../CSharp/CodeClassDeclarationWriter.cs | 8 ++---- .../Writers/CSharp/CodeEnumWriter.cs | 2 +- src/Kiota.Builder/Writers/LanguageWriter.cs | 6 ++--- .../Handlers/KiotaGenerateCommandHandler.cs | 7 ++--- src/kiota/KiotaConfigurationExtensions.cs | 3 ++- src/kiota/KiotaHost.cs | 18 ++++++++----- .../Writers/CSharp/CSharpWriterTests.cs | 6 ++--- .../CSharp/CodeClassDeclarationWriterTests.cs | 26 +++++++++---------- .../Writers/CSharp/CodeEnumWriterTests.cs | 14 ++++++++++ 20 files changed, 90 insertions(+), 49 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 819a17f5da..2b48222739 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,7 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added the ability to export the CodeDom to a file showing the public APIs to be generated in a given language [#4627](https://github.com/microsoft/kiota/issues/4627) - Added composed type serialization in Typescript [2462](https://github.com/microsoft/kiota/issues/2462) - Use authentication information available in the source OpenAPI document when generating a plugin manifest. [#5070](https://github.com/microsoft/kiota/issues/5070) -- Control generated class access modifier for C# via `--class-access-modifier` flag. [#4788](https://github.com/microsoft/kiota/issues/4788) +- Control generated type access modifier for C# via `--type-access-modifier` flag. [#4788](https://github.com/microsoft/kiota/issues/4788) ### Changed diff --git a/src/Kiota.Builder/CodeDOM/AccessModifier.cs b/src/Kiota.Builder/CodeDOM/AccessModifier.cs index b440fbca54..1ff57953d8 100644 --- a/src/Kiota.Builder/CodeDOM/AccessModifier.cs +++ b/src/Kiota.Builder/CodeDOM/AccessModifier.cs @@ -1,6 +1,7 @@ namespace Kiota.Builder.CodeDOM; public enum AccessModifier { + Internal = 3, Public = 2, Protected = 1, Private = 0 diff --git a/src/Kiota.Builder/CodeDOM/CodeClass.cs b/src/Kiota.Builder/CodeDOM/CodeClass.cs index 1e5be4b934..0ffab89e86 100644 --- a/src/Kiota.Builder/CodeDOM/CodeClass.cs +++ b/src/Kiota.Builder/CodeDOM/CodeClass.cs @@ -33,6 +33,9 @@ public enum CodeClassKind public class CodeClass : ProprietableBlock, ITypeDefinition, IDiscriminatorInformationHolder, IDeprecableElement { private readonly ConcurrentDictionary PropertiesByWireName = new(StringComparer.OrdinalIgnoreCase); + + public AccessModifier Access { get; set; } = AccessModifier.Public; + public bool IsErrorDefinition { get; set; diff --git a/src/Kiota.Builder/CodeDOM/CodeEnum.cs b/src/Kiota.Builder/CodeDOM/CodeEnum.cs index 3a46dd0a40..9a115c78de 100644 --- a/src/Kiota.Builder/CodeDOM/CodeEnum.cs +++ b/src/Kiota.Builder/CodeDOM/CodeEnum.cs @@ -8,6 +8,7 @@ namespace Kiota.Builder.CodeDOM; public class CodeEnum : CodeBlock, IDocumentedElement, ITypeDefinition, IDeprecableElement { #pragma warning restore CA2227 + public AccessModifier Access { get; set; } = AccessModifier.Public; public bool Flags { get; set; diff --git a/src/Kiota.Builder/Configuration/GenerationConfiguration.cs b/src/Kiota.Builder/Configuration/GenerationConfiguration.cs index 64bc333ee3..352dd98b65 100644 --- a/src/Kiota.Builder/Configuration/GenerationConfiguration.cs +++ b/src/Kiota.Builder/Configuration/GenerationConfiguration.cs @@ -3,6 +3,7 @@ using System.IO; using System.Linq; using System.Text.Json.Nodes; +using Kiota.Builder.CodeDOM; using Kiota.Builder.Extensions; using Kiota.Builder.Lock; using Microsoft.OpenApi.ApiManifest; @@ -38,7 +39,7 @@ public ConsumerOperation? Operation public string ApiManifestPath { get; set; } = "apimanifest.json"; public string OutputPath { get; set; } = "./output"; public string ClientClassName { get; set; } = "ApiClient"; - public string? ClientClassAccessModifier { get; set; } + public AccessModifier TypeAccessModifier { get; set; } = AccessModifier.Public; public string ClientNamespaceName { get; set; } = "ApiSdk"; public string NamespaceNameSeparator { get; set; } = "."; public bool ExportPublicApi diff --git a/src/Kiota.Builder/KiotaBuilder.cs b/src/Kiota.Builder/KiotaBuilder.cs index 7b1045d222..a9841f1fd9 100644 --- a/src/Kiota.Builder/KiotaBuilder.cs +++ b/src/Kiota.Builder/KiotaBuilder.cs @@ -579,7 +579,7 @@ public async Task ApplyLanguageRefinementAsync(GenerationConfiguration config, C public async Task CreateLanguageSourceFilesAsync(GenerationLanguage language, CodeNamespace generatedCode, CancellationToken cancellationToken) { - var languageWriter = LanguageWriter.GetLanguageWriter(language, config.OutputPath, config.ClientNamespaceName, config.ClientClassAccessModifier, config.UsesBackingStore, config.ExcludeBackwardCompatible); + var languageWriter = LanguageWriter.GetLanguageWriter(language, config.OutputPath, config.ClientNamespaceName, config.UsesBackingStore, config.ExcludeBackwardCompatible); var stopwatch = new Stopwatch(); stopwatch.Start(); var codeRenderer = CodeRenderer.GetCodeRender(config); diff --git a/src/Kiota.Builder/Lock/KiotaLock.cs b/src/Kiota.Builder/Lock/KiotaLock.cs index 42ea715212..ca1e213c30 100644 --- a/src/Kiota.Builder/Lock/KiotaLock.cs +++ b/src/Kiota.Builder/Lock/KiotaLock.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Kiota.Builder.CodeDOM; using Kiota.Builder.Configuration; namespace Kiota.Builder.Lock; @@ -31,9 +32,9 @@ public class KiotaLock /// public string ClientClassName { get; set; } = string.Empty; /// - /// The class access modifier to use for the client classes. + /// The type access modifier to use for the client types. /// - public string? ClientClassAccessModifier { get; set; } + public string TypeAccessModifier { get; set; } = string.Empty; /// /// The main namespace for this client. /// @@ -106,10 +107,11 @@ public void UpdateGenerationConfigurationFromLock(GenerationConfiguration config { ArgumentNullException.ThrowIfNull(config); config.ClientClassName = ClientClassName; - config.ClientClassAccessModifier = ClientClassAccessModifier; - config.ClientNamespaceName = ClientNamespaceName; if (Enum.TryParse(Language, out var parsedLanguage)) config.Language = parsedLanguage; + config.ClientNamespaceName = ClientNamespaceName; + if (Enum.TryParse(TypeAccessModifier, out var parsedAccessModifier)) + config.TypeAccessModifier = parsedAccessModifier; config.UsesBackingStore = UsesBackingStore; config.ExcludeBackwardCompatible = ExcludeBackwardCompatible; config.IncludeAdditionalData = IncludeAdditionalData; @@ -137,7 +139,7 @@ public KiotaLock(GenerationConfiguration config) ArgumentNullException.ThrowIfNull(config); Language = config.Language.ToString(); ClientClassName = config.ClientClassName; - ClientClassAccessModifier = config.ClientClassAccessModifier; + TypeAccessModifier = config.TypeAccessModifier.ToString(); ClientNamespaceName = config.ClientNamespaceName; UsesBackingStore = config.UsesBackingStore; ExcludeBackwardCompatible = config.ExcludeBackwardCompatible; diff --git a/src/Kiota.Builder/Refiners/CSharpRefiner.cs b/src/Kiota.Builder/Refiners/CSharpRefiner.cs index 31c12c6bbe..556d4fd80f 100644 --- a/src/Kiota.Builder/Refiners/CSharpRefiner.cs +++ b/src/Kiota.Builder/Refiners/CSharpRefiner.cs @@ -110,6 +110,7 @@ public override Task RefineAsync(CodeNamespace generatedCode, CancellationToken generatedCode, "IParseNode" ); + SetTypeAccessModifiers(generatedCode); }, cancellationToken); } protected static void DisambiguatePropertiesWithClassNames(CodeElement currentElement) @@ -260,4 +261,19 @@ protected static void CorrectIndexerType(CodeIndexer currentIndexer) }) }, }; + + private void SetTypeAccessModifiers(CodeElement currentElement) + { + switch (currentElement) + { + case CodeClass currentClass: + currentClass.Access = _configuration.TypeAccessModifier; + break; + case CodeEnum currentEnum: + currentEnum.Access = _configuration.TypeAccessModifier; + break; + } + + CrawlTree(currentElement, SetTypeAccessModifiers); + } } diff --git a/src/Kiota.Builder/Writers/CLI/CliWriter.cs b/src/Kiota.Builder/Writers/CLI/CliWriter.cs index cb488e3aa6..ce03c5c07a 100644 --- a/src/Kiota.Builder/Writers/CLI/CliWriter.cs +++ b/src/Kiota.Builder/Writers/CLI/CliWriter.cs @@ -3,10 +3,10 @@ namespace Kiota.Builder.Writers.Cli; class CliWriter : CSharpWriter { - public CliWriter(string rootPath, string clientNamespaceName, string? clientClassAccessModifier) : base(rootPath, clientNamespaceName, clientClassAccessModifier) + public CliWriter(string rootPath, string clientNamespaceName) : base(rootPath, clientNamespaceName) { var conventionService = new CSharpConventionService(); - AddOrReplaceCodeElementWriter(new CodeClassDeclarationWriter(conventionService, clientClassAccessModifier)); + AddOrReplaceCodeElementWriter(new CodeClassDeclarationWriter(conventionService)); AddOrReplaceCodeElementWriter(new CodeBlockEndWriter(conventionService)); AddOrReplaceCodeElementWriter(new CodeEnumWriter(conventionService)); AddOrReplaceCodeElementWriter(new CodeIndexerWriter(conventionService)); diff --git a/src/Kiota.Builder/Writers/CSharp/CSharpConventionService.cs b/src/Kiota.Builder/Writers/CSharp/CSharpConventionService.cs index 40baff16f0..46a6fda2f0 100644 --- a/src/Kiota.Builder/Writers/CSharp/CSharpConventionService.cs +++ b/src/Kiota.Builder/Writers/CSharp/CSharpConventionService.cs @@ -96,6 +96,7 @@ public override string GetAccessModifier(AccessModifier access) { return access switch { + AccessModifier.Internal => "internal", AccessModifier.Public => "public", AccessModifier.Protected => "protected", _ => "private", diff --git a/src/Kiota.Builder/Writers/CSharp/CSharpWriter.cs b/src/Kiota.Builder/Writers/CSharp/CSharpWriter.cs index f963985d8e..287b4db588 100644 --- a/src/Kiota.Builder/Writers/CSharp/CSharpWriter.cs +++ b/src/Kiota.Builder/Writers/CSharp/CSharpWriter.cs @@ -3,11 +3,11 @@ namespace Kiota.Builder.Writers.CSharp; public class CSharpWriter : LanguageWriter { - public CSharpWriter(string rootPath, string clientNamespaceName, string? clientClassAccessModifier) + public CSharpWriter(string rootPath, string clientNamespaceName) { PathSegmenter = new CSharpPathSegmenter(rootPath, clientNamespaceName); var conventionService = new CSharpConventionService(); - AddOrReplaceCodeElementWriter(new CodeClassDeclarationWriter(conventionService, clientClassAccessModifier)); + AddOrReplaceCodeElementWriter(new CodeClassDeclarationWriter(conventionService)); AddOrReplaceCodeElementWriter(new CodeBlockEndWriter(conventionService)); AddOrReplaceCodeElementWriter(new CodeEnumWriter(conventionService)); AddOrReplaceCodeElementWriter(new CodeIndexerWriter(conventionService)); diff --git a/src/Kiota.Builder/Writers/CSharp/CodeClassDeclarationWriter.cs b/src/Kiota.Builder/Writers/CSharp/CodeClassDeclarationWriter.cs index e7dbe68d0a..c7f3bdb808 100644 --- a/src/Kiota.Builder/Writers/CSharp/CodeClassDeclarationWriter.cs +++ b/src/Kiota.Builder/Writers/CSharp/CodeClassDeclarationWriter.cs @@ -6,13 +6,9 @@ namespace Kiota.Builder.Writers.CSharp; public class CodeClassDeclarationWriter : BaseElementWriter { - private readonly string _clientClassAccessModifier; public static string AutoGenerationHeader => "// "; public static string GeneratedCodeAttribute { get; } = $"[global::System.CodeDom.Compiler.GeneratedCode(\"Kiota\", \"{Kiota.Generated.KiotaVersion.Current()}\")]"; - public CodeClassDeclarationWriter(CSharpConventionService conventionService, string? clientClassAccessModifier) : base(conventionService) - { - _clientClassAccessModifier = string.IsNullOrWhiteSpace(clientClassAccessModifier) ? "public" : clientClassAccessModifier; - } + public CodeClassDeclarationWriter(CSharpConventionService conventionService) : base(conventionService) { } public override void WriteCodeElement(ClassDeclaration codeElement, LanguageWriter writer) { ArgumentNullException.ThrowIfNull(codeElement); @@ -45,7 +41,7 @@ public override void WriteCodeElement(ClassDeclaration codeElement, LanguageWrit conventions.WriteDeprecationAttribute(parentClass, writer); writer.WriteLine(GeneratedCodeAttribute); if (!hasDescription) conventions.WritePragmaDisable(writer, CSharpConventionService.CS1591); - writer.WriteLine($"{_clientClassAccessModifier} partial class {codeElement.Name.ToFirstCharacterUpperCase()} {derivation}"); + writer.WriteLine($"{conventions.GetAccessModifier(parentClass.Access)} partial class {codeElement.Name.ToFirstCharacterUpperCase()} {derivation}"); if (!hasDescription) conventions.WritePragmaRestore(writer, CSharpConventionService.CS1591); writer.StartBlock(); } diff --git a/src/Kiota.Builder/Writers/CSharp/CodeEnumWriter.cs b/src/Kiota.Builder/Writers/CSharp/CodeEnumWriter.cs index 588bb7db87..5b43dd3c44 100644 --- a/src/Kiota.Builder/Writers/CSharp/CodeEnumWriter.cs +++ b/src/Kiota.Builder/Writers/CSharp/CodeEnumWriter.cs @@ -37,7 +37,7 @@ public override void WriteCodeElement(CodeEnum codeElement, LanguageWriter write writer.WriteLine("[Flags]"); conventions.WriteDeprecationAttribute(codeElement, writer); if (!hasDescription) writer.WriteLine("#pragma warning disable CS1591"); - writer.WriteLine($"public enum {codeElement.Name.ToFirstCharacterUpperCase()}"); + writer.WriteLine($"{conventions.GetAccessModifier(codeElement.Access)} enum {codeElement.Name.ToFirstCharacterUpperCase()}"); if (!hasDescription) writer.WriteLine("#pragma warning restore CS1591"); writer.StartBlock(); var idx = 0; diff --git a/src/Kiota.Builder/Writers/LanguageWriter.cs b/src/Kiota.Builder/Writers/LanguageWriter.cs index 82e4b8eeb1..3a4a8886e0 100644 --- a/src/Kiota.Builder/Writers/LanguageWriter.cs +++ b/src/Kiota.Builder/Writers/LanguageWriter.cs @@ -179,18 +179,18 @@ protected void AddOrReplaceCodeElementWriter(ICodeElementWriter writer) wh Writers[typeof(T)] = writer; } private readonly Dictionary Writers = []; // we have to type as object because dotnet doesn't have type capture i.e eq for `? extends CodeElement` - public static LanguageWriter GetLanguageWriter(GenerationLanguage language, string outputPath, string clientNamespaceName, string? clientClassAccessModifier = null, bool usesBackingStore = false, bool excludeBackwardCompatible = false) + public static LanguageWriter GetLanguageWriter(GenerationLanguage language, string outputPath, string clientNamespaceName, bool usesBackingStore = false, bool excludeBackwardCompatible = false) { return language switch { - GenerationLanguage.CSharp => new CSharpWriter(outputPath, clientNamespaceName, clientClassAccessModifier), + GenerationLanguage.CSharp => new CSharpWriter(outputPath, clientNamespaceName), GenerationLanguage.Java => new JavaWriter(outputPath, clientNamespaceName), GenerationLanguage.TypeScript => new TypeScriptWriter(outputPath, clientNamespaceName), GenerationLanguage.Ruby => new RubyWriter(outputPath, clientNamespaceName), GenerationLanguage.PHP => new PhpWriter(outputPath, clientNamespaceName, usesBackingStore), GenerationLanguage.Python => new PythonWriter(outputPath, clientNamespaceName, usesBackingStore), GenerationLanguage.Go => new GoWriter(outputPath, clientNamespaceName, excludeBackwardCompatible), - GenerationLanguage.CLI => new CliWriter(outputPath, clientNamespaceName, clientClassAccessModifier), + GenerationLanguage.CLI => new CliWriter(outputPath, clientNamespaceName), GenerationLanguage.Swift => new SwiftWriter(outputPath, clientNamespaceName), _ => throw new InvalidEnumArgumentException($"{language} language currently not supported."), }; diff --git a/src/kiota/Handlers/KiotaGenerateCommandHandler.cs b/src/kiota/Handlers/KiotaGenerateCommandHandler.cs index f83b065287..d44c035fdf 100644 --- a/src/kiota/Handlers/KiotaGenerateCommandHandler.cs +++ b/src/kiota/Handlers/KiotaGenerateCommandHandler.cs @@ -3,6 +3,7 @@ using System.Text.Json; using Kiota.Builder; +using Kiota.Builder.CodeDOM; using Kiota.Builder.Extensions; using Microsoft.Extensions.Logging; @@ -27,7 +28,7 @@ public required Option ClassOption { get; init; } - public required Option ClassAccessModifierOption + public required Option TypeAccessModifierOption { get; init; } @@ -76,7 +77,7 @@ public override async Task InvokeAsync(InvocationContext context) bool disableSSLValidation = context.ParseResult.GetValueForOption(DisableSSLValidationOption); bool includeAdditionalData = context.ParseResult.GetValueForOption(AdditionalDataOption); string className = context.ParseResult.GetValueForOption(ClassOption) ?? string.Empty; - string? classAccessModifier = context.ParseResult.GetValueForOption(ClassAccessModifierOption); + AccessModifier typeAccessModifier = context.ParseResult.GetValueForOption(TypeAccessModifierOption); string namespaceName = context.ParseResult.GetValueForOption(NamespaceOption) ?? string.Empty; List serializer = context.ParseResult.GetValueForOption(SerializerOption) ?? []; List deserializer = context.ParseResult.GetValueForOption(DeserializerOption) ?? []; @@ -91,7 +92,7 @@ public override async Task InvokeAsync(InvocationContext context) AssignIfNotNullOrEmpty(manifest, (c, s) => c.ApiManifestPath = s); AssignIfNotNullOrEmpty(className, (c, s) => c.ClientClassName = s); AssignIfNotNullOrEmpty(namespaceName, (c, s) => c.ClientNamespaceName = s); - Configuration.Generation.ClientClassAccessModifier = classAccessModifier; + Configuration.Generation.TypeAccessModifier = typeAccessModifier; Configuration.Generation.UsesBackingStore = backingStore; Configuration.Generation.ExcludeBackwardCompatible = excludeBackwardCompatible; Configuration.Generation.IncludeAdditionalData = includeAdditionalData; diff --git a/src/kiota/KiotaConfigurationExtensions.cs b/src/kiota/KiotaConfigurationExtensions.cs index a4343cd0b1..c54572b1f6 100644 --- a/src/kiota/KiotaConfigurationExtensions.cs +++ b/src/kiota/KiotaConfigurationExtensions.cs @@ -1,4 +1,5 @@ using Kiota.Builder; +using Kiota.Builder.CodeDOM; using Kiota.Builder.Configuration; using Microsoft.Extensions.Configuration; @@ -54,7 +55,7 @@ public static void BindConfiguration(this KiotaConfiguration configObject, IConf configObject.Generation.OpenAPIFilePath = configuration[$"{nameof(configObject.Generation)}:{nameof(GenerationConfiguration.OpenAPIFilePath)}"] is string openApiFilePath && !string.IsNullOrEmpty(openApiFilePath) ? openApiFilePath : configObject.Generation.OpenAPIFilePath; configObject.Generation.OutputPath = configuration[$"{nameof(configObject.Generation)}:{nameof(GenerationConfiguration.OutputPath)}"] is string outputPath && !string.IsNullOrEmpty(outputPath) ? outputPath : configObject.Generation.OutputPath; configObject.Generation.ClientClassName = configuration[$"{nameof(configObject.Generation)}:{nameof(GenerationConfiguration.ClientClassName)}"] is string clientClassName && !string.IsNullOrEmpty(clientClassName) ? clientClassName : configObject.Generation.ClientClassName; - configObject.Generation.ClientClassAccessModifier = configuration[$"{nameof(configObject.Generation)}:{nameof(GenerationConfiguration.ClientClassAccessModifier)}"] is string clientClassAccessModifier && !string.IsNullOrEmpty(clientClassAccessModifier) ? clientClassAccessModifier : configObject.Generation.ClientClassAccessModifier; + configObject.Generation.TypeAccessModifier = Enum.TryParse(configuration[$"{nameof(configObject.Generation)}:{nameof(GenerationConfiguration.TypeAccessModifier)}"], true, out var accessModifier) ? accessModifier : AccessModifier.Public; configObject.Generation.ClientNamespaceName = configuration[$"{nameof(configObject.Generation)}:{nameof(GenerationConfiguration.ClientNamespaceName)}"] is string clientNamespaceName && !string.IsNullOrEmpty(clientNamespaceName) ? clientNamespaceName : configObject.Generation.ClientNamespaceName; configObject.Generation.UsesBackingStore = bool.TryParse(configuration[$"{nameof(configObject.Generation)}:{nameof(GenerationConfiguration.UsesBackingStore)}"], out var usesBackingStore) && usesBackingStore; configObject.Generation.IncludeAdditionalData = bool.TryParse(configuration[$"{nameof(configObject.Generation)}:{nameof(GenerationConfiguration.IncludeAdditionalData)}"], out var includeAdditionalData) && includeAdditionalData; diff --git a/src/kiota/KiotaHost.cs b/src/kiota/KiotaHost.cs index 67d52de17a..6df8daf978 100644 --- a/src/kiota/KiotaHost.cs +++ b/src/kiota/KiotaHost.cs @@ -4,6 +4,7 @@ using kiota.Handlers; using kiota.Rpc; using Kiota.Builder; +using Kiota.Builder.CodeDOM; using Kiota.Builder.Configuration; using Kiota.Builder.Validation; using Microsoft.Extensions.Logging; @@ -357,6 +358,13 @@ internal static Option GetLanguageOption() AddEnumValidator(languageOption, "language"); return languageOption; } + internal static Option GetTypeAccessModifierOption() + { + var accessOption = new Option("--type-access-modifier", "The type access modifier to use for the client types."); + accessOption.AddAlias("--tam"); + AddEnumValidator(accessOption, "type-access-modifier"); + return accessOption; + } internal static Option GetOptionalLanguageOption() { var languageOption = new Option("--language", "The target language for the generated code files."); @@ -431,10 +439,8 @@ private static Command GetGenerateCommand() classOption.AddAlias("-c"); classOption.ArgumentHelpName = "name"; AddStringRegexValidator(classOption, classNameRegex(), "class name"); - - var classAccessModifierOption = new Option("--class-access-modifier", "The class access modifier to use for the client classes."); - classAccessModifierOption.AddAlias("-cam"); - classAccessModifierOption.ArgumentHelpName = "class accessibility"; + + var typeAccessModifierOption = GetTypeAccessModifierOption(); var namespaceOption = GetNamespaceOption(defaultConfiguration.ClientNamespaceName); @@ -478,7 +484,7 @@ private static Command GetGenerateCommand() outputOption, languageOption, classOption, - classAccessModifierOption, + typeAccessModifierOption, namespaceOption, logLevelOption, backingStoreOption, @@ -501,7 +507,7 @@ private static Command GetGenerateCommand() OutputOption = outputOption, LanguageOption = languageOption, ClassOption = classOption, - ClassAccessModifierOption = classAccessModifierOption, + TypeAccessModifierOption = typeAccessModifierOption, NamespaceOption = namespaceOption, LogLevelOption = logLevelOption, BackingStoreOption = backingStoreOption, diff --git a/tests/Kiota.Builder.Tests/Writers/CSharp/CSharpWriterTests.cs b/tests/Kiota.Builder.Tests/Writers/CSharp/CSharpWriterTests.cs index 3350d95eb2..06dcbded3f 100644 --- a/tests/Kiota.Builder.Tests/Writers/CSharp/CSharpWriterTests.cs +++ b/tests/Kiota.Builder.Tests/Writers/CSharp/CSharpWriterTests.cs @@ -10,10 +10,10 @@ public class CSharpWriterTests [Fact] public void Instantiates() { - var writer = new CSharpWriter("./", "graph", null); + var writer = new CSharpWriter("./", "graph"); Assert.NotNull(writer); Assert.NotNull(writer.PathSegmenter); - Assert.Throws(() => new CSharpWriter(null, "graph", null)); - Assert.Throws(() => new CSharpWriter("./", null, null)); + Assert.Throws(() => new CSharpWriter(null, "graph")); + Assert.Throws(() => new CSharpWriter("./", null)); } } diff --git a/tests/Kiota.Builder.Tests/Writers/CSharp/CodeClassDeclarationWriterTests.cs b/tests/Kiota.Builder.Tests/Writers/CSharp/CodeClassDeclarationWriterTests.cs index 9768f17294..ba6ead893c 100644 --- a/tests/Kiota.Builder.Tests/Writers/CSharp/CodeClassDeclarationWriterTests.cs +++ b/tests/Kiota.Builder.Tests/Writers/CSharp/CodeClassDeclarationWriterTests.cs @@ -20,7 +20,7 @@ public sealed class CodeClassDeclarationWriterTests : IDisposable public CodeClassDeclarationWriterTests() { - codeElementWriter = new CodeClassDeclarationWriter(new CSharpConventionService(), null); + codeElementWriter = new CodeClassDeclarationWriter(new CSharpConventionService()); writer = LanguageWriter.GetLanguageWriter(GenerationLanguage.CSharp, DefaultPath, DefaultName); tw = new StringWriter(); writer.SetTextWriter(tw); @@ -53,19 +53,6 @@ public void WritesSimpleDeclaration() var result = tw.ToString(); Assert.Contains("public partial class", result); } - - [Theory] - [InlineData(null, "public")] - [InlineData("", "public")] - [InlineData(" ", "public")] - [InlineData("internal", "internal")] - public void WritesClassAccessModifier(string accessModifierSetting, string expectedAccessModifier) - { - var codeElementWriterWithAccessModifier = new CodeClassDeclarationWriter(new CSharpConventionService(), accessModifierSetting); - codeElementWriterWithAccessModifier.WriteCodeElement(parentClass.StartBlock, writer); - var result = tw.ToString(); - Assert.Contains($"{expectedAccessModifier} partial class", result); - } [Fact] public void WritesWarningDisableCs0618() @@ -136,4 +123,15 @@ public void WritesGeneratedCodeAttribute() var result = tw.ToString(); Assert.Matches(CodeEnumWriterTests.GeneratedCodePattern, result); } + + [Theory] + [InlineData(AccessModifier.Public)] + [InlineData(AccessModifier.Internal)] + public void WritesAccessModifier(AccessModifier accessModifier) + { + parentClass.Access = accessModifier; + codeElementWriter.WriteCodeElement(parentClass.StartBlock, writer); + var result = tw.ToString(); + Assert.Contains($"{accessModifier.ToString().ToLower()} partial class", result); + } } diff --git a/tests/Kiota.Builder.Tests/Writers/CSharp/CodeEnumWriterTests.cs b/tests/Kiota.Builder.Tests/Writers/CSharp/CodeEnumWriterTests.cs index bbbd6fd2f5..2c1b2dfe87 100644 --- a/tests/Kiota.Builder.Tests/Writers/CSharp/CodeEnumWriterTests.cs +++ b/tests/Kiota.Builder.Tests/Writers/CSharp/CodeEnumWriterTests.cs @@ -139,4 +139,18 @@ public void WritesGeneratedCodeAttribute() var result = tw.ToString(); Assert.Matches(GeneratedCodePattern, result); } + + [Theory] + [InlineData(AccessModifier.Public)] + [InlineData(AccessModifier.Internal)] + public void WritesAccessModifier(AccessModifier accessModifier) + { + currentEnum.Access = accessModifier; + currentEnum.AddOption(Option); + writer.Write(currentEnum); + var result = tw.ToString(); + Assert.Contains($"{accessModifier.ToString().ToLower()} enum", result); + AssertExtensions.CurlyBracesAreClosed(result, 1); + Assert.Contains(Option.Name, result); + } } From 1fb471a0bd9e8c4d4bf4a03f6a64765cbb8fee77 Mon Sep 17 00:00:00 2001 From: NKnusperer Date: Sun, 8 Sep 2024 11:43:20 +0200 Subject: [PATCH 3/8] Review feedback 2 - Add `TypeAccessModifierOption` to client handlers. - Add `TypeAccessModifier` to workspace `ApiClientConfiguration` and `ApiClientConfigurationComparer`. - Add default value of `Public` for stringified `TypeAccessModifier` properties. - Add test case for `CSharpRefiner`. - Implement `IAccessibleElement` for `CodeClass` and `CodeEnum`. --- src/Kiota.Builder/CodeDOM/CodeClass.cs | 2 +- src/Kiota.Builder/CodeDOM/CodeEnum.cs | 2 +- src/Kiota.Builder/Lock/KiotaLock.cs | 2 +- src/Kiota.Builder/Refiners/CSharpRefiner.cs | 8 +++----- .../ApiClientConfiguration.cs | 9 +++++++++ .../ApiClientConfigurationComparer.cs | 2 ++ src/kiota/Handlers/Client/AddHandler.cs | 7 +++++++ src/kiota/Handlers/Client/EditHandler.cs | 8 ++++++++ src/kiota/KiotaClientCommands.cs | 6 ++++++ src/kiota/KiotaHost.cs | 17 ++++++++++++----- .../Refiners/CSharpLanguageRefinerTests.cs | 18 ++++++++++++++++++ 11 files changed, 68 insertions(+), 13 deletions(-) diff --git a/src/Kiota.Builder/CodeDOM/CodeClass.cs b/src/Kiota.Builder/CodeDOM/CodeClass.cs index 0ffab89e86..4b08c14a7e 100644 --- a/src/Kiota.Builder/CodeDOM/CodeClass.cs +++ b/src/Kiota.Builder/CodeDOM/CodeClass.cs @@ -30,7 +30,7 @@ public enum CodeClassKind /// /// CodeClass represents an instance of a Class to be generated in source code /// -public class CodeClass : ProprietableBlock, ITypeDefinition, IDiscriminatorInformationHolder, IDeprecableElement +public class CodeClass : ProprietableBlock, ITypeDefinition, IDiscriminatorInformationHolder, IDeprecableElement, IAccessibleElement { private readonly ConcurrentDictionary PropertiesByWireName = new(StringComparer.OrdinalIgnoreCase); diff --git a/src/Kiota.Builder/CodeDOM/CodeEnum.cs b/src/Kiota.Builder/CodeDOM/CodeEnum.cs index 9a115c78de..c4c48550e5 100644 --- a/src/Kiota.Builder/CodeDOM/CodeEnum.cs +++ b/src/Kiota.Builder/CodeDOM/CodeEnum.cs @@ -5,7 +5,7 @@ namespace Kiota.Builder.CodeDOM; #pragma warning disable CA1711 -public class CodeEnum : CodeBlock, IDocumentedElement, ITypeDefinition, IDeprecableElement +public class CodeEnum : CodeBlock, IDocumentedElement, ITypeDefinition, IDeprecableElement, IAccessibleElement { #pragma warning restore CA2227 public AccessModifier Access { get; set; } = AccessModifier.Public; diff --git a/src/Kiota.Builder/Lock/KiotaLock.cs b/src/Kiota.Builder/Lock/KiotaLock.cs index ca1e213c30..671def487b 100644 --- a/src/Kiota.Builder/Lock/KiotaLock.cs +++ b/src/Kiota.Builder/Lock/KiotaLock.cs @@ -34,7 +34,7 @@ public class KiotaLock /// /// The type access modifier to use for the client types. /// - public string TypeAccessModifier { get; set; } = string.Empty; + public string TypeAccessModifier { get; set; } = "Public"; /// /// The main namespace for this client. /// diff --git a/src/Kiota.Builder/Refiners/CSharpRefiner.cs b/src/Kiota.Builder/Refiners/CSharpRefiner.cs index 556d4fd80f..aabdd38b53 100644 --- a/src/Kiota.Builder/Refiners/CSharpRefiner.cs +++ b/src/Kiota.Builder/Refiners/CSharpRefiner.cs @@ -266,11 +266,9 @@ private void SetTypeAccessModifiers(CodeElement currentElement) { switch (currentElement) { - case CodeClass currentClass: - currentClass.Access = _configuration.TypeAccessModifier; - break; - case CodeEnum currentEnum: - currentEnum.Access = _configuration.TypeAccessModifier; + case CodeClass: + case CodeEnum: + ((IAccessibleElement)currentElement).Access = _configuration.TypeAccessModifier; break; } diff --git a/src/Kiota.Builder/WorkspaceManagement/ApiClientConfiguration.cs b/src/Kiota.Builder/WorkspaceManagement/ApiClientConfiguration.cs index a8441571fd..05fe7ed810 100644 --- a/src/Kiota.Builder/WorkspaceManagement/ApiClientConfiguration.cs +++ b/src/Kiota.Builder/WorkspaceManagement/ApiClientConfiguration.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using Kiota.Builder.CodeDOM; using Kiota.Builder.Configuration; using Microsoft.OpenApi.ApiManifest; @@ -15,6 +16,10 @@ public class ApiClientConfiguration : BaseApiConsumerConfiguration, ICloneable /// public string Language { get; set; } = string.Empty; /// + /// The type access modifier to use for the client types. + /// + public string TypeAccessModifier { get; set; } = "Public"; + /// /// The structured mime types used for this client. /// #pragma warning disable CA1002 @@ -64,6 +69,7 @@ public ApiClientConfiguration(GenerationConfiguration config) : base(config) { ArgumentNullException.ThrowIfNull(config); Language = config.Language.ToString(); + TypeAccessModifier = config.TypeAccessModifier.ToString(); ClientNamespaceName = config.ClientNamespaceName; UsesBackingStore = config.UsesBackingStore; ExcludeBackwardCompatible = config.ExcludeBackwardCompatible; @@ -84,6 +90,8 @@ public void UpdateGenerationConfigurationFromApiClientConfiguration(GenerationCo config.ClientNamespaceName = ClientNamespaceName; if (Enum.TryParse(Language, out var parsedLanguage)) config.Language = parsedLanguage; + if (Enum.TryParse(TypeAccessModifier, out var parsedTypeAccessModifier)) + config.TypeAccessModifier = parsedTypeAccessModifier; config.UsesBackingStore = UsesBackingStore; config.ExcludeBackwardCompatible = ExcludeBackwardCompatible; config.IncludeAdditionalData = IncludeAdditionalData; @@ -97,6 +105,7 @@ public object Clone() var result = new ApiClientConfiguration { Language = Language, + TypeAccessModifier = TypeAccessModifier, StructuredMimeTypes = [.. StructuredMimeTypes], ClientNamespaceName = ClientNamespaceName, UsesBackingStore = UsesBackingStore, diff --git a/src/Kiota.Builder/WorkspaceManagement/ApiClientConfigurationComparer.cs b/src/Kiota.Builder/WorkspaceManagement/ApiClientConfigurationComparer.cs index d13b5621cb..29e7a901dc 100644 --- a/src/Kiota.Builder/WorkspaceManagement/ApiClientConfigurationComparer.cs +++ b/src/Kiota.Builder/WorkspaceManagement/ApiClientConfigurationComparer.cs @@ -28,6 +28,7 @@ public override bool Equals(ApiClientConfiguration? x, ApiClientConfiguration? y if (x.IncludeAdditionalData != y.IncludeAdditionalData) return false; if (!_stringComparer.Equals(x.ClientNamespaceName, y.ClientNamespaceName)) return false; if (!_stringComparer.Equals(x.Language, y.Language)) return false; + if (!_stringComparer.Equals(x.TypeAccessModifier, y.TypeAccessModifier)) return false; // slow deep comparison return _stringIEnumerableDeepComparer.Equals(x.DisabledValidationRules, y.DisabledValidationRules) @@ -42,6 +43,7 @@ public override int GetHashCode([DisallowNull] ApiClientConfiguration obj) hash.Add(obj.DisabledValidationRules, _stringIEnumerableDeepComparer); // _stringIEnumerableDeepComparer orders hash.Add(obj.ClientNamespaceName, _stringComparer); hash.Add(obj.Language, _stringComparer); + hash.Add(obj.TypeAccessModifier, _stringComparer); hash.Add(obj.ExcludeBackwardCompatible); hash.Add(obj.UsesBackingStore); hash.Add(obj.IncludeAdditionalData); diff --git a/src/kiota/Handlers/Client/AddHandler.cs b/src/kiota/Handlers/Client/AddHandler.cs index b7eb188e97..beec8f8058 100644 --- a/src/kiota/Handlers/Client/AddHandler.cs +++ b/src/kiota/Handlers/Client/AddHandler.cs @@ -2,6 +2,7 @@ using System.CommandLine.Invocation; using System.Text.Json; using Kiota.Builder; +using Kiota.Builder.CodeDOM; using Kiota.Builder.Configuration; using Kiota.Builder.Extensions; using Kiota.Builder.WorkspaceManagement; @@ -27,6 +28,10 @@ public required Option LanguageOption { get; init; } + public required Option TypeAccessModifierOption + { + get; init; + } public required Option DescriptionOption { get; init; @@ -69,6 +74,7 @@ public override async Task InvokeAsync(InvocationContext context) { string output = context.ParseResult.GetValueForOption(OutputOption) ?? string.Empty; GenerationLanguage language = context.ParseResult.GetValueForOption(LanguageOption); + AccessModifier typeAccessModifier = context.ParseResult.GetValueForOption(TypeAccessModifierOption); string openapi = context.ParseResult.GetValueForOption(DescriptionOption) ?? string.Empty; bool backingStore = context.ParseResult.GetValueForOption(BackingStoreOption); bool excludeBackwardCompatible = context.ParseResult.GetValueForOption(ExcludeBackwardCompatibleOption); @@ -90,6 +96,7 @@ public override async Task InvokeAsync(InvocationContext context) Configuration.Generation.IncludeAdditionalData = includeAdditionalData; Configuration.Generation.Language = language; WarnUsingPreviewLanguage(language); + Configuration.Generation.TypeAccessModifier = typeAccessModifier; Configuration.Generation.SkipGeneration = skipGeneration; Configuration.Generation.Operation = ConsumerOperation.Add; if (includePatterns.Count != 0) diff --git a/src/kiota/Handlers/Client/EditHandler.cs b/src/kiota/Handlers/Client/EditHandler.cs index ae28990879..5c2bee3dfb 100644 --- a/src/kiota/Handlers/Client/EditHandler.cs +++ b/src/kiota/Handlers/Client/EditHandler.cs @@ -2,6 +2,7 @@ using System.CommandLine.Invocation; using System.Text.Json; using Kiota.Builder; +using Kiota.Builder.CodeDOM; using Kiota.Builder.Configuration; using Kiota.Builder.Extensions; using Kiota.Builder.WorkspaceManagement; @@ -27,6 +28,10 @@ public required Option LanguageOption { get; init; } + public required Option TypeAccessModifierOption + { + get; init; + } public required Option DescriptionOption { get; init; @@ -69,6 +74,7 @@ public override async Task InvokeAsync(InvocationContext context) { string output = context.ParseResult.GetValueForOption(OutputOption) ?? string.Empty; GenerationLanguage? language = context.ParseResult.GetValueForOption(LanguageOption); + AccessModifier? typeAccessModifier = context.ParseResult.GetValueForOption(TypeAccessModifierOption); string openapi = context.ParseResult.GetValueForOption(DescriptionOption) ?? string.Empty; bool? backingStore = context.ParseResult.GetValueForOption(BackingStoreOption); bool? excludeBackwardCompatible = context.ParseResult.GetValueForOption(ExcludeBackwardCompatibleOption); @@ -109,6 +115,8 @@ public override async Task InvokeAsync(InvocationContext context) clientConfiguration.UpdateGenerationConfigurationFromApiClientConfiguration(Configuration.Generation, className); if (language.HasValue) Configuration.Generation.Language = language.Value; + if (typeAccessModifier.HasValue) + Configuration.Generation.TypeAccessModifier = typeAccessModifier.Value; if (backingStore.HasValue) Configuration.Generation.UsesBackingStore = backingStore.Value; if (excludeBackwardCompatible.HasValue) diff --git a/src/kiota/KiotaClientCommands.cs b/src/kiota/KiotaClientCommands.cs index df7bced23a..cd912c3b90 100644 --- a/src/kiota/KiotaClientCommands.cs +++ b/src/kiota/KiotaClientCommands.cs @@ -33,6 +33,7 @@ public static Command GetAddCommand() { var defaultConfiguration = new GenerationConfiguration(); var languageOption = KiotaHost.GetLanguageOption(); + var typeAccessModifierOption = KiotaHost.GetTypeAccessModifierOption(); var outputOption = KiotaHost.GetOutputPathOption(defaultConfiguration.OutputPath); var descriptionOption = KiotaHost.GetDescriptionOption(defaultConfiguration.OpenAPIFilePath, true); var namespaceOption = KiotaHost.GetNamespaceOption(defaultConfiguration.ClientNamespaceName); @@ -50,6 +51,7 @@ public static Command GetAddCommand() descriptionOption, outputOption, languageOption, + typeAccessModifierOption, clientNameOption, namespaceOption, logLevelOption, @@ -67,6 +69,7 @@ public static Command GetAddCommand() DescriptionOption = descriptionOption, OutputOption = outputOption, LanguageOption = languageOption, + TypeAccessModifierOption = typeAccessModifierOption, ClassOption = clientNameOption, NamespaceOption = namespaceOption, LogLevelOption = logLevelOption, @@ -104,6 +107,7 @@ public static Command GetRemoveCommand() public static Command GetEditCommand() { var languageOption = KiotaHost.GetOptionalLanguageOption(); + var typeAccessModifierOption = KiotaHost.GetOptionalTypeAccessModifierOption(); var outputOption = KiotaHost.GetOutputPathOption(string.Empty); var descriptionOption = KiotaHost.GetDescriptionOption(string.Empty); var namespaceOption = KiotaHost.GetNamespaceOption(string.Empty); @@ -121,6 +125,7 @@ public static Command GetEditCommand() descriptionOption, outputOption, languageOption, + typeAccessModifierOption, clientNameOption, namespaceOption, logLevelOption, @@ -138,6 +143,7 @@ public static Command GetEditCommand() DescriptionOption = descriptionOption, OutputOption = outputOption, LanguageOption = languageOption, + TypeAccessModifierOption = typeAccessModifierOption, ClassOption = clientNameOption, NamespaceOption = namespaceOption, LogLevelOption = logLevelOption, diff --git a/src/kiota/KiotaHost.cs b/src/kiota/KiotaHost.cs index 6df8daf978..700901f471 100644 --- a/src/kiota/KiotaHost.cs +++ b/src/kiota/KiotaHost.cs @@ -358,6 +358,13 @@ internal static Option GetLanguageOption() AddEnumValidator(languageOption, "language"); return languageOption; } + internal static Option GetOptionalLanguageOption() + { + var languageOption = new Option("--language", "The target language for the generated code files."); + languageOption.AddAlias("-l"); + AddEnumValidator(languageOption, "language"); + return languageOption; + } internal static Option GetTypeAccessModifierOption() { var accessOption = new Option("--type-access-modifier", "The type access modifier to use for the client types."); @@ -365,12 +372,12 @@ internal static Option GetTypeAccessModifierOption() AddEnumValidator(accessOption, "type-access-modifier"); return accessOption; } - internal static Option GetOptionalLanguageOption() + internal static Option GetOptionalTypeAccessModifierOption() { - var languageOption = new Option("--language", "The target language for the generated code files."); - languageOption.AddAlias("-l"); - AddEnumValidator(languageOption, "language"); - return languageOption; + var accessOption = new Option("--type-access-modifier", "The type access modifier to use for the client types."); + accessOption.AddAlias("--tam"); + AddEnumValidator(accessOption, "type-access-modifier"); + return accessOption; } internal static Option GetNamespaceOption(string defaultNamespaceName) { diff --git a/tests/Kiota.Builder.Tests/Refiners/CSharpLanguageRefinerTests.cs b/tests/Kiota.Builder.Tests/Refiners/CSharpLanguageRefinerTests.cs index df29b9e80b..2f344d0bf1 100644 --- a/tests/Kiota.Builder.Tests/Refiners/CSharpLanguageRefinerTests.cs +++ b/tests/Kiota.Builder.Tests/Refiners/CSharpLanguageRefinerTests.cs @@ -910,5 +910,23 @@ public async Task AddsUsingForUntypedNodeAsync() Assert.Equal("Microsoft.Kiota.Abstractions.Serialization", nodeUsing[0].Declaration.Name); } + [Theory] + [InlineData(AccessModifier.Public)] + [InlineData(AccessModifier.Internal)] + public async Task SetTypeAccessModifierAsync(AccessModifier accessModifier) + { + var codeClass = root.AddClass(new CodeClass + { + Name = "Class1", + Kind = CodeClassKind.Model + }).First(); + var codeEnum = root.AddEnum(new CodeEnum + { + Name = "Enum1", + }).First(); + await ILanguageRefiner.RefineAsync(new GenerationConfiguration { Language = GenerationLanguage.CSharp, TypeAccessModifier = accessModifier}, root); + Assert.Equal(codeClass.Access, accessModifier); + Assert.Equal(codeEnum.Access, accessModifier); + } #endregion } From e6ec1b6fc84bea9e1a9c717ed33014a4d08a4a5d Mon Sep 17 00:00:00 2001 From: NKnusperer Date: Mon, 9 Sep 2024 21:34:22 +0200 Subject: [PATCH 4/8] Review feedback 3 - Use parenthesized pattern matching for type checks. --- src/Kiota.Builder/Refiners/CSharpRefiner.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Kiota.Builder/Refiners/CSharpRefiner.cs b/src/Kiota.Builder/Refiners/CSharpRefiner.cs index aabdd38b53..c432dee00e 100644 --- a/src/Kiota.Builder/Refiners/CSharpRefiner.cs +++ b/src/Kiota.Builder/Refiners/CSharpRefiner.cs @@ -264,12 +264,9 @@ protected static void CorrectIndexerType(CodeIndexer currentIndexer) private void SetTypeAccessModifiers(CodeElement currentElement) { - switch (currentElement) + if (currentElement is IAccessibleElement accessibleElement and (CodeEnum or CodeClass)) { - case CodeClass: - case CodeEnum: - ((IAccessibleElement)currentElement).Access = _configuration.TypeAccessModifier; - break; + accessibleElement.Access = _configuration.TypeAccessModifier; } CrawlTree(currentElement, SetTypeAccessModifiers); From 307258a8ec634733d9436e87dd03c26600a6bf87 Mon Sep 17 00:00:00 2001 From: NKnusperer Date: Thu, 12 Sep 2024 22:03:32 +0200 Subject: [PATCH 5/8] Move changelog to unreleased section --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b48222739..730cd41fd5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added +- Control generated type access modifier for C# via `--type-access-modifier` flag. [#4788](https://github.com/microsoft/kiota/issues/4788) ### Changed @@ -30,7 +31,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added the ability to export the CodeDom to a file showing the public APIs to be generated in a given language [#4627](https://github.com/microsoft/kiota/issues/4627) - Added composed type serialization in Typescript [2462](https://github.com/microsoft/kiota/issues/2462) - Use authentication information available in the source OpenAPI document when generating a plugin manifest. [#5070](https://github.com/microsoft/kiota/issues/5070) -- Control generated type access modifier for C# via `--type-access-modifier` flag. [#4788](https://github.com/microsoft/kiota/issues/4788) ### Changed From 79de4eb986191b0f2acc5071ab3869576ea0d1ed Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Fri, 13 Sep 2024 13:30:48 -0400 Subject: [PATCH 6/8] chore: runs dotnet format --- src/Kiota.Builder/CodeDOM/CodeClass.cs | 2 +- .../Kiota.Builder.Tests/Refiners/CSharpLanguageRefinerTests.cs | 2 +- .../Writers/CSharp/CodeClassDeclarationWriterTests.cs | 2 +- tests/Kiota.Builder.Tests/Writers/CSharp/CodeEnumWriterTests.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Kiota.Builder/CodeDOM/CodeClass.cs b/src/Kiota.Builder/CodeDOM/CodeClass.cs index 4b08c14a7e..8ac263668e 100644 --- a/src/Kiota.Builder/CodeDOM/CodeClass.cs +++ b/src/Kiota.Builder/CodeDOM/CodeClass.cs @@ -33,7 +33,7 @@ public enum CodeClassKind public class CodeClass : ProprietableBlock, ITypeDefinition, IDiscriminatorInformationHolder, IDeprecableElement, IAccessibleElement { private readonly ConcurrentDictionary PropertiesByWireName = new(StringComparer.OrdinalIgnoreCase); - + public AccessModifier Access { get; set; } = AccessModifier.Public; public bool IsErrorDefinition diff --git a/tests/Kiota.Builder.Tests/Refiners/CSharpLanguageRefinerTests.cs b/tests/Kiota.Builder.Tests/Refiners/CSharpLanguageRefinerTests.cs index 2f344d0bf1..73fb546e0b 100644 --- a/tests/Kiota.Builder.Tests/Refiners/CSharpLanguageRefinerTests.cs +++ b/tests/Kiota.Builder.Tests/Refiners/CSharpLanguageRefinerTests.cs @@ -924,7 +924,7 @@ public async Task SetTypeAccessModifierAsync(AccessModifier accessModifier) { Name = "Enum1", }).First(); - await ILanguageRefiner.RefineAsync(new GenerationConfiguration { Language = GenerationLanguage.CSharp, TypeAccessModifier = accessModifier}, root); + await ILanguageRefiner.RefineAsync(new GenerationConfiguration { Language = GenerationLanguage.CSharp, TypeAccessModifier = accessModifier }, root); Assert.Equal(codeClass.Access, accessModifier); Assert.Equal(codeEnum.Access, accessModifier); } diff --git a/tests/Kiota.Builder.Tests/Writers/CSharp/CodeClassDeclarationWriterTests.cs b/tests/Kiota.Builder.Tests/Writers/CSharp/CodeClassDeclarationWriterTests.cs index ba6ead893c..836c5221e8 100644 --- a/tests/Kiota.Builder.Tests/Writers/CSharp/CodeClassDeclarationWriterTests.cs +++ b/tests/Kiota.Builder.Tests/Writers/CSharp/CodeClassDeclarationWriterTests.cs @@ -123,7 +123,7 @@ public void WritesGeneratedCodeAttribute() var result = tw.ToString(); Assert.Matches(CodeEnumWriterTests.GeneratedCodePattern, result); } - + [Theory] [InlineData(AccessModifier.Public)] [InlineData(AccessModifier.Internal)] diff --git a/tests/Kiota.Builder.Tests/Writers/CSharp/CodeEnumWriterTests.cs b/tests/Kiota.Builder.Tests/Writers/CSharp/CodeEnumWriterTests.cs index 2c1b2dfe87..0a76a2e617 100644 --- a/tests/Kiota.Builder.Tests/Writers/CSharp/CodeEnumWriterTests.cs +++ b/tests/Kiota.Builder.Tests/Writers/CSharp/CodeEnumWriterTests.cs @@ -139,7 +139,7 @@ public void WritesGeneratedCodeAttribute() var result = tw.ToString(); Assert.Matches(GeneratedCodePattern, result); } - + [Theory] [InlineData(AccessModifier.Public)] [InlineData(AccessModifier.Internal)] From c6cbfe76e773469919330a8ee5ad81490d4c5116 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Fri, 13 Sep 2024 13:37:54 -0400 Subject: [PATCH 7/8] fix: failing hashcode test --- .../WorkspaceManagement/ApiClientConfigurationComparerTests.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Kiota.Builder.Tests/WorkspaceManagement/ApiClientConfigurationComparerTests.cs b/tests/Kiota.Builder.Tests/WorkspaceManagement/ApiClientConfigurationComparerTests.cs index f967f0b54b..161466ccc6 100644 --- a/tests/Kiota.Builder.Tests/WorkspaceManagement/ApiClientConfigurationComparerTests.cs +++ b/tests/Kiota.Builder.Tests/WorkspaceManagement/ApiClientConfigurationComparerTests.cs @@ -25,10 +25,11 @@ public void GetsHashCode() var stringComparer = StringComparer.OrdinalIgnoreCase; hash.Add(string.Empty, stringComparer); hash.Add(string.Empty, stringComparer); + hash.Add("public", stringComparer); hash.Add(false); hash.Add(true); hash.Add(false); - hash.Add(new List(), iEnumComparer); + hash.Add([], iEnumComparer); var hash2 = new HashCode(); hash2.Add(string.Empty, stringComparer); hash2.Add(string.Empty, stringComparer); From d0ebaa14c0d1431ec73e69ed04c2bc767eb9a83d Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Fri, 13 Sep 2024 13:58:58 -0400 Subject: [PATCH 8/8] fix: missing default value for add/generate command access modifier Signed-off-by: Vincent Biret --- src/kiota/KiotaHost.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/kiota/KiotaHost.cs b/src/kiota/KiotaHost.cs index 700901f471..a604cf5602 100644 --- a/src/kiota/KiotaHost.cs +++ b/src/kiota/KiotaHost.cs @@ -369,6 +369,7 @@ internal static Option GetTypeAccessModifierOption() { var accessOption = new Option("--type-access-modifier", "The type access modifier to use for the client types."); accessOption.AddAlias("--tam"); + accessOption.SetDefaultValue(AccessModifier.Public); AddEnumValidator(accessOption, "type-access-modifier"); return accessOption; }