@@ -20,18 +20,22 @@ public static ParserResult<T> Build<T>(
2020 StringComparer nameComparer ,
2121 bool ignoreValueCase ,
2222 CultureInfo parsingCulture ,
23+ bool autoHelp ,
24+ bool autoVersion ,
2325 IEnumerable < ErrorType > nonFatalErrors )
2426 {
2527 var typeInfo = factory . MapValueOrDefault ( f => f ( ) . GetType ( ) , typeof ( T ) ) ;
2628
2729 var specProps = typeInfo . GetSpecifications ( pi => SpecificationProperty . Create (
28- Specification . FromProperty ( pi ) , pi , Maybe . Nothing < object > ( ) ) ) ;
30+ Specification . FromProperty ( pi ) , pi , Maybe . Nothing < object > ( ) ) )
31+ . Memorize ( ) ;
2932
3033 var specs = from pt in specProps select pt . Specification ;
3134
3235 var optionSpecs = specs
3336 . ThrowingValidate ( SpecificationGuards . Lookup )
34- . OfType < OptionSpecification > ( ) ;
37+ . OfType < OptionSpecification > ( )
38+ . Memorize ( ) ;
3539
3640 Func < T > makeDefault = ( ) =>
3741 typeof ( T ) . IsMutable ( )
@@ -42,18 +46,19 @@ public static ParserResult<T> Build<T>(
4246 Func < IEnumerable < Error > , ParserResult < T > > notParsed =
4347 errs => new NotParsed < T > ( makeDefault ( ) . GetType ( ) . ToTypeInfo ( ) , errs ) ;
4448
49+ var argumentsList = arguments . Memorize ( ) ;
4550 Func < ParserResult < T > > buildUp = ( ) =>
4651 {
47- var tokenizerResult = tokenizer ( arguments , optionSpecs ) ;
52+ var tokenizerResult = tokenizer ( argumentsList , optionSpecs ) ;
4853
49- var tokens = tokenizerResult . SucceededWith ( ) ;
54+ var tokens = tokenizerResult . SucceededWith ( ) . Memorize ( ) ;
5055
5156 var partitions = TokenPartitioner . Partition (
5257 tokens ,
5358 name => TypeLookup . FindTypeDescriptorAndSibling ( name , optionSpecs , nameComparer ) ) ;
54- var optionsPartition = partitions . Item1 ;
55- var valuesPartition = partitions . Item2 ;
56- var errorsPartition = partitions . Item3 ;
59+ var optionsPartition = partitions . Item1 . Memorize ( ) ;
60+ var valuesPartition = partitions . Item2 . Memorize ( ) ;
61+ var errorsPartition = partitions . Item3 . Memorize ( ) ;
5762
5863 var optionSpecPropsResult =
5964 OptionMapper . MapValues (
@@ -65,7 +70,7 @@ public static ParserResult<T> Build<T>(
6570 var valueSpecPropsResult =
6671 ValueMapper . MapValues (
6772 ( from pt in specProps where pt . Specification . IsValue ( ) orderby ( ( ValueSpecification ) pt . Specification ) . Index select pt ) ,
68- valuesPartition ,
73+ valuesPartition ,
6974 ( vals , type , isScalar ) => TypeConverter . ChangeType ( vals , type , isScalar , parsingCulture , ignoreValueCase ) ) ;
7075
7176 var missingValueErrors = from token in errorsPartition
@@ -75,7 +80,7 @@ public static ParserResult<T> Build<T>(
7580 . FromOptionSpecification ( ) ) ;
7681
7782 var specPropsWithValue =
78- optionSpecPropsResult . SucceededWith ( ) . Concat ( valueSpecPropsResult . SucceededWith ( ) ) ;
83+ optionSpecPropsResult . SucceededWith ( ) . Concat ( valueSpecPropsResult . SucceededWith ( ) ) . Memorize ( ) ;
7984
8085 var setPropertyErrors = new List < Error > ( ) ;
8186
@@ -100,9 +105,13 @@ public static ParserResult<T> Build<T>(
100105 {
101106 var ctor = typeInfo . GetTypeInfo ( ) . GetConstructor ( ( from sp in specProps select sp . Property . PropertyType ) . ToArray ( ) ) ;
102107 var values = ( from prms in ctor . GetParameters ( )
103- join sp in specPropsWithValue on prms . Name . ToLower ( ) equals sp . Property . Name . ToLower ( )
108+ join sp in specPropsWithValue on prms . Name . ToLower ( ) equals sp . Property . Name . ToLower ( ) into spv
109+ from sp in spv . DefaultIfEmpty ( )
104110 select
105- sp . Value . GetValueOrDefault (
111+ sp == null
112+ ? specProps . First ( s => String . Equals ( s . Property . Name , prms . Name , StringComparison . CurrentCultureIgnoreCase ) )
113+ . Property . PropertyType . GetDefaultValue ( )
114+ : sp . Value . GetValueOrDefault (
106115 sp . Specification . DefaultValue . GetValueOrDefault (
107116 sp . Specification . ConversionType . CreateDefaultForImmutable ( ) ) ) ) . ToArray ( ) ;
108117 var immutable = ( T ) ctor . Invoke ( values ) ;
@@ -127,11 +136,13 @@ join sp in specPropsWithValue on prms.Name.ToLower() equals sp.Property.Name.ToL
127136 return allErrors . Except ( warnings ) . ToParserResult ( instance ) ;
128137 } ;
129138
130- var preprocessorErrors = arguments . Any ( )
131- ? arguments . Preprocess ( PreprocessorGuards . Lookup ( nameComparer ) )
132- : Enumerable . Empty < Error > ( ) ;
139+ var preprocessorErrors = (
140+ argumentsList . Any ( )
141+ ? arguments . Preprocess ( PreprocessorGuards . Lookup ( nameComparer , autoHelp , autoVersion ) )
142+ : Enumerable . Empty < Error > ( )
143+ ) . Memorize ( ) ;
133144
134- var result = arguments . Any ( )
145+ var result = argumentsList . Any ( )
135146 ? preprocessorErrors . Any ( )
136147 ? notParsed ( preprocessorErrors )
137148 : buildUp ( )
0 commit comments