internal static IArgument ToArgument(this IArgumentDef argumentDef, AppConfig appConfig, bool isInterceptorOption) { var underlyingType = argumentDef.Type.GetUnderlyingType(); var argument = BuildArgument( argumentDef, new TypeInfo(argumentDef.Type, underlyingType), isInterceptorOption); argument.Services.AddOrUpdate(argumentDef); if (argumentDef.CustomAttributes is ParameterInfo param) { argument.Services.Add(param); } else if (argumentDef.CustomAttributes is PropertyInfo prop) { argument.Services.Add(prop); } var typeDescriptor = appConfig.AppSettings.ArgumentTypeDescriptors.GetDescriptorOrThrow(underlyingType); argument.TypeInfo.DisplayName = typeDescriptor.GetDisplayName(argument); if (typeDescriptor is IAllowedValuesTypeDescriptor allowedValuesTypeDescriptor) { argument.AllowedValues = allowedValuesTypeDescriptor.GetAllowedValues(argument).ToReadOnlyCollection(); } return(argument); }
internal static BooleanMode?GetBooleanMode( this IArgumentDef argumentDef, BooleanMode defaultBooleanMode) { if (argumentDef.Type != typeof(bool) && argumentDef.Type != typeof(bool?)) { return(null); } if (argumentDef.CommandNodeType == CommandNodeType.Operand) { return(BooleanMode.Explicit); } OptionAttribute?optionAttr = argumentDef.GetCustomAttribute <OptionAttribute>(); if (optionAttr?.BooleanModeAsNullable == null) { return(defaultBooleanMode); } return(argumentDef.Type.GetUnderlyingType() == typeof(bool) ? optionAttr.BooleanMode : throw new InvalidConfigurationException( $"BooleanMode is set to `{optionAttr.BooleanMode}` for a non boolean type. {argumentDef}")); }
// end-snippet internal static IArgumentArity Default(IArgumentDef argumentDef) { return(Default( argumentDef.Type, argumentDef.IsOptional, argumentDef.HasDefaultValue, argumentDef.BooleanMode)); }
private static IArgument BuildArgument(IArgumentDef argumentDef, Command parent, AppConfig appConfig, TypeInfo typeInfo, bool isInterceptorOption) { var defaultValue = argumentDef.HasDefaultValue ? argumentDef.DefaultValue : null; if (argumentDef.CommandNodeType == CommandNodeType.Operand) { var operandAttr = argumentDef.CustomAttributes.GetCustomAttribute <OperandAttribute>() ?? (INameAndDescription)argumentDef.CustomAttributes.GetCustomAttribute <ArgumentAttribute>(); return(new Operand( argumentDef.Name, parent, typeInfo, ArgumentArity.Default(argumentDef.Type, argumentDef.HasDefaultValue, BooleanMode.Explicit), argumentDef.SourcePath, customAttributes: argumentDef.CustomAttributes, argumentDef.ValueProxy) { Description = operandAttr?.Description, DefaultValue = defaultValue }); } if (argumentDef.CommandNodeType == CommandNodeType.Option) { var optionAttr = argumentDef.CustomAttributes.GetCustomAttribute <OptionAttribute>(); var booleanMode = GetOptionBooleanMode(argumentDef, appConfig.AppSettings.BooleanMode, optionAttr); var argumentArity = ArgumentArity.Default(argumentDef.Type, argumentDef.HasDefaultValue, booleanMode); var assignOnlyToExecutableSubcommands = optionAttr?.AssignToExecutableSubcommands ?? false; isInterceptorOption = isInterceptorOption && !assignOnlyToExecutableSubcommands; var longName = optionAttr?.ShortName != null ? optionAttr?.LongName : (optionAttr?.LongName ?? argumentDef.Name); return(new Option( longName, ParseShortName(argumentDef, optionAttr?.ShortName), parent, typeInfo, argumentArity, definitionSource: argumentDef.SourcePath, customAttributes: argumentDef.CustomAttributes, isInterceptorOption: isInterceptorOption, assignToExecutableSubcommands: assignOnlyToExecutableSubcommands, valueProxy: argumentDef.ValueProxy) { Description = optionAttr?.Description, DefaultValue = defaultValue }); } throw new ArgumentOutOfRangeException($"Unknown argument type: {argumentDef.CommandNodeType}"); }
internal static char?GetSplitChar(this IArgumentDef argumentDef) { OptionAttribute?optionAttr = argumentDef.GetCustomAttribute <OptionAttribute>(); return(optionAttr?.SplitAsNullable is null ? null : argumentDef.Type.IsNonStringEnumerable() ? optionAttr.SplitAsNullable : throw new InvalidConfigurationException( $"Split can only be specified for IEnumerable<T> types. {argumentDef.SourcePath} is type {argumentDef.Type}")); }
private static BooleanMode GetOptionBooleanMode( IArgumentDef argumentDef, BooleanMode appBooleanMode, OptionAttribute optionAttr) { if (optionAttr == null || optionAttr.BooleanMode == BooleanMode.Unknown) { return(appBooleanMode); } return(argumentDef.Type.GetUnderlyingType() == typeof(bool) ? optionAttr.BooleanMode : throw new AppRunnerException( $"BooleanMode is set to `{optionAttr.BooleanMode}` for a non boolean type. {argumentDef}")); }
private static BooleanMode GetOptionBooleanMode( IArgumentDef argumentDef, BooleanMode defaultBooleanMode, OptionAttribute?optionAttr) { if (optionAttr?.BooleanModeAsNullable == null) { return(defaultBooleanMode); } return(argumentDef.Type.GetUnderlyingType() == typeof(bool) ? optionAttr.BooleanMode : throw new InvalidConfigurationException( $"BooleanMode is set to `{optionAttr.BooleanMode}` for a non boolean type. {argumentDef}")); }
private static string?ParseLongName(IArgumentDef argumentDef, OptionAttribute?optionAttr) { if (optionAttr == null) { return(argumentDef.Name); } if (optionAttr.LongName != null) { return(optionAttr.LongName); } return(optionAttr.NoLongName ? null : argumentDef.Name); }
private static IArgument BuildArgument(IArgumentDef argumentDef, TypeInfo typeInfo, bool isInterceptorOption) { var argumentDefault = argumentDef.HasDefaultValue && !argumentDef.DefaultValue.IsNullValue() ? new ArgumentDefault($"app.{argumentDef.ArgumentDefType}", argumentDef.SourcePath, argumentDef.DefaultValue !) : null; if (argumentDef.CommandNodeType == CommandNodeType.Operand) { var operandAttr = argumentDef.GetCustomAttribute <OperandAttribute>(); return(new Operand( argumentDef.Name, typeInfo, argumentDef.Arity, argumentDef.BooleanMode, argumentDef.SourcePath, customAttributes: argumentDef.CustomAttributes, argumentDef.ValueProxy) { Description = JoinFromAttribute(argumentDef, nameof(operandAttr.Description), operandAttr?.Description, operandAttr?.DescriptionLines), Default = argumentDefault }); } if (argumentDef.CommandNodeType == CommandNodeType.Option) { var optionAttr = argumentDef.GetCustomAttribute <OptionAttribute>(); var assignOnlyToExecutableSubcommands = optionAttr?.AssignToExecutableSubcommands ?? false; isInterceptorOption = isInterceptorOption && !assignOnlyToExecutableSubcommands; return(new Option( ParseLongName(argumentDef, optionAttr), optionAttr?.ShortName, typeInfo, argumentDef.Arity, argumentDef.BooleanMode, definitionSource: argumentDef.SourcePath, customAttributes: argumentDef.CustomAttributes, isInterceptorOption: isInterceptorOption, assignToExecutableSubcommands: assignOnlyToExecutableSubcommands, valueProxy: argumentDef.ValueProxy) { Description = JoinFromAttribute(argumentDef, nameof(optionAttr.Description), optionAttr?.Description, optionAttr?.DescriptionLines), Split = argumentDef.Split, Default = argumentDefault }); } throw new ArgumentOutOfRangeException($"Unknown argument type: {argumentDef.CommandNodeType}"); }
private static char?ParseShortName(IArgumentDef argumentDef, string shortNameAsString) { if (shortNameAsString.IsNullOrWhitespace()) { return(null); } if (shortNameAsString.Length > 1) { throw new ArgumentException($"Short name must be a single character: {shortNameAsString} {argumentDef}", nameof(shortNameAsString)); } return(shortNameAsString.Single()); }
private static IArgument ToArgument(this IArgumentDef argumentDef, AppConfig appConfig, bool isInterceptorOption) { var underlyingType = argumentDef.Type.GetUnderlyingType(); var argument = BuildArgument( argumentDef, appConfig, new TypeInfo(argumentDef.Type, underlyingType), isInterceptorOption); argumentDef.Argument = argument; argument.Services.AddOrUpdate(argumentDef); var typeDescriptor = appConfig.AppSettings.ArgumentTypeDescriptors.GetDescriptorOrThrow(underlyingType); argument.TypeInfo.DisplayName = typeDescriptor.GetDisplayName(argument); if (typeDescriptor is IAllowedValuesTypeDescriptor allowedValuesTypeDescriptor) { argument.AllowedValues = allowedValuesTypeDescriptor.GetAllowedValues(argument).ToReadOnlyCollection(); } return(argument); }