44 Func<IEnumerable<string>, IEnumerable<OptionSpecification>,
46 IEnumerable<string> arguments,
47 StringComparer nameComparer,
49 CultureInfo parsingCulture,
52 bool allowMultiInstance,
53 IEnumerable<ErrorType> nonFatalErrors)
55 Type typeInfo = factory.MapValueOrDefault(f => f()
60 IEnumerable<SpecificationProperty> specProps = typeInfo
61 .GetSpecifications(pi =>
66 Maybe.Nothing<
object>()
71 IEnumerable<Specification> specs = from pt in specProps select pt.Specification;
73 IEnumerable<OptionSpecification> optionSpecs = specs
78 Func<T> makeDefault = () =>
80 ? factory.MapValueOrDefault(f => f(), () => Activator.CreateInstance<T>())
82 select p.Specification.ConversionType)
93 IEnumerable<string> argumentsList = arguments.Memoize();
95 Func<ParserResult<T>> buildUp = () =>
99 IEnumerable<Token> tokens = tokenizerResult.SucceededWith()
102 Tuple<IEnumerable<KeyValuePair<string, IEnumerable<string>>>, IEnumerable<string>, IEnumerable<Token>>
110 IEnumerable<KeyValuePair<string, IEnumerable<string>>> optionsPartition = partitions.Item1.Memoize();
111 IEnumerable<string> valuesPartition = partitions.Item2.Memoize();
112 IEnumerable<Token> errorsPartition = partitions.Item3.Memoize();
117 (vals, type, isScalar, isFlag) =>
130 where pt.Specification.IsValue()
134 (vals, type, isScalar) =>
144 IEnumerable<MissingValueOptionError> missingValueErrors = from token in errorsPartition
155 .FromOptionSpecification()
158 IEnumerable<SpecificationProperty> specPropsWithValue =
159 optionSpecPropsResult.SucceededWith()
160 .Concat(valueSpecPropsResult.SucceededWith())
163 List<Error> setPropertyErrors =
new List<Error>();
168 if (typeInfo.IsMutable())
170 instance = BuildMutable(factory, specPropsWithValue, setPropertyErrors);
174 instance = BuildImmutable(typeInfo, factory, specProps, specPropsWithValue, setPropertyErrors);
177 IEnumerable<Error> validationErrors =
180 IEnumerable<Error> allErrors =
181 tokenizerResult.SuccessMessages()
182 .Concat(missingValueErrors)
183 .Concat(optionSpecPropsResult.SuccessMessages())
184 .Concat(valueSpecPropsResult.SuccessMessages())
185 .Concat(validationErrors)
186 .Concat(setPropertyErrors)
189 IEnumerable<Error> warnings = from e in allErrors where nonFatalErrors.Contains(e.Tag) select e;
191 return allErrors.Except(warnings)
192 .ToParserResult(instance);
195 IEnumerable<Error> preprocessorErrors = (
198 .Lookup(nameComparer, autoHelp, autoVersion)
200 : Enumerable.Empty<
Error>()
204 ? preprocessorErrors.Any()
205 ? notParsed(preprocessorErrors)
213 IEnumerable<SpecificationProperty> specPropsWithValue,
214 List<Error> setPropertyErrors)
216 T
mutable = factory.MapValueOrDefault(f => f(), () => Activator.CreateInstance<T>());
218 setPropertyErrors.AddRange(
mutable.SetProperties(specPropsWithValue,
219 sp => sp.Value.IsJust(),
220 sp => sp.Value.FromJustOrFail()
224 setPropertyErrors.AddRange(
mutable.SetProperties(specPropsWithValue,
225 sp => sp.Value.IsNothing() &&
226 sp.Specification.DefaultValue.IsJust(),
227 sp => sp.Specification.DefaultValue.FromJustOrFail()
231 setPropertyErrors.AddRange(
mutable.SetProperties(specPropsWithValue,
232 sp => sp.Value.IsNothing() &&
233 sp.Specification.TargetType ==
TargetType.Sequence &&
234 sp.Specification.DefaultValue.MatchNothing(),
235 sp => sp.Property.PropertyType.GetTypeInfo()
236 .GetGenericArguments()
246 Maybe<Func<T>> factory,
247 IEnumerable<SpecificationProperty> specProps,
248 IEnumerable<SpecificationProperty> specPropsWithValue,
249 List<Error> setPropertyErrors)
251 ConstructorInfo ctor = typeInfo.GetTypeInfo()
252 .GetConstructor(specProps.Select(sp => sp.Property.PropertyType)
259 InvalidOperationException($
"Type {typeInfo.FullName} appears to be immutable, but no constructor found to accept values."
266 (from prms in ctor.GetParameters()
267 join sp in specPropsWithValue on prms.Name.ToLower() equals sp.Property.Name.ToLower() into spv
268 from sp in spv.DefaultIfEmpty()
271 ? specProps.First(s =>
string.Equals(s.Property.Name,
273 StringComparison.CurrentCultureIgnoreCase
276 .Property.PropertyType.GetDefaultValue()
277 : sp.Value.GetValueOrDefault(sp.Specification.DefaultValue
278 .GetValueOrDefault(sp.Specification.ConversionType
279 .CreateDefaultForImmutable()
283 T immutable = (T)ctor.Invoke(values);
289 string[] ctorArgs = specPropsWithValue
290 .Select(x => x.Property.Name.ToLowerInvariant())
293 throw GetException(ctorArgs);
296 Exception GetException(
string[] s)
298 string ctorSyntax = s !=
null
299 ?
" Constructor Parameters can be ordered as: " + $
"'({string.Join(",
", s)})'"
303 $
"Type {typeInfo.FullName} appears to be Immutable with invalid constructor. Check that constructor arguments have the same name and order of their underlying Type. {ctorSyntax}";
304 InvalidOperationException invalidOperationException =
new InvalidOperationException(msg);
306 return invalidOperationException;