private static ParserResult <object> MatchVerb(
     Func <IEnumerable <string>, IEnumerable <OptionSpecification>, StatePair <IEnumerable <Token> > > tokenizer,
     IEnumerable <Tuple <Verb, Type> > verbs,
     IEnumerable <string> arguments,
     StringComparer nameComparer,
     CultureInfo parsingCulture)
 {
     return(verbs.Any(a => nameComparer.Equals(a.Item1.Name, arguments.First()))
         ? InstanceBuilder.Build(
                () => Activator.CreateInstance(verbs.Single(v => nameComparer.Equals(v.Item1.Name, arguments.First())).Item2),
                tokenizer,
                arguments.Skip(1),
                nameComparer,
                parsingCulture)
         : ParserResult.Create <object>(
                ParserResultType.Verbs,
                new NullInstance(),
                new[] { new BadVerbSelectedError(arguments.First()) },
                Maybe.Just(verbs.Select(v => v.Item2))));
 }
        public void Explicit_help_request_generates_help_requested_error()
        {
            // Fixture setup
            var fakeOptions    = new FakeOptions();
            var expectedResult = ParserResult.Create(
                ParserResultType.Options,
                fakeOptions, new Error[] { new HelpRequestedError() });

            // Exercize system
            var result = InstanceBuilder.Build(
                Maybe.Just <Func <FakeOptions> >(() => fakeOptions),
                new[] { "--help" },
                StringComparer.Ordinal,
                CultureInfo.InvariantCulture);

            // Verify outcome
            Assert.True(expectedResult.Equals(result));

            // Teardown
        }
        public static ParserResult <object> Choose(
            Func <IEnumerable <string>, IEnumerable <OptionSpecification>, StatePair <IEnumerable <Token> > > tokenizer,
            IEnumerable <Type> types,
            IEnumerable <string> arguments,
            StringComparer nameComparer,
            CultureInfo parsingCulture)
        {
            var verbs = Verb.SelectFromTypes(types);

            return(arguments.Empty()
                ? ParserResult.Create <object>(
                       ParserResultType.Verbs, new NullInstance(), new[] { new NoVerbSelectedError() }, Maybe.Just(types))
                : nameComparer.Equals("help", arguments.First())
                   ? ParserResult.Create <object>(
                       ParserResultType.Verbs,
                       new NullInstance(), new[] { CreateHelpVerbRequestedError(
                                                       verbs,
                                                       arguments.Skip(1).SingleOrDefault() ?? string.Empty,
                                                       nameComparer) }, Maybe.Just(types))
                   : MatchVerb(tokenizer, verbs, arguments, nameComparer, parsingCulture));
        }
示例#4
0
        /// <summary>
        /// Creates a new instance of the <see cref="CommandLine.Text.HelpText"/> class,
        /// automatically handling verbs or options scenario.
        /// </summary>
        /// <param name='parserResult'>The <see cref="CommandLine.ParserResult{T}"/> containing the instance that collected command line arguments parsed with <see cref="CommandLine.Parser"/> class.</param>
        /// <returns>
        /// An instance of <see cref="CommandLine.Text.HelpText"/> class.
        /// </returns>
        /// <remarks>This feature is meant to be invoked automatically by the parser, setting the HelpWriter property
        /// of <see cref="CommandLine.ParserSettings"/>.</remarks>
        public static HelpText AutoBuild <T>(ParserResult <T> parserResult)
        {
            switch (parserResult.Tag)
            {
            case ParserResultType.Options:
                return(HelpText.AutoBuild(parserResult, current => HelpText.DefaultParsingErrorsHandler(parserResult, current)));

            case ParserResultType.Verbs:
                var helpVerbErr = parserResult.Errors.OfType <HelpVerbRequestedError>();
                if (helpVerbErr.Any())
                {
                    var err = helpVerbErr.Single();
                    if (err.Matched)
                    {
                        var pr = ParserResult.Create(ParserResultType.Options, Activator.CreateInstance(err.Type), Enumerable.Empty <Error>());
                        return(HelpText.AutoBuild(pr, current => HelpText.DefaultParsingErrorsHandler(pr, current)));
                    }
                }
                return(HelpText.AutoBuild(parserResult, current => HelpText.DefaultParsingErrorsHandler(parserResult, current), true));

            default:
                throw new InvalidOperationException();
            }
        }
