From 578f662317b0038d0f196433326ea40011782857 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Sun, 9 Feb 2020 13:15:52 -0800 Subject: [PATCH 1/2] Remove .NET Standard 1.6 target framework --- CHANGELOG.md | 2 ++ docs/v3.0/upgrade-guide.md | 18 ++++++++++++++++++ .../Attributes/AllowedValuesAttribute.cs | 5 ----- src/CommandLineUtils/IO/Pager.cs | 2 +- src/CommandLineUtils/Internal/Util.cs | 2 +- ...McMaster.Extensions.CommandLineUtils.csproj | 16 +--------------- src/CommandLineUtils/Utilities/DotNetExe.cs | 2 +- src/CommandLineUtils/Utilities/Prompt.cs | 10 +++------- 8 files changed, 27 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a637c621..7b1cd74f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,12 +6,14 @@ * Fix [#251] by [@mattnischan] - remove API that was marked as obsolete in 2.x releases * Fix [#294] by [@natemcmaster] - change dependencies on McMaster.Extensions.Hosting.CommandLine to just use Microsoft.Extensions.Hosting.Abstractions +* Fix [#337] by [@natemcmaster] - removed .NET Standard 1.6 target from library [@mattnischan]: https://github.com/mattnischan [@natemcmaster]: https://github.com/natemcmaster [#251]: https://github.com/natemcmaster/CommandLineUtils/issues/251 [#294]: https://github.com/natemcmaster/CommandLineUtils/issues/294 +[#337]: https://github.com/natemcmaster/CommandLineUtils/issues/337 ## [v2.5.1](https://github.com/natemcmaster/CommandLineUtils/compare/v2.5.0...v2.5.1) diff --git a/docs/v3.0/upgrade-guide.md b/docs/v3.0/upgrade-guide.md index 3f443d34..0bcebd33 100644 --- a/docs/v3.0/upgrade-guide.md +++ b/docs/v3.0/upgrade-guide.md @@ -3,6 +3,24 @@ uid: 2.x-to-3.0-upgrade --- # Upgrading to CommandLineUtils 3.0 +For more technical details, see [this list of GitHub issues](https://github.com/natemcmaster/CommandLineUtils/issues?q=label%3Abreaking-change+milestone%3A3.0). + +## NuGet compatibility with older platforms + +3.0 removed support for older .NET platforms, like .NET Standard 1.6, .NET Core 1.x, and UWP 8.0. The library still supports .NET Framework 4.5 and .NET Standard 2.0. + +## Symptom + +NuGet fails to install your project with an error like + +> error NU1202: Package McMaster.Extensions.CommandLineUtils 3.0.0 is not compatible with netcoreapp1.1 (.NETCoreApp,Version=v1.1). Package McMaster.Extensions.CommandLineUtils 3.1.0 supports: +> error NU1202: - net45 (.NETFramework,Version=v4.5) +> error NU1202: - netstandard2.0 (.NETStandard,Version=v2.0) + +## Resolution + +Either keep using CommandLineUtils 2.x, or upgrade your application to something newer. See https://dotnet.microsoft.com/platform/dotnet-standard for a list of .NET platforms compatible with .NET Standard 2.0. + ## Upgrading McMaster.Extensions.Hosting.CommandLine In order to fix [#294], McMaster.Extensions.Hosting.CommandLine 3.0's dependency on Microsoft.Extensions.Hosting diff --git a/src/CommandLineUtils/Attributes/AllowedValuesAttribute.cs b/src/CommandLineUtils/Attributes/AllowedValuesAttribute.cs index 93289bc6..81af784e 100644 --- a/src/CommandLineUtils/Attributes/AllowedValuesAttribute.cs +++ b/src/CommandLineUtils/Attributes/AllowedValuesAttribute.cs @@ -56,12 +56,7 @@ public bool IgnoreCase get { return Comparer == StringComparison.CurrentCultureIgnoreCase -#if (NETSTANDARD2_0 || NET45) || Comparer == StringComparison.InvariantCultureIgnoreCase -#elif NETSTANDARD1_6 -#else -#error Target frameworks should be updated -#endif || Comparer == StringComparison.OrdinalIgnoreCase; } set diff --git a/src/CommandLineUtils/IO/Pager.cs b/src/CommandLineUtils/IO/Pager.cs index 7d9deb19..484ee1ab 100644 --- a/src/CommandLineUtils/IO/Pager.cs +++ b/src/CommandLineUtils/IO/Pager.cs @@ -46,7 +46,7 @@ public Pager(IConsole console) #if NET45 // if .NET Framework, assume we're on Windows unless it's running on Mono. _enabled = Type.GetType("Mono.Runtime") != null; -#elif NETSTANDARD1_6 || NETSTANDARD2_0 +#elif NETSTANDARD2_0 _enabled = !RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !console.IsOutputRedirected; #else #error Update target frameworks diff --git a/src/CommandLineUtils/Internal/Util.cs b/src/CommandLineUtils/Internal/Util.cs index cec4b1a4..4f4ca840 100644 --- a/src/CommandLineUtils/Internal/Util.cs +++ b/src/CommandLineUtils/Internal/Util.cs @@ -16,7 +16,7 @@ private static class EmptyArrayCache internal static readonly T[] Value = new T[0]; } -#elif (NETSTANDARD1_6 || NETSTANDARD2_0) +#elif NETSTANDARD2_0 => Array.Empty(); #else #error Update target frameworks diff --git a/src/CommandLineUtils/McMaster.Extensions.CommandLineUtils.csproj b/src/CommandLineUtils/McMaster.Extensions.CommandLineUtils.csproj index ee309c0d..e50a779a 100644 --- a/src/CommandLineUtils/McMaster.Extensions.CommandLineUtils.csproj +++ b/src/CommandLineUtils/McMaster.Extensions.CommandLineUtils.csproj @@ -1,12 +1,7 @@  - netstandard2.0;netstandard1.6;net45 - - true + netstandard2.0;net45 true true Command-line parsing API. @@ -35,13 +30,4 @@ McMaster.Extensions.CommandLineUtils.ArgumentEscaper - - - - - - - - - diff --git a/src/CommandLineUtils/Utilities/DotNetExe.cs b/src/CommandLineUtils/Utilities/DotNetExe.cs index b8fdad63..95c9d48a 100644 --- a/src/CommandLineUtils/Utilities/DotNetExe.cs +++ b/src/CommandLineUtils/Utilities/DotNetExe.cs @@ -44,7 +44,7 @@ public static string FullPathOrDefault() var fileName = FileName; #if NET45 fileName += ".exe"; -#elif (NETSTANDARD1_6 || NETSTANDARD2_0) +#elif NETSTANDARD2_0 if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { fileName += ".exe"; diff --git a/src/CommandLineUtils/Utilities/Prompt.cs b/src/CommandLineUtils/Utilities/Prompt.cs index 025b0e6c..99466139 100644 --- a/src/CommandLineUtils/Utilities/Prompt.cs +++ b/src/CommandLineUtils/Utilities/Prompt.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Security; using System.Text; namespace McMaster.Extensions.CommandLineUtils @@ -118,7 +119,6 @@ public static string GetPassword(string prompt, ConsoleColor? promptColor = null return resp.ToString(); } -#if NET45 || NETSTANDARD2_0 /// /// Gets a response as a SecureString object. Input is masked with an asterisk. /// @@ -126,9 +126,9 @@ public static string GetPassword(string prompt, ConsoleColor? promptColor = null /// The console color to use for the prompt /// The console background color for the prompt /// A finalized SecureString object, may be empty. - public static System.Security.SecureString GetPasswordAsSecureString(string prompt, ConsoleColor? promptColor = null, ConsoleColor? promptBgColor = null) + public static SecureString GetPasswordAsSecureString(string prompt, ConsoleColor? promptColor = null, ConsoleColor? promptBgColor = null) { - var secureString = new System.Security.SecureString(); + var secureString = new SecureString(); foreach (var key in ReadObfuscatedLine(prompt, promptColor, promptBgColor)) { @@ -146,10 +146,6 @@ public static System.Security.SecureString GetPasswordAsSecureString(string prom secureString.MakeReadOnly(); return secureString; } -#elif NETSTANDARD1_6 -#else -#error Target frameworks should be updated -#endif /// /// Base implementation of GetPassword and GetPasswordAsString. Prompts the user for From 1de7d64cfff6eab0d4af7cff2a50cfcc8a75fc38 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Sun, 9 Feb 2020 13:45:26 -0800 Subject: [PATCH 2/2] cleanup: remove usages of TypeInfo --- .../Abstractions/ValueParserProvider.cs | 22 +++++------ .../AppNameFromEntryAssemblyConvention.cs | 2 +- .../ArgumentAttributeConvention.cs | 2 +- .../Conventions/AttributeConvention.cs | 2 +- .../Conventions/CommandAttributeConvention.cs | 4 +- .../ConstructorInjectionConvention.cs | 4 +- .../DefaultHelpOptionConvention.cs | 11 ++---- .../Conventions/ExecuteMethodConvention.cs | 5 +-- .../HelpOptionAttributeConvention.cs | 2 +- .../Conventions/ParentPropertyConvention.cs | 2 +- .../RemainingArgsPropertyConvention.cs | 9 ++--- .../SubcommandAttributeConvention.cs | 2 +- .../SubcommandPropertyConvention.cs | 2 +- .../Conventions/ValidateMethodConvention.cs | 9 ++--- .../ValidationErrorMethodConvention.cs | 5 +-- .../VersionOptionAttributeConvention.cs | 2 +- ...sionOptionFromMemberAttributeConvention.cs | 2 +- .../HelpText/DefaultHelpTextGenerator.cs | 2 +- .../Internal/CollectionParserProvider.cs | 5 +-- .../Internal/CommandOptionTypeMapper.cs | 19 +++++----- .../Internal/ReflectionHelper.cs | 37 +++++++++---------- src/CommandLineUtils/Properties/Strings.cs | 4 +- .../Validation/ValidationExtensions.cs | 2 +- .../CommandLineApplicationExecutorTests.cs | 2 +- .../OptionAttributeTests.cs | 4 +- 25 files changed, 72 insertions(+), 90 deletions(-) diff --git a/src/CommandLineUtils/Abstractions/ValueParserProvider.cs b/src/CommandLineUtils/Abstractions/ValueParserProvider.cs index 982148e3..5e5e2e1d 100644 --- a/src/CommandLineUtils/Abstractions/ValueParserProvider.cs +++ b/src/CommandLineUtils/Abstractions/ValueParserProvider.cs @@ -48,7 +48,7 @@ internal ValueParserProvider() public CultureInfo ParseCulture { get; set; } = CultureInfo.CurrentCulture; private static readonly MethodInfo s_GetParserGeneric - = typeof(ValueParserProvider).GetTypeInfo() + = typeof(ValueParserProvider) .GetMethods(BindingFlags.Instance | BindingFlags.Public) .Single(m => m.Name == nameof(GetParser) && m.IsGenericMethod); @@ -95,16 +95,14 @@ public IValueParser GetParser(Type type) return parser; } - var typeInfo = type.GetTypeInfo(); - - if (typeInfo.IsEnum) + if (type.IsEnum) { return EnumParser.Create(type); } - if (ReflectionHelper.IsNullableType(typeInfo, out var wrappedType) && wrappedType != null) + if (ReflectionHelper.IsNullableType(type, out var wrappedType) && wrappedType != null) { - if (wrappedType.GetTypeInfo().IsEnum) + if (wrappedType.IsEnum) { return new NullableValueParser(EnumParser.Create(wrappedType)); } @@ -115,20 +113,20 @@ public IValueParser GetParser(Type type) } } - if (!typeInfo.IsGenericType) + if (!type.IsGenericType) { return null; } - var typeDef = typeInfo.GetGenericTypeDefinition(); - if (typeDef == typeof(ValueTuple<,>) && typeInfo.GenericTypeArguments[0] == typeof(bool)) + var typeDef = type.GetGenericTypeDefinition(); + if (typeDef == typeof(ValueTuple<,>) && type.GenericTypeArguments[0] == typeof(bool)) { - var innerParser = GetParser(typeInfo.GenericTypeArguments[1]); + var innerParser = GetParser(type.GenericTypeArguments[1]); if (innerParser == null) { return null; } - var method = typeof(ValueTupleValueParser).GetTypeInfo().GetMethod(nameof(ValueTupleValueParser.Create)).MakeGenericMethod(typeInfo.GenericTypeArguments[1]); + var method = typeof(ValueTupleValueParser).GetMethod(nameof(ValueTupleValueParser.Create)).MakeGenericMethod(type.GenericTypeArguments[1]); return (IValueParser)method.Invoke(null, new object[] { innerParser }); } @@ -197,7 +195,7 @@ private void SafeAdd(IValueParser parser, bool andReplace = false) } // strip nullable wrappers since we have a dedicated nullable value parser - targetType = ReflectionHelper.IsNullableType(targetType.GetTypeInfo(), out var wrappedType) && wrappedType != null + targetType = ReflectionHelper.IsNullableType(targetType, out var wrappedType) && wrappedType != null ? wrappedType : targetType; diff --git a/src/CommandLineUtils/Conventions/AppNameFromEntryAssemblyConvention.cs b/src/CommandLineUtils/Conventions/AppNameFromEntryAssemblyConvention.cs index 45d8eaa5..dc25fdf6 100644 --- a/src/CommandLineUtils/Conventions/AppNameFromEntryAssemblyConvention.cs +++ b/src/CommandLineUtils/Conventions/AppNameFromEntryAssemblyConvention.cs @@ -22,7 +22,7 @@ public virtual void Apply(ConventionContext context) var assembly = Assembly.GetEntryAssembly(); if (assembly == null && context.ModelType != null) { - assembly = context.ModelType.GetTypeInfo().Assembly; + assembly = context.ModelType.Assembly; } if (assembly != null) diff --git a/src/CommandLineUtils/Conventions/ArgumentAttributeConvention.cs b/src/CommandLineUtils/Conventions/ArgumentAttributeConvention.cs index f415da2c..132e2455 100644 --- a/src/CommandLineUtils/Conventions/ArgumentAttributeConvention.cs +++ b/src/CommandLineUtils/Conventions/ArgumentAttributeConvention.cs @@ -83,7 +83,7 @@ private void AddArgument(PropertyInfo prop, argument.MultipleValues = prop.PropertyType.IsArray - || (typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(prop.PropertyType) + || (typeof(IEnumerable).IsAssignableFrom(prop.PropertyType) && prop.PropertyType != typeof(string)); if (argPropOrder.TryGetValue(argumentAttr.Order, out var otherProp)) diff --git a/src/CommandLineUtils/Conventions/AttributeConvention.cs b/src/CommandLineUtils/Conventions/AttributeConvention.cs index 367e7d3f..22e52b09 100644 --- a/src/CommandLineUtils/Conventions/AttributeConvention.cs +++ b/src/CommandLineUtils/Conventions/AttributeConvention.cs @@ -19,7 +19,7 @@ public void Apply(ConventionContext context) return; } - foreach (var attr in context.ModelType.GetTypeInfo().GetCustomAttributes().OfType()) + foreach (var attr in context.ModelType.GetCustomAttributes().OfType()) { attr.Apply(context); } diff --git a/src/CommandLineUtils/Conventions/CommandAttributeConvention.cs b/src/CommandLineUtils/Conventions/CommandAttributeConvention.cs index 654231ad..326e4548 100644 --- a/src/CommandLineUtils/Conventions/CommandAttributeConvention.cs +++ b/src/CommandLineUtils/Conventions/CommandAttributeConvention.cs @@ -27,7 +27,7 @@ public virtual void Apply(ConventionContext context) return; } - var attribute = context.ModelType.GetTypeInfo().GetCustomAttribute(); + var attribute = context.ModelType.GetCustomAttribute(); attribute?.Configure(context.Application); foreach (var subcommand in context.Application.Commands) @@ -38,7 +38,7 @@ public virtual void Apply(ConventionContext context) } } - foreach (var attr in context.ModelType.GetTypeInfo().GetCustomAttributes()) + foreach (var attr in context.ModelType.GetCustomAttributes()) { context.Application.Validators.Add(new AttributeValidator(attr)); } diff --git a/src/CommandLineUtils/Conventions/ConstructorInjectionConvention.cs b/src/CommandLineUtils/Conventions/ConstructorInjectionConvention.cs index 709a9671..00cec77f 100644 --- a/src/CommandLineUtils/Conventions/ConstructorInjectionConvention.cs +++ b/src/CommandLineUtils/Conventions/ConstructorInjectionConvention.cs @@ -53,9 +53,7 @@ private static readonly MethodInfo s_applyMethod private void ApplyImpl(ConventionContext context) where TModel : class { - var constructors = typeof(TModel) - .GetTypeInfo() - .GetConstructors(BindingFlags.Public | BindingFlags.Instance); + var constructors = typeof(TModel).GetConstructors(BindingFlags.Public | BindingFlags.Instance); var factory = FindMatchedConstructor(constructors, context.Application, constructors.Length == 1); diff --git a/src/CommandLineUtils/Conventions/DefaultHelpOptionConvention.cs b/src/CommandLineUtils/Conventions/DefaultHelpOptionConvention.cs index 58fcabd8..bcadccc3 100644 --- a/src/CommandLineUtils/Conventions/DefaultHelpOptionConvention.cs +++ b/src/CommandLineUtils/Conventions/DefaultHelpOptionConvention.cs @@ -33,14 +33,11 @@ public void Apply(ConventionContext context) return; } - if (context.ModelType != null) + if (context.ModelType != null + && (context.ModelType.GetCustomAttribute() != null + || context.ModelType.Assembly.GetCustomAttribute() != null)) { - var typeInfo = context.ModelType.GetTypeInfo(); - if (typeInfo.GetCustomAttribute() != null - || typeInfo.Assembly.GetCustomAttribute() != null) - { - return; - } + return; } var help = new CommandOption(_template, CommandOptionType.NoValue) diff --git a/src/CommandLineUtils/Conventions/ExecuteMethodConvention.cs b/src/CommandLineUtils/Conventions/ExecuteMethodConvention.cs index f09dfa11..473b15c9 100644 --- a/src/CommandLineUtils/Conventions/ExecuteMethodConvention.cs +++ b/src/CommandLineUtils/Conventions/ExecuteMethodConvention.cs @@ -31,13 +31,12 @@ private async Task OnExecute(ConventionContext context, CancellationToken c { const BindingFlags binding = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public; - var typeInfo = context.ModelType.GetTypeInfo(); MethodInfo? method; MethodInfo? asyncMethod; try { - method = typeInfo.GetMethod("OnExecute", binding); - asyncMethod = typeInfo.GetMethod("OnExecuteAsync", binding); + method = context.ModelType.GetMethod("OnExecute", binding); + asyncMethod = context.ModelType.GetMethod("OnExecuteAsync", binding); } catch (AmbiguousMatchException ex) { diff --git a/src/CommandLineUtils/Conventions/HelpOptionAttributeConvention.cs b/src/CommandLineUtils/Conventions/HelpOptionAttributeConvention.cs index 63b46781..0551d087 100644 --- a/src/CommandLineUtils/Conventions/HelpOptionAttributeConvention.cs +++ b/src/CommandLineUtils/Conventions/HelpOptionAttributeConvention.cs @@ -20,7 +20,7 @@ public virtual void Apply(ConventionContext context) return; } - var helpOptionAttrOnType = context.ModelType.GetTypeInfo().GetCustomAttribute(); + var helpOptionAttrOnType = context.ModelType.GetCustomAttribute(); helpOptionAttrOnType?.Configure(context.Application); var props = ReflectionHelper.GetProperties(context.ModelType); diff --git a/src/CommandLineUtils/Conventions/ParentPropertyConvention.cs b/src/CommandLineUtils/Conventions/ParentPropertyConvention.cs index 5a3ac173..ef95c48a 100644 --- a/src/CommandLineUtils/Conventions/ParentPropertyConvention.cs +++ b/src/CommandLineUtils/Conventions/ParentPropertyConvention.cs @@ -21,7 +21,7 @@ public virtual void Apply(ConventionContext context) return; } - var parentProp = context.ModelType.GetTypeInfo().GetProperty("Parent", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); + var parentProp = context.ModelType.GetProperty("Parent", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); if (parentProp == null) { return; diff --git a/src/CommandLineUtils/Conventions/RemainingArgsPropertyConvention.cs b/src/CommandLineUtils/Conventions/RemainingArgsPropertyConvention.cs index f3511c48..fdf1ec2e 100644 --- a/src/CommandLineUtils/Conventions/RemainingArgsPropertyConvention.cs +++ b/src/CommandLineUtils/Conventions/RemainingArgsPropertyConvention.cs @@ -26,9 +26,8 @@ public virtual void Apply(ConventionContext context) return; } - var typeInfo = context.ModelType.GetTypeInfo(); - var prop = typeInfo.GetProperty("RemainingArguments", PropertyBindingFlags); - prop ??= typeInfo.GetProperty("RemainingArgs", PropertyBindingFlags); + var prop = context.ModelType.GetProperty("RemainingArguments", PropertyBindingFlags); + prop ??= context.ModelType.GetProperty("RemainingArgs", PropertyBindingFlags); if (prop == null) { return; @@ -43,9 +42,9 @@ public virtual void Apply(ConventionContext context) return; } - if (!typeof(IReadOnlyList).GetTypeInfo().IsAssignableFrom(prop.PropertyType)) + if (!typeof(IReadOnlyList).IsAssignableFrom(prop.PropertyType)) { - throw new InvalidOperationException(Strings.RemainingArgsPropsIsUnassignable(typeInfo)); + throw new InvalidOperationException(Strings.RemainingArgsPropsIsUnassignable(context.ModelType)); } context.Application.OnParsingComplete(r => diff --git a/src/CommandLineUtils/Conventions/SubcommandAttributeConvention.cs b/src/CommandLineUtils/Conventions/SubcommandAttributeConvention.cs index db49e21a..637127f0 100644 --- a/src/CommandLineUtils/Conventions/SubcommandAttributeConvention.cs +++ b/src/CommandLineUtils/Conventions/SubcommandAttributeConvention.cs @@ -24,7 +24,7 @@ public virtual void Apply(ConventionContext context) return; } - var attributes = context.ModelType.GetTypeInfo().GetCustomAttributes(); + var attributes = context.ModelType.GetCustomAttributes(); foreach (var attribute in attributes) { diff --git a/src/CommandLineUtils/Conventions/SubcommandPropertyConvention.cs b/src/CommandLineUtils/Conventions/SubcommandPropertyConvention.cs index 29379eb3..17d2db6e 100644 --- a/src/CommandLineUtils/Conventions/SubcommandPropertyConvention.cs +++ b/src/CommandLineUtils/Conventions/SubcommandPropertyConvention.cs @@ -21,7 +21,7 @@ public virtual void Apply(ConventionContext context) return; } - var subcommandProp = context.ModelType.GetTypeInfo().GetProperty("Subcommand", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); + var subcommandProp = context.ModelType.GetProperty("Subcommand", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); if (subcommandProp == null) { return; diff --git a/src/CommandLineUtils/Conventions/ValidateMethodConvention.cs b/src/CommandLineUtils/Conventions/ValidateMethodConvention.cs index cb6d2d10..924982bc 100644 --- a/src/CommandLineUtils/Conventions/ValidateMethodConvention.cs +++ b/src/CommandLineUtils/Conventions/ValidateMethodConvention.cs @@ -25,10 +25,7 @@ public void Apply(ConventionContext context) const BindingFlags MethodFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; - var method = context.ModelType - .GetTypeInfo() - .GetMethod("OnValidate", MethodFlags); - + var method = context.ModelType.GetMethod("OnValidate", MethodFlags); if (method == null) { return; @@ -48,11 +45,11 @@ public void Apply(ConventionContext context) { var methodParam = methodParams[i]; - if (typeof(ValidationContext).GetTypeInfo().IsAssignableFrom(methodParam.ParameterType)) + if (typeof(ValidationContext).IsAssignableFrom(methodParam.ParameterType)) { arguments[i] = ctx; } - else if (typeof(CommandLineContext).GetTypeInfo().IsAssignableFrom(methodParam.ParameterType)) + else if (typeof(CommandLineContext).IsAssignableFrom(methodParam.ParameterType)) { arguments[i] = context.Application._context; } diff --git a/src/CommandLineUtils/Conventions/ValidationErrorMethodConvention.cs b/src/CommandLineUtils/Conventions/ValidationErrorMethodConvention.cs index cb97bbe8..7104c789 100644 --- a/src/CommandLineUtils/Conventions/ValidationErrorMethodConvention.cs +++ b/src/CommandLineUtils/Conventions/ValidationErrorMethodConvention.cs @@ -22,10 +22,7 @@ public virtual void Apply(ConventionContext context) const BindingFlags MethodFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; - var method = context.ModelType - .GetTypeInfo() - .GetMethod("OnValidationError", MethodFlags); - + var method = context.ModelType.GetMethod("OnValidationError", MethodFlags); if (method == null) { return; diff --git a/src/CommandLineUtils/Conventions/VersionOptionAttributeConvention.cs b/src/CommandLineUtils/Conventions/VersionOptionAttributeConvention.cs index dd969317..bc7472cf 100644 --- a/src/CommandLineUtils/Conventions/VersionOptionAttributeConvention.cs +++ b/src/CommandLineUtils/Conventions/VersionOptionAttributeConvention.cs @@ -21,7 +21,7 @@ public virtual void Apply(ConventionContext context) return; } - var versionOptionAttrOnType = context.ModelType.GetTypeInfo().GetCustomAttribute(); + var versionOptionAttrOnType = context.ModelType.GetCustomAttribute(); versionOptionAttrOnType?.Configure(context.Application); var props = ReflectionHelper.GetProperties(context.ModelType); diff --git a/src/CommandLineUtils/Conventions/VersionOptionFromMemberAttributeConvention.cs b/src/CommandLineUtils/Conventions/VersionOptionFromMemberAttributeConvention.cs index 24464e7a..d0368d7c 100644 --- a/src/CommandLineUtils/Conventions/VersionOptionFromMemberAttributeConvention.cs +++ b/src/CommandLineUtils/Conventions/VersionOptionFromMemberAttributeConvention.cs @@ -20,7 +20,7 @@ public virtual void Apply(ConventionContext context) return; } - var versionOptionFromMember = context.ModelType.GetTypeInfo().GetCustomAttribute(); + var versionOptionFromMember = context.ModelType.GetCustomAttribute(); versionOptionFromMember?.Configure(context.Application, context.ModelType, modelAccessor.GetModel); } } diff --git a/src/CommandLineUtils/HelpText/DefaultHelpTextGenerator.cs b/src/CommandLineUtils/HelpText/DefaultHelpTextGenerator.cs index 9c5d963b..83252ee3 100644 --- a/src/CommandLineUtils/HelpText/DefaultHelpTextGenerator.cs +++ b/src/CommandLineUtils/HelpText/DefaultHelpTextGenerator.cs @@ -367,7 +367,7 @@ protected virtual string Format(CommandOption option) private string[] ExtractNamesFromEnum(Type type) { - if (type == null || !type.GetTypeInfo().IsEnum) + if (type == null || !type.IsEnum) { return Util.EmptyArray(); } diff --git a/src/CommandLineUtils/Internal/CollectionParserProvider.cs b/src/CommandLineUtils/Internal/CollectionParserProvider.cs index 1447723f..e62e0bef 100644 --- a/src/CommandLineUtils/Internal/CollectionParserProvider.cs +++ b/src/CommandLineUtils/Internal/CollectionParserProvider.cs @@ -30,11 +30,10 @@ private CollectionParserProvider() return new ArrayParser(elementType, elementParser, valueParsers.ParseCulture); } - var typeInfo = type.GetTypeInfo(); - if (typeInfo.IsGenericType) + if (type.IsGenericType) { var typeDef = type.GetGenericTypeDefinition(); - var elementType = typeInfo.GetGenericArguments().First(); + var elementType = type.GetGenericArguments().First(); var elementParser = valueParsers.GetParser(elementType); if (typeof(IList<>) == typeDef diff --git a/src/CommandLineUtils/Internal/CommandOptionTypeMapper.cs b/src/CommandLineUtils/Internal/CommandOptionTypeMapper.cs index 61106454..0f98fcd6 100644 --- a/src/CommandLineUtils/Internal/CommandOptionTypeMapper.cs +++ b/src/CommandLineUtils/Internal/CommandOptionTypeMapper.cs @@ -45,36 +45,35 @@ public CommandOptionType GetOptionType(Type clrType, ValueParserProvider? valueP return CommandOptionType.SingleValue; } - if (clrType.IsArray || typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(clrType)) + if (clrType.IsArray || typeof(IEnumerable).IsAssignableFrom(clrType)) { return CommandOptionType.MultipleValue; } - var typeInfo = clrType.GetTypeInfo(); - if (typeInfo.IsEnum) + if (clrType.IsEnum) { return CommandOptionType.SingleValue; } - if (typeInfo.IsGenericType) + if (clrType.IsGenericType) { - var typeDef = typeInfo.GetGenericTypeDefinition(); + var typeDef = clrType.GetGenericTypeDefinition(); if (typeDef == typeof(Nullable<>)) { - return GetOptionType(typeInfo.GetGenericArguments().First(), valueParsers); + return GetOptionType(clrType.GetGenericArguments().First(), valueParsers); } - if (typeDef == typeof(Tuple<,>) && typeInfo.GenericTypeArguments[0] == typeof(bool)) + if (typeDef == typeof(Tuple<,>) && clrType.GenericTypeArguments[0] == typeof(bool)) { - if (GetOptionType(typeInfo.GenericTypeArguments[1], valueParsers) == CommandOptionType.SingleValue) + if (GetOptionType(clrType.GenericTypeArguments[1], valueParsers) == CommandOptionType.SingleValue) { return CommandOptionType.SingleOrNoValue; } } - if (typeDef == typeof(ValueTuple<,>) && typeInfo.GenericTypeArguments[0] == typeof(bool)) + if (typeDef == typeof(ValueTuple<,>) && clrType.GenericTypeArguments[0] == typeof(bool)) { - if (GetOptionType(typeInfo.GenericTypeArguments[1], valueParsers) == CommandOptionType.SingleValue) + if (GetOptionType(clrType.GenericTypeArguments[1], valueParsers) == CommandOptionType.SingleValue) { return CommandOptionType.SingleOrNoValue; } diff --git a/src/CommandLineUtils/Internal/ReflectionHelper.cs b/src/CommandLineUtils/Internal/ReflectionHelper.cs index 9e1487d2..a3785611 100644 --- a/src/CommandLineUtils/Internal/ReflectionHelper.cs +++ b/src/CommandLineUtils/Internal/ReflectionHelper.cs @@ -13,6 +13,8 @@ namespace McMaster.Extensions.CommandLineUtils { internal class ReflectionHelper { + private const BindingFlags DeclaredOnlyLookup = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly; + public static SetPropertyDelegate GetPropertySetter(PropertyInfo prop) { var setter = prop.GetSetMethod(nonPublic: true); @@ -22,12 +24,11 @@ public static SetPropertyDelegate GetPropertySetter(PropertyInfo prop) } else { - var backingFieldName = string.Format("<{0}>k__BackingField", prop.Name); - var backingField = prop.DeclaringType.GetTypeInfo().GetDeclaredField(backingFieldName); + var backingField = prop.DeclaringType.GetField($"<{prop.Name}>k__BackingField", DeclaredOnlyLookup); if (backingField == null) { throw new InvalidOperationException( - $"Could not find a way to set {prop.DeclaringType.FullName}.{prop.Name}"); + $"Could not find a way to set {prop.DeclaringType.FullName}.{prop.Name}. Try adding a private setter."); } return (obj, value) => backingField.SetValue(obj, value); @@ -36,7 +37,7 @@ public static SetPropertyDelegate GetPropertySetter(PropertyInfo prop) public static MethodInfo[] GetPropertyOrMethod(Type type, string name) { - var members = GetAllMembers(type.GetTypeInfo()).ToList(); + var members = GetAllMembers(type).ToList(); return members .OfType() .Where(m => m.Name == name) @@ -47,14 +48,14 @@ public static MethodInfo[] GetPropertyOrMethod(Type type, string name) public static PropertyInfo[] GetProperties(Type type) { - return GetAllMembers(type.GetTypeInfo()) + return GetAllMembers(type) .OfType() .ToArray(); } public static MemberInfo[] GetMembers(Type type) { - return GetAllMembers(type.GetTypeInfo()).ToArray(); + return GetAllMembers(type).ToArray(); } public static object[] BindParameters(MethodInfo method, CommandLineApplication command, CancellationToken cancellationToken) @@ -66,19 +67,19 @@ public static object[] BindParameters(MethodInfo method, CommandLineApplication { var methodParam = methodParams[i]; - if (typeof(CommandLineApplication).GetTypeInfo().IsAssignableFrom(methodParam.ParameterType)) + if (typeof(CommandLineApplication).IsAssignableFrom(methodParam.ParameterType)) { arguments[i] = command; } - else if (typeof(IConsole).GetTypeInfo().IsAssignableFrom(methodParam.ParameterType)) + else if (typeof(IConsole).IsAssignableFrom(methodParam.ParameterType)) { arguments[i] = command._context.Console; } - else if (typeof(ValidationResult).GetTypeInfo().IsAssignableFrom(methodParam.ParameterType)) + else if (typeof(ValidationResult).IsAssignableFrom(methodParam.ParameterType)) { arguments[i] = command.GetValidationResult(); } - else if (typeof(CommandLineContext).GetTypeInfo().IsAssignableFrom(methodParam.ParameterType)) + else if (typeof(CommandLineContext).IsAssignableFrom(methodParam.ParameterType)) { arguments[i] = command._context; } @@ -96,27 +97,25 @@ public static object[] BindParameters(MethodInfo method, CommandLineApplication return arguments; } - public static bool IsNullableType(TypeInfo typeInfo, out Type? wrappedType) + public static bool IsNullableType(Type type, out Type? wrappedType) { - var result = typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(Nullable<>); - wrappedType = result ? typeInfo.GetGenericArguments().First() : null; + var result = type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); + wrappedType = result ? type.GetGenericArguments().First() : null; return result; } - private static IEnumerable GetAllMembers(TypeInfo typeInfo) + private static IEnumerable GetAllMembers(Type type) { - const BindingFlags binding = BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly; - - while (typeInfo != null) + while (type != null) { - var members = typeInfo.GetMembers(binding); + var members = type.GetMembers(DeclaredOnlyLookup); foreach (var member in members) { yield return member; } - typeInfo = typeInfo.BaseType?.GetTypeInfo(); + type = type.BaseType; } } } diff --git a/src/CommandLineUtils/Properties/Strings.cs b/src/CommandLineUtils/Properties/Strings.cs index cbb93478..301704f1 100644 --- a/src/CommandLineUtils/Properties/Strings.cs +++ b/src/CommandLineUtils/Properties/Strings.cs @@ -90,8 +90,8 @@ public const string VersionOptionOnTypeAndProperty public const string MultipleVersionOptionPropertiesFound = "Multiple VersionOptionAttributes found. VersionOptionAttribute should only be used on one property per type."; - public static string RemainingArgsPropsIsUnassignable(TypeInfo typeInfo) - => $"The RemainingArguments property type on {typeInfo.Name} is invalid. It must be assignable from string[]."; + public static string RemainingArgsPropsIsUnassignable(Type type) + => $"The RemainingArguments property type on {type.Name} is invalid. It must be assignable from string[]."; public static string NoPropertyOrMethodFound(string memberName, Type type) => $"Could not find a property or method named {memberName} on type {type.FullName}"; diff --git a/src/CommandLineUtils/Validation/ValidationExtensions.cs b/src/CommandLineUtils/Validation/ValidationExtensions.cs index be231100..4e57c9cc 100644 --- a/src/CommandLineUtils/Validation/ValidationExtensions.cs +++ b/src/CommandLineUtils/Validation/ValidationExtensions.cs @@ -198,7 +198,7 @@ public static IArgumentValidationBuilder Accepts(this CommandArgument a public static IValidationBuilder Enum(this IValidationBuilder builder, bool ignoreCase = false) where TEnum : struct { - if (!typeof(TEnum).GetTypeInfo().IsEnum) + if (!typeof(TEnum).IsEnum) { throw new ArgumentException("Type parameter T must be an enum."); } diff --git a/test/CommandLineUtils.Tests/CommandLineApplicationExecutorTests.cs b/test/CommandLineUtils.Tests/CommandLineApplicationExecutorTests.cs index 19485c3f..c89a34d1 100755 --- a/test/CommandLineUtils.Tests/CommandLineApplicationExecutorTests.cs +++ b/test/CommandLineUtils.Tests/CommandLineApplicationExecutorTests.cs @@ -157,7 +157,7 @@ public void ThrowsForUnknownOnExecuteTypes() { var ex = Assert.Throws( () => CommandLineApplication.Execute()); - var method = typeof(ExecuteWithUnknownTypes).GetTypeInfo().GetMethod("OnExecute", BindingFlags.Instance | BindingFlags.NonPublic); + var method = typeof(ExecuteWithUnknownTypes).GetMethod("OnExecute", BindingFlags.Instance | BindingFlags.NonPublic); var param = Assert.Single(method.GetParameters()); Assert.Equal(Strings.UnsupportedParameterTypeOnMethod(method.Name, param), ex.Message); } diff --git a/test/CommandLineUtils.Tests/OptionAttributeTests.cs b/test/CommandLineUtils.Tests/OptionAttributeTests.cs index a303a901..6682a3ea 100644 --- a/test/CommandLineUtils.Tests/OptionAttributeTests.cs +++ b/test/CommandLineUtils.Tests/OptionAttributeTests.cs @@ -310,8 +310,8 @@ private CommandOption CreateOption(Type propType, string propName) var ctor = typeof(OptionAttribute).GetConstructor(Array.Empty()); var ab = new CustomAttributeBuilder(ctor, Array.Empty()); pb.SetCustomAttribute(ab); - var program = tb.CreateTypeInfo(); - var appBuilder = typeof(CommandLineApplication<>).MakeGenericType(program.AsType()); + var program = tb.CreateType(); + var appBuilder = typeof(CommandLineApplication<>).MakeGenericType(program); var app = (CommandLineApplication)Activator.CreateInstance(appBuilder, new object[] { false }); app.Conventions.UseOptionAttributes(); return app.Options[0];