public static SpecificationProperty WithValue(this SpecificationProperty specProp, Maybe <object> newValue) { if (newValue == null) { throw new ArgumentNullException(nameof(newValue)); } return(SpecificationProperty.Create(specProp.Specification, specProp.Property, newValue)); }
public static SpecificationProperty WithSpecification(this SpecificationProperty specProp, Specification newSpecification) { if (newSpecification == null) { throw new ArgumentNullException(nameof(newSpecification)); } return(SpecificationProperty.Create(newSpecification, specProp.Property, specProp.Value)); }
public static Type GetConversionType(this SpecificationProperty specProp) { switch (specProp.Specification.TargetType) { case TargetType.Sequence: return(specProp.Property.PropertyType.GetTypeInfo().GetGenericArguments() .SingleOrDefault() .ToMaybe() .FromJustOrFail( new InvalidOperationException("Sequence properties should be of type IEnumerable<T>."))); default: return(specProp.Property.PropertyType); } }
private static IEnumerable <Error> SetValue <T>(this SpecificationProperty specProp, T instance, object value) { try { specProp.Property.SetValue(instance, value, null); return(Enumerable.Empty <Error>()); } catch (TargetInvocationException e) { return(new[] { new SetValueExceptionError(specProp.Specification.FromSpecification(), e.InnerException, value) }); } catch (ArgumentException e) { var argEx = new ArgumentException(InvalidAttributeConfigurationError.ErrorMessage, e); return(new[] { new SetValueExceptionError(specProp.Specification.FromSpecification(), argEx, value) }); } catch (Exception e) { return(new[] { new SetValueExceptionError(specProp.Specification.FromSpecification(), e, value) }); } }
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, 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) => 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()).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)); 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); }