示例#5
0
        public static ParserResult <T> Build <T>(
            Func <T> factory,
            Func <IEnumerable <string>, IEnumerable <OptionSpecification>, StatePair <IEnumerable <Token> > > tokenizer,
            IEnumerable <string> arguments,
            StringComparer nameComparer,
            CultureInfo parsingCulture)
        {
            var instance = factory();

            if (arguments.Any() && nameComparer.Equals("--help", arguments.First()))
            {
                return(ParserResult.Create(
                           ParserResultType.Options,
                           instance,
                           new[] { new HelpRequestedError() }));
            }

            var specProps = instance.GetType().GetSpecifications(pi => SpecificationProperty.Create(
                                                                     Specification.FromProperty(pi), pi, Maybe.Nothing <object>()));

            var optionSpecs = (from pt in specProps select pt.Specification)
                              .ThrowingValidate(SpecificationGuards.Lookup)
                              .OfType <OptionSpecification>();

            var tokenizerResult = tokenizer(arguments, optionSpecs);

            var tokens = tokenizerResult.Value;

            var partitions = TokenPartitioner.Partition(
                tokens,
                name => TypeLookup.GetDescriptorInfo(name, optionSpecs, nameComparer));

            var optionSpecProps = OptionMapper.MapValues(
                (from pt in specProps where pt.Specification.IsOption() select pt),
                partitions.Item1,
                (vals, type, isScalar) => TypeConverter.ChangeType(vals, type, isScalar, parsingCulture),
                nameComparer);

            var valueSpecProps = ValueMapper.MapValues(
                (from pt in specProps where pt.Specification.IsValue() select pt),
                partitions.Item2,
                (vals, type, isScalar) => TypeConverter.ChangeType(vals, type, isScalar, parsingCulture));

            var missingValueErrors = from token in partitions.Item3
                                     select new MissingValueOptionError(
                NameInfo.FromOptionSpecification(optionSpecs.Single(o => token.Text.MatchName(o.ShortName, o.LongName, nameComparer))));

            var specPropsWithValue = optionSpecProps.Value.Concat(valueSpecProps.Value);

            instance = instance
                       .SetProperties(specPropsWithValue,
                                      sp => sp.Value.IsJust(),
                                      sp => sp.Value.FromJust())
                       .SetProperties(specPropsWithValue,
                                      sp => sp.Value.IsNothing() && sp.Specification.DefaultValue.IsJust(),
                                      sp => sp.Specification.DefaultValue.FromJust())
                       .SetProperties(specPropsWithValue,
                                      sp => sp.Value.IsNothing() &&
                                      sp.Specification.ConversionType.ToDescriptor() == DescriptorType.Sequence &&
                                      sp.Specification.DefaultValue.MatchNothing(),
                                      sp => sp.Property.PropertyType.GetGenericArguments().Single().CreateEmptyArray());

            var validationErrors = specPropsWithValue.Validate(SpecificationPropertyRules.Lookup)
                                   .OfType <Just <Error> >().Select(e => e.Value);

            return(ParserResult.Create(
                       ParserResultType.Options,
                       instance,
                       tokenizerResult.Errors
                       .Concat(missingValueErrors)
                       .Concat(optionSpecProps.Errors)
                       .Concat(valueSpecProps.Errors)
                       .Concat(validationErrors)));
        }
