public static SpecificationProperty WithSpecification(this SpecificationProperty specProp, Specification newSpecification)
        {
            if (specProp == null) throw new ArgumentNullException("specProp");
            if (newSpecification == null) throw new ArgumentNullException("newSpecification");

            return SpecificationProperty.Create(newSpecification, specProp.Property, specProp.Value);
        }
        public static SpecificationProperty Create(Specification specification, PropertyInfo property, Maybe<object> value)
        {
            if (specification == null) throw new ArgumentNullException("specification");
            if (property == null) throw new ArgumentNullException("property");
            if (value == null) throw new ArgumentNullException("value");

            return new SpecificationProperty(specification, property, value);
        }
 private SpecificationProperty(Specification specification, PropertyInfo property, Maybe<object> value)
 {
     this.property = property;
     this.specification = specification;
     this.value = value;
 }
Esempio n. 4
0
 private static Maybe<Error> MakeErrorInCaseOfMinConstraint(Specification specification)
 {
     return !specification.IsMinNotSpecified()
         ? Maybe.Just<Error>(new SequenceOutOfRangeError(NameInfo.EmptyName))
         : Maybe.Nothing<Error>();
 }
Esempio n. 5
0
        public static ParserResult<T> Build<T>(
            Maybe<Func<T>> factory,
            Func<IEnumerable<string>, IEnumerable<OptionSpecification>, Result<IEnumerable<Token>, Error>> tokenizer,
            IEnumerable<string> arguments,
            StringComparer nameComparer,
            bool ignoreValueCase,
            CultureInfo parsingCulture,
            IEnumerable<ErrorType> nonFatalErrors)
        {
            var typeInfo = factory.MapValueOrDefault(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>();

            Func<T> makeDefault = () =>
                typeof(T).IsMutable()
                    ? factory.MapValueOrDefault(f => f(), Activator.CreateInstance<T>())
                    : ReflectionHelper.CreateDefaultImmutableInstance<T>(
                        (from p in specProps select p.Specification.ConversionType).ToArray());

            Func<IEnumerable<Error>, ParserResult<T>> notParsed =
                errs => new NotParsed<T>(makeDefault().GetType().ToTypeInfo(), errs);

            Func<ParserResult<T>> buildUp = () =>
            {
                var tokenizerResult = tokenizer(arguments, optionSpecs);

                var tokens = tokenizerResult.SucceededWith();

                var partitions = TokenPartitioner.Partition(
                    tokens,
                    name => TypeLookup.FindTypeDescriptorAndSibling(name, optionSpecs, nameComparer));
                var optionsPartition = partitions.Item1;
                var valuesPartition = partitions.Item2;
                var errorsPartition = partitions.Item3;

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

                var valueSpecPropsResult =
                    ValueMapper.MapValues(
                        (from pt in specProps where pt.Specification.IsValue() orderby ((ValueSpecification)pt.Specification).Index select pt),
                        valuesPartition,
                        (vals, type, isScalar) => TypeConverter.ChangeType(vals, type, isScalar, parsingCulture, ignoreValueCase));

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

                var specPropsWithValue =
                    optionSpecPropsResult.SucceededWith().Concat(valueSpecPropsResult.SucceededWith());

                Func<T> buildMutable = () =>
                {
                    var mutable = factory.MapValueOrDefault(f => f(), Activator.CreateInstance<T>());
                    mutable =
                        mutable.SetProperties(specPropsWithValue, sp => sp.Value.IsJust(), sp => sp.Value.FromJustOrFail())
                            .SetProperties(
                                specPropsWithValue,
                                sp => sp.Value.IsNothing() && sp.Specification.DefaultValue.IsJust(),
                                sp => sp.Specification.DefaultValue.FromJustOrFail())
                            .SetProperties(
                                specPropsWithValue,
                                sp =>
                                    sp.Value.IsNothing() && sp.Specification.TargetType == TargetType.Sequence
                                    && sp.Specification.DefaultValue.MatchNothing(),
                                sp => sp.Property.PropertyType.GetTypeInfo().GetGenericArguments().Single().CreateEmptyArray());
                    return mutable;
                };

                Func<T> buildImmutable = () =>
                {
                    var ctor = typeInfo.GetTypeInfo().GetConstructor((from sp in specProps select sp.Property.PropertyType).ToArray());
                    var values = (from prms in ctor.GetParameters()
                        join sp in specPropsWithValue on prms.Name.ToLower() equals sp.Property.Name.ToLower()
                        select
                            sp.Value.GetValueOrDefault(
                                sp.Specification.DefaultValue.GetValueOrDefault(
                                    sp.Specification.ConversionType.CreateDefaultForImmutable()))).ToArray();
                    var immutable = (T)ctor.Invoke(values);
                    return immutable;
                };

                var instance = typeInfo.IsMutable() ? buildMutable() : buildImmutable();
                
                var validationErrors = specPropsWithValue.Validate(SpecificationPropertyRules.Lookup(tokens));

                var allErrors =
                    tokenizerResult.SuccessfulMessages()
                        .Concat(missingValueErrors)
                        .Concat(optionSpecPropsResult.SuccessfulMessages())
                        .Concat(valueSpecPropsResult.SuccessfulMessages())
                        .Concat(validationErrors)
                        .Memorize();

                var warnings = from e in allErrors where nonFatalErrors.Contains(e.Tag) select e;

                return allErrors.Except(warnings).ToParserResult(instance);
            };

            var preprocessorErrors = arguments.Any()
                ? arguments.Preprocess(PreprocessorGuards.Lookup(nameComparer))
                : Enumerable.Empty<Error>();

            var result = arguments.Any()
                ? preprocessorErrors.Any()
                    ? notParsed(preprocessorErrors)
                    : buildUp()
                : buildUp();

            return result;
        }
Esempio n. 6
0
 private static Maybe <Error> MakeErrorInCaseOfMinConstraint(this Specification specification)
 {
     return(specification.Min.IsJust()
         ? Maybe.Just <Error>(new SequenceOutOfRangeError(NameInfo.EmptyName))
         : Maybe.Nothing <Error>());
 }
Esempio n. 7
0
 public static bool IsValue(this Specification specification)
 {
     return(specification.Tag == SpecificationType.Value);
 }
Esempio n. 8
0
 public static bool IsOption(this Specification specification)
 {
     return(specification.Tag == SpecificationType.Option);
 }
Esempio n. 9
0
        public static ParserResult <T> Build <T>(
            Maybe <Func <T> > factory,
            Func <IEnumerable <string>, IEnumerable <OptionSpecification>, Result <IEnumerable <Token>, Error> > tokenizer,
            IEnumerable <string> arguments,
            StringComparer nameComparer,
            bool ignoreValueCase,
            CultureInfo parsingCulture,
            bool autoHelp,
            bool autoVersion,
            bool allowMultiInstance,
            IEnumerable <ErrorType> nonFatalErrors)
        {
            var typeInfo = factory.MapValueOrDefault(f => f().GetType(), typeof(T));

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

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

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

            Func <T> makeDefault = () =>
                                   typeof(T).IsMutable()
                    ? factory.MapValueOrDefault(f => f(), () => Activator.CreateInstance <T>())
                    : ReflectionHelper.CreateDefaultImmutableInstance <T>(
                (from p in specProps select p.Specification.ConversionType).ToArray());

            Func <IEnumerable <Error>, ParserResult <T> > notParsed =
                errs => new NotParsed <T>(makeDefault().GetType().ToTypeInfo(), errs);

            var argumentsList = arguments.Memoize();
            Func <ParserResult <T> > buildUp = () =>
            {
                var tokenizerResult = tokenizer(argumentsList, optionSpecs);

                var tokens = tokenizerResult.SucceededWith().Memoize();

                var partitions = TokenPartitioner.Partition(
                    tokens,
                    name => TypeLookup.FindTypeDescriptorAndSibling(name, optionSpecs, nameComparer));
                var optionsPartition = partitions.Item1.Memoize();
                var valuesPartition  = partitions.Item2.Memoize();
                var errorsPartition  = partitions.Item3.Memoize();

                var optionSpecPropsResult =
                    OptionMapper.MapValues(
                        (from pt in specProps where pt.Specification.IsOption() select pt),
                        optionsPartition,
                        (vals, type, isScalar, isFlag) => TypeConverter.ChangeType(vals, type, isScalar, isFlag, parsingCulture, ignoreValueCase),
                        nameComparer);

                var valueSpecPropsResult =
                    ValueMapper.MapValues(
                        (from pt in specProps where pt.Specification.IsValue() orderby((ValueSpecification)pt.Specification).Index select pt),
                        valuesPartition,
                        (vals, type, isScalar) => TypeConverter.ChangeType(vals, type, isScalar, false, parsingCulture, ignoreValueCase));

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

                var specPropsWithValue =
                    optionSpecPropsResult.SucceededWith().Concat(valueSpecPropsResult.SucceededWith()).Memoize();

                var setPropertyErrors = new List <Error>();

                //build the instance, determining if the type is mutable or not.
                T instance;
                if (typeInfo.IsMutable() == true)
                {
                    instance = BuildMutable(factory, specPropsWithValue, setPropertyErrors);
                }
                else
                {
                    instance = BuildImmutable(typeInfo, factory, specProps, specPropsWithValue, setPropertyErrors);
                }

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

                var allErrors =
                    tokenizerResult.SuccessMessages()
                    .Concat(missingValueErrors)
                    .Concat(optionSpecPropsResult.SuccessMessages())
                    .Concat(valueSpecPropsResult.SuccessMessages())
                    .Concat(validationErrors)
                    .Concat(setPropertyErrors)
                    .Memoize();

                var warnings = from e in allErrors where nonFatalErrors.Contains(e.Tag) select e;

                return(allErrors.Except(warnings).ToParserResult(instance));
            };

            var preprocessorErrors = (
                argumentsList.Any()
                    ? arguments.Preprocess(PreprocessorGuards.Lookup(nameComparer, autoHelp, autoVersion))
                    : Enumerable.Empty <Error>()
                ).Memoize();

            var result = argumentsList.Any()
                ? preprocessorErrors.Any()
                    ? notParsed(preprocessorErrors)
                    : buildUp()
                : buildUp();

            return(result);
        }
        public static SpecificationProperty WithSpecification(this SpecificationProperty specProp, Specification newSpecification)
        {
            if (newSpecification == null)
            {
                throw new ArgumentNullException("newSpecification");
            }

            return(SpecificationProperty.Create(newSpecification, specProp.Property, specProp.Value));
        }