Beispiel #1
0
        private static ArgumentDefinition CreateArgumentDescriptor(
            IMutableMemberInfo member,
            ArgumentBaseAttribute attribute,
            object defaultValues,
            ArgumentSetDefinition argSet,
            object fixedDestination,
            ArgumentDefinition containingArgument,
            ServiceConfigurer serviceConfigurer)
        {
            if (!member.IsReadable || !member.IsWritable)
            {
                var declaringType = member.MemberInfo.DeclaringType;

                throw new InvalidArgumentSetException(member, string.Format(
                                                          CultureInfo.CurrentCulture,
                                                          Strings.MemberNotSupported,
                                                          member.MemberInfo.Name,
                                                          declaringType?.Name));
            }

            var defaultFieldValue = (defaultValues != null) ? member.GetValue(defaultValues) : null;

            return(new ArgumentDefinition(member,
                                          attribute,
                                          argSet,
                                          defaultValue: defaultFieldValue,
                                          fixedDestination: fixedDestination,
                                          containingArgument: containingArgument,
                                          serviceConfigurer: serviceConfigurer));
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="argSet">Argument set to create parser for.</param>
        /// <param name="options">Parser options.</param>
        public ArgumentSetParser(ArgumentSetDefinition argSet, CommandLineParserOptions options)
        {
            if (argSet == null)
            {
                throw new ArgumentNullException(nameof(argSet));
            }

            // Clone the argument set definition, as parsing may mutate it.
            ArgumentSet = argSet.DeepClone();

            // Save off the options provided; if none were provided, construct some quiet defaults.
            _options = options?.DeepClone() ?? CommandLineParserOptions.Quiet();

            // If no reporter was provided, use a no-op one.
            if (_options.Reporter == null)
            {
                _options.Reporter = err => { };
            }

            // If no file-system reader was provided, use our default implementation.
            if (_options.FileSystemReader == null)
            {
                _options.FileSystemReader = FileSystemReader.Create();
            }
        }
Beispiel #3
0
 public ArgumentDefinition(MemberInfo member,
                           ArgumentBaseAttribute attribute,
                           ArgumentSetDefinition argSet,
                           object defaultValue = null,
                           ArgumentDefinition containingArgument = null,
                           ServiceConfigurer serviceConfigurer   = null)
     : this(GetMutableMemberInfo(member), attribute, argSet, defaultValue, /*fixedDestination=*/ null, containingArgument, serviceConfigurer)
 {
 }
Beispiel #4
0
        /// <summary>
        /// Internal constructor.
        /// </summary>
        /// <param name="member">Field to describe.</param>
        /// <param name="attribute">Argument attribute on the field.</param>
        /// <param name="argSet">Argument set containing this argument.</param>
        /// <param name="defaultValue">Default value for the field.</param>
        /// <param name="fixedDestination">Optionally provides fixed parse destination object.</param>
        /// <param name="containingArgument">Optionally provides a reference
        /// to the definition of the argument that "contains" these arguments.
        /// </param>
        /// <param name="serviceConfigurer">Optionally provides a service configurer.</param>
        internal ArgumentDefinition(IMutableMemberInfo member,
                                    ArgumentBaseAttribute attribute,
                                    ArgumentSetDefinition argSet,
                                    object defaultValue     = null,
                                    object fixedDestination = null,
                                    ArgumentDefinition containingArgument = null,
                                    ServiceConfigurer serviceConfigurer   = null)
        {
            Member                 = member ?? throw new ArgumentNullException(nameof(member));
            Attribute              = attribute ?? throw new ArgumentNullException(nameof(attribute));
            ContainingSet          = argSet ?? throw new ArgumentNullException(nameof(argSet));
            ContainingArgument     = containingArgument;
            FixedDestination       = fixedDestination;
            IsPositional           = attribute is PositionalArgumentAttribute;
            ArgumentType           = GetArgumentType(Attribute, member, member.MemberType, serviceConfigurer);
            CollectionArgumentType = AsCollectionType(ArgumentType);
            HasDefaultValue        = attribute.ExplicitDefaultValue || attribute.DynamicDefaultValue;
            ValidationAttributes   = GetValidationAttributes(ArgumentType, Member);

            LongName          = GetLongName(attribute, argSet.Attribute, member.MemberInfo);
            ExplicitShortName = HasExplicitShortName(attribute);
            ShortName         = GetShortNameOrNull(attribute, argSet.Attribute, member.MemberInfo);
            DefaultValue      = GetDefaultValue(attribute, member, defaultValue);

            var nullableBase = Nullable.GetUnderlyingType(member.MemberType);

            if (CollectionArgumentType != null)
            {
                ValueType = CollectionArgumentType.ElementType;
            }
            else if (nullableBase != null)
            {
                // For nullable arguments, we use the wrapped type (T in
                // Nullable<T>) as the value type. Parsing an enum or int is the
                // same as parsing an enum? or int?, for example, since null can
                // only arise if the value was not provided at all.
                ValueType = GetArgumentType(Attribute, member, nullableBase, serviceConfigurer);
            }
            else
            {
                ValueType = ArgumentType;
            }

            Debug.Assert(ValueType != null);

            if (Unique && !IsCollection)
            {
                throw new InvalidArgumentSetException(member, Strings.UniqueUsedOnNonCollectionArgument);
            }

            Debug.Assert(!string.IsNullOrEmpty(LongName));
        }
Beispiel #5
0
        /// <summary>
        /// Constructs a new stateful parser for the given argument.
        /// </summary>
        /// <param name="argSet">The argument set containing the argument to be parsed.</param>
        /// <param name="arg">The definition of the argument.</param>
        /// <param name="options">General options for parsing this argument set.</param>
        /// <param name="destination">The destination object into which the parsed result should go,
        /// if so desired; null otherwise to parse without saving results.</param>
        public ArgumentParser(ArgumentSetDefinition argSet, ArgumentDefinition arg, CommandLineParserOptions options,
                              object destination = null)
        {
            ArgumentSet       = argSet ?? throw new ArgumentNullException(nameof(argSet));
            Argument          = arg ?? throw new ArgumentNullException(nameof(arg));
            Reporter          = options?.Reporter ?? (s => { });
            DestinationObject = arg.FixedDestination ?? destination;
            ParseContext      = CreateParseContext(Argument, ArgumentSet.Attribute, options, DestinationObject);

            if (Argument.IsCollection)
            {
                CollectionValues = GenericCollectionFactory.CreateList(Argument.CollectionArgumentType.ElementType.Type);
            }
        }
        /// <summary>
        /// Creates a new command-line argument parser.
        /// </summary>
        /// <param name="type">Destination object type.</param>
        /// <param name="defaultValues">Optionally provides an object with
        /// default values.</param>
        /// <param name="options">Optionally provides additional options
        /// controlling how parsing proceeds.</param>
        public CommandLineParserEngine(Type type, object defaultValues = null, CommandLineParserOptions options = null)
        {
            // Save off the options provided; if none were provided, construct
            // some defaults.
            _options = options?.Clone() ?? new CommandLineParserOptions();

            // If no reporter was provided, use a no-op one.
            if (_options.Reporter == null)
            {
                _options.Reporter = err => { };
            }

            // If no file-system reader was provided, use our default implementation.
            if (_options.FileSystemReader == null)
            {
                _options.FileSystemReader = FileSystemReader.Create();
            }

            // Define the argument set.
            _argumentSet = new ArgumentSetDefinition(type, defaultValues, _options);
        }
Beispiel #7
0
        public static ArgumentSetDefinition CreateArgumentSet(
            Type typeToReflectOn,
            ArgumentSetAttribute attribute      = null,
            object defaultValues                = null,
            object fixedDestination             = null,
            ServiceConfigurer serviceConfigurer = null)
        {
            // Find high-level metadata for the argument set.
            var argSetAttrib = attribute ?? GetSetAttributeOrDefault(typeToReflectOn);

            // Construct an empty definition.
            var argSet = new ArgumentSetDefinition(argSetAttrib);

            // Add arguments.
            AddToArgumentSet(
                argSet,
                typeToReflectOn,
                defaultValues: defaultValues,
                fixedDestination: fixedDestination,
                serviceConfigurer: serviceConfigurer);

            return(argSet);
        }
Beispiel #8
0
        public static void AddToArgumentSet(
            ArgumentSetDefinition argSet,
            Type typeToReflectOn,
            object defaultValues    = null,
            object fixedDestination = null,
            ArgumentDefinition containingArgument = null,
            ServiceConfigurer serviceConfigurer   = null)
        {
            // Extract argument descriptors from the defining type.
            var args = GetArgumentDescriptors(
                typeToReflectOn,
                argSet,
                defaultValues,
                fixedDestination,
                containingArgument,
                serviceConfigurer).ToList();

            // Define the arguments.
            argSet.Add(args);

            // If the provided type we're reflecting on has an ArgumentSetAttribute,
            // then add that as auxiliary information.
            var auxiliaryAttrib = TryGetSetAttribute(typeToReflectOn);

            if (auxiliaryAttrib != null)
            {
                argSet.AddAuxiliaryAttribute(auxiliaryAttrib);
            }

            // If the argument set doesn't already have a default assembly associated
            // with it, then fill that out.
            if (argSet.DefaultAssembly == null)
            {
                argSet.DefaultAssembly = typeToReflectOn.GetTypeInfo().Assembly;
            }
        }
Beispiel #9
0
        private static IEnumerable <ArgumentDefinition> CreateArgumentDescriptorsIfApplicable(IMutableMemberInfo member, object defaultValues,
                                                                                              ArgumentSetDefinition argSet, object fixedDestination, ArgumentDefinition containingArgument, ServiceConfigurer serviceConfigurer)
        {
            var descriptors = Enumerable.Empty <ArgumentDefinition>();

            var argAttrib = member.MemberInfo.GetSingleAttribute <ArgumentBaseAttribute>();

            if (argAttrib != null)
            {
                descriptors = descriptors.Concat(
                    new[]
                {
                    CreateArgumentDescriptor(
                        member,
                        argAttrib,
                        defaultValues,
                        argSet,
                        fixedDestination,
                        containingArgument,
                        serviceConfigurer)
                });
            }

            return(descriptors);
        }
Beispiel #10
0
        private static IEnumerable <ArgumentDefinition> GetArgumentDescriptors(Type type, ArgumentSetDefinition argSet, object defaultValues, object fixedDestination, ArgumentDefinition containingArgument, ServiceConfigurer serviceConfigurer)
        {
            // Find all fields and properties that have argument attributes on
            // them. For each that we find, capture information about them.
            var argList = GetAllFieldsAndProperties(type, includeNonPublicMembers: true)
                          .SelectMany(member => CreateArgumentDescriptorsIfApplicable(member, defaultValues, argSet, fixedDestination, containingArgument, serviceConfigurer));

            // If the argument set attribute indicates that we should also
            // include un-attributed, public, writable members as named
            // arguments, then look for them now.
            if (argSet.Attribute.PublicMembersAreNamedArguments)
            {
                argList = argList.Concat(GetAllFieldsAndProperties(type, includeNonPublicMembers: false)
                                         .Where(member => member.IsWritable)
                                         .Where(member => member.MemberInfo.GetSingleAttribute <ArgumentBaseAttribute>() == null)
                                         .Select(member => CreateArgumentDescriptor(
                                                     member,
                                                     new NamedArgumentAttribute(),
                                                     defaultValues,
                                                     argSet,
                                                     fixedDestination,
                                                     containingArgument,
                                                     serviceConfigurer)));
            }

            return(argList);
        }