diff --git a/src/Common/ArgumentBuilder.cs b/src/Common/ArgumentBuilder.cs new file mode 100644 index 0000000000..6aa7453862 --- /dev/null +++ b/src/Common/ArgumentBuilder.cs @@ -0,0 +1,29 @@ + +using System; +using System.CommandLine; +using System.Reflection; + +internal static class ArgumentBuilder +{ + private static readonly ConstructorInfo _ctor; + + static ArgumentBuilder() + { + _ctor = typeof(Argument).GetConstructor(new[] { typeof(string), typeof(string) }); + } + + public static Argument CreateArgument(Type valueType, string name = "value") + { + var argumentType = typeof(Argument<>).MakeGenericType(valueType); + +#if NET6_0_OR_GREATER + var ctor = (ConstructorInfo)argumentType.GetMemberWithSameMetadataDefinitionAs(_ctor); +#else + var ctor = argumentType.GetConstructor(new[] { typeof(string), typeof(string) }); +#endif + + var option = (Argument)ctor.Invoke(new object[] { name, null }); + + return option; + } +} \ No newline at end of file diff --git a/src/Common/OptionBuilder.cs b/src/Common/OptionBuilder.cs new file mode 100644 index 0000000000..aafc6df100 --- /dev/null +++ b/src/Common/OptionBuilder.cs @@ -0,0 +1,31 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Reflection; + +namespace System.CommandLine.Utility; + +internal static class OptionBuilder +{ + private static readonly ConstructorInfo _ctor; + + static OptionBuilder() + { + _ctor = typeof(Option).GetConstructor(new[] { typeof(string), typeof(string) }); + } + + public static Option CreateOption(string name, Type valueType) + { + var optionType = typeof(Option<>).MakeGenericType(valueType); + +#if NET6_0_OR_GREATER + var ctor = (ConstructorInfo)optionType.GetMemberWithSameMetadataDefinitionAs(_ctor); +#else + var ctor = optionType.GetConstructor(new[] { typeof(string), typeof(string) }); +#endif + + var option = (Option)ctor.Invoke(new object[] { name, null }); + + return option; + } +} \ No newline at end of file diff --git a/src/System.CommandLine.ApiCompatibility.Tests/ApiCompatibilityApprovalTests.System_CommandLine_api_is_not_changed.approved.txt b/src/System.CommandLine.ApiCompatibility.Tests/ApiCompatibilityApprovalTests.System_CommandLine_api_is_not_changed.approved.txt index 7cd496d848..32365a95ab 100644 --- a/src/System.CommandLine.ApiCompatibility.Tests/ApiCompatibilityApprovalTests.System_CommandLine_api_is_not_changed.approved.txt +++ b/src/System.CommandLine.ApiCompatibility.Tests/ApiCompatibilityApprovalTests.System_CommandLine_api_is_not_changed.approved.txt @@ -1,12 +1,10 @@ System.CommandLine - public class Argument : Symbol, System.CommandLine.Binding.IValueDescriptor, System.CommandLine.Completions.ICompletionSource - .ctor() - .ctor(System.String name = null, System.String description = null) + public abstract class Argument : Symbol, System.CommandLine.Binding.IValueDescriptor, System.CommandLine.Completions.ICompletionSource public ArgumentArity Arity { get; set; } public CompletionSourceList Completions { get; } public System.Boolean HasDefaultValue { get; } public System.String HelpName { get; set; } - public System.Type ValueType { get; set; } + public System.Type ValueType { get; } public System.Void AddValidator(System.CommandLine.Parsing.ValidateSymbolResult validate) public System.Collections.Generic.IEnumerable GetCompletions(System.CommandLine.Completions.CompletionContext context) public System.Object GetDefaultValue() @@ -21,7 +19,7 @@ .ctor(Func getDefaultValue) .ctor(System.String name, ParseArgument parse, System.Boolean isDefault = False, System.String description = null) .ctor(ParseArgument parse, System.Boolean isDefault = False) - public System.Type ValueType { get; set; } + public System.Type ValueType { get; } public struct ArgumentArity : System.ValueType, System.IEquatable public static ArgumentArity ExactlyOne { get; } public static ArgumentArity OneOrMore { get; } @@ -181,9 +179,7 @@ public System.String UnrecognizedCommandOrArgument(System.String arg) public System.String VersionOptionCannotBeCombinedWithOtherArguments(System.String optionAlias) public System.String VersionOptionDescription() - public class Option : IdentifierSymbol, System.CommandLine.Binding.IValueDescriptor, System.CommandLine.Completions.ICompletionSource - .ctor(System.String name, System.String description = null, System.Type argumentType = null, System.Func getDefaultValue = null, ArgumentArity arity = null) - .ctor(System.String[] aliases, System.String description = null, System.Type argumentType = null, System.Func getDefaultValue = null, ArgumentArity arity = null) + public abstract class Option : IdentifierSymbol, System.CommandLine.Binding.IValueDescriptor, System.CommandLine.Completions.ICompletionSource public System.Boolean AllowMultipleArgumentsPerToken { get; set; } public System.String ArgumentHelpName { get; set; } public ArgumentArity Arity { get; set; } diff --git a/src/System.CommandLine.Benchmarks/CommandLine/Perf_Parser_Options_Bare.cs b/src/System.CommandLine.Benchmarks/CommandLine/Perf_Parser_Options_Bare.cs index b4b69698db..ca6d9d3a70 100644 --- a/src/System.CommandLine.Benchmarks/CommandLine/Perf_Parser_Options_Bare.cs +++ b/src/System.CommandLine.Benchmarks/CommandLine/Perf_Parser_Options_Bare.cs @@ -22,8 +22,9 @@ public class Perf_Parser_Options_Bare private IEnumerable