示例#6
0
        public static ParserResult <T> Build <T>(
            Maybe <Func <T> > factory,
            Func <IEnumerable <string>, IEnumerable <OptionSpecification>, StatePair <IEnumerable <Token> > > tokenizer,
            IEnumerable <string> arguments,
            StringComparer nameComparer,
            CultureInfo parsingCulture)
        {
            var typeInfo = factory.Return(f => f().GetType(), typeof(T));

            var specProps = typeInfo.GetSpecifications(pi => SpecificationProperty.Create(
                                                           Specification.FromProperty(pi), pi, Maybe.Nothing <object>()));

            var specs = from pt in specProps select pt.Specification;

            var optionSpecs = specs
                              .ThrowingValidate(SpecificationGuards.Lookup)
                              .OfType <OptionSpecification>();

            if (arguments.Any() && nameComparer.Equals("--help", arguments.First()))
            {
                return(ParserResult.Create(
                           ParserResultType.Options,
                           factory.Return(f => f(), default(T)),
                           new[] { new HelpRequestedError() }));
            }

            var tokenizerResult = tokenizer(arguments, optionSpecs);

            var tokens = tokenizerResult.Value;

            var partitions = TokenPartitioner.Partition(
                tokens,
                name => TypeLookup.FindTypeDescriptorAndSibling(name, optionSpecs, nameComparer));

            var optionSpecProps = OptionMapper.MapValues(
                (from pt in specProps where pt.Specification.IsOption() select pt),
                partitions.Options,
                (vals, type, isScalar) => TypeConverter.ChangeType(vals, type, isScalar, parsingCulture),
                nameComparer);

            var valueSpecProps = ValueMapper.MapValues(
                (from pt in specProps where pt.Specification.IsValue() select pt),
                partitions.Values,
                (vals, type, isScalar) => TypeConverter.ChangeType(vals, type, isScalar, parsingCulture));

            var missingValueErrors = from token in partitions.Errors
                                     select new MissingValueOptionError(
                optionSpecs.Single(o => token.Text.MatchName(o.ShortName, o.LongName, nameComparer)).FromOptionSpecification());

            var specPropsWithValue = optionSpecProps.Value.Concat(valueSpecProps.Value);

            T instance;

            if (ReflectionHelper.IsTypeMutable(typeInfo))
            {
                instance = factory.Return(f => f(), Activator.CreateInstance <T>());
                instance = instance
                           .SetProperties(specPropsWithValue,
                                          sp => sp.Value.IsJust(),
                                          sp => sp.Value.FromJust())
                           .SetProperties(specPropsWithValue,
                                          sp => sp.Value.IsNothing() && sp.Specification.DefaultValue.IsJust(),
                                          sp => sp.Specification.DefaultValue.FromJust())
                           .SetProperties(specPropsWithValue,
                                          sp => sp.Value.IsNothing() &&
                                          sp.Specification.TargetType == TargetType.Sequence &&
                                          sp.Specification.DefaultValue.MatchNothing(),
                                          sp => sp.Property.PropertyType.GetGenericArguments().Single().CreateEmptyArray());
            }
            else
            {
                var t      = typeof(T);
                var ctor   = t.GetConstructor((from p in specProps select p.Specification.ConversionType).ToArray());
                var values = (from prms in ctor.GetParameters()
                              join sp in specPropsWithValue on prms.Name.ToLower() equals sp.Property.Name.ToLower()
                              select sp.Value.Return(v => v,
                                                     sp.Specification.DefaultValue.Return(d => d,
                                                                                          sp.Specification.ConversionType.CreateDefaultForImmutable()))).ToArray();
                instance = (T)ctor.Invoke(values);
            }

            var validationErrors = specPropsWithValue.Validate(
                SpecificationPropertyRules.Lookup(tokens));

            return(ParserResult.Create(
                       ParserResultType.Options,
                       instance,
                       tokenizerResult.Errors
                       .Concat(missingValueErrors)
                       .Concat(optionSpecProps.Errors)
                       .Concat(valueSpecProps.Errors)
                       .Concat(validationErrors)));
        }