@@ -7,32 +7,26 @@ namespace AutoMapper.Execution;
77public static class ExpressionBuilder
88{
99 public static readonly MethodInfo ObjectToString = typeof ( object ) . GetMethod ( nameof ( object . ToString ) ) ;
10- private static readonly MethodInfo DisposeMethod = typeof ( IDisposable ) . GetMethod ( nameof ( IDisposable . Dispose ) ) ;
1110 public static readonly Expression True = Constant ( true , typeof ( bool ) ) ;
12- public static readonly Expression Null = Constant ( null , typeof ( object ) ) ;
11+ public static readonly Expression Null = Expression . Default ( typeof ( object ) ) ;
1312 public static readonly Expression Empty = Empty ( ) ;
14- public static readonly LambdaExpression EmptyLambda = Expression . Lambda ( Empty ) ;
15- public static readonly Expression Zero = Constant ( 0 , typeof ( int ) ) ;
13+ public static readonly Expression Zero = Expression . Default ( typeof ( int ) ) ;
1614 public static readonly ParameterExpression ExceptionParameter = Parameter ( typeof ( Exception ) , "ex" ) ;
1715 public static readonly ParameterExpression ContextParameter = Parameter ( typeof ( ResolutionContext ) , "context" ) ;
1816 public static readonly MethodInfo IListClear = typeof ( IList ) . GetMethod ( nameof ( IList . Clear ) ) ;
19- public static readonly MethodInfo IListAdd = typeof ( IList ) . GetMethod ( nameof ( IList . Add ) ) ;
20- public static readonly MethodInfo IncTypeDepthInfo = typeof ( ResolutionContext ) . GetInstanceMethod ( nameof ( ResolutionContext . IncrementTypeDepth ) ) ;
21- public static readonly MethodInfo DecTypeDepthInfo = typeof ( ResolutionContext ) . GetInstanceMethod ( nameof ( ResolutionContext . DecrementTypeDepth ) ) ;
22- private static readonly MethodInfo ContextCreate = typeof ( ResolutionContext ) . GetInstanceMethod ( nameof ( ResolutionContext . CreateInstance ) ) ;
23- public static readonly MethodInfo OverTypeDepthMethod = typeof ( ResolutionContext ) . GetInstanceMethod ( nameof ( ResolutionContext . OverTypeDepth ) ) ;
24- public static readonly MethodInfo CacheDestinationMethod = typeof ( ResolutionContext ) . GetInstanceMethod ( nameof ( ResolutionContext . CacheDestination ) ) ;
25- public static readonly MethodInfo GetDestinationMethod = typeof ( ResolutionContext ) . GetInstanceMethod ( nameof ( ResolutionContext . GetDestination ) ) ;
26- private static readonly MethodCallExpression CheckContextCall = Expression . Call (
17+ static readonly MethodInfo ContextCreate = typeof ( ResolutionContext ) . GetInstanceMethod ( nameof ( ResolutionContext . CreateInstance ) ) ;
18+ static readonly MethodInfo OverTypeDepthMethod = typeof ( ResolutionContext ) . GetInstanceMethod ( nameof ( ResolutionContext . OverTypeDepth ) ) ;
19+ static readonly MethodCallExpression CheckContextCall = Expression . Call (
2720 typeof ( ResolutionContext ) . GetStaticMethod ( nameof ( ResolutionContext . CheckContext ) ) , ContextParameter ) ;
28- private static readonly MethodInfo ContextMapMethod = typeof ( ResolutionContext ) . GetInstanceMethod ( nameof ( ResolutionContext . MapInternal ) ) ;
29- private static readonly MethodInfo ArrayEmptyMethod = typeof ( Array ) . GetStaticMethod ( nameof ( Array . Empty ) ) ;
30- private static readonly ParameterExpression Disposable = Variable ( typeof ( IDisposable ) , "disposableEnumerator" ) ;
31- private static readonly ReadOnlyCollection < ParameterExpression > DisposableArray = Disposable . ToReadOnly ( ) ;
32- private static readonly Expression DisposeCall = IfThen ( ReferenceNotEqual ( Disposable , Null ) , Expression . Call ( Disposable , DisposeMethod ) ) ;
33- private static readonly ParameterExpression Index = Variable ( typeof ( int ) , "sourceArrayIndex" ) ;
34- private static readonly BinaryExpression ResetIndex = Assign ( Index , Zero ) ;
35- private static readonly UnaryExpression IncrementIndex = PostIncrementAssign ( Index ) ;
21+ static readonly MethodInfo ContextMapMethod = typeof ( ResolutionContext ) . GetInstanceMethod ( nameof ( ResolutionContext . MapInternal ) ) ;
22+ static readonly MethodInfo ArrayEmptyMethod = typeof ( Array ) . GetStaticMethod ( nameof ( Array . Empty ) ) ;
23+ static readonly ParameterExpression Disposable = Variable ( typeof ( IDisposable ) , "disposableEnumerator" ) ;
24+ static readonly ReadOnlyCollection < ParameterExpression > DisposableArray = Disposable . ToReadOnly ( ) ;
25+ static readonly MethodInfo DisposeMethod = typeof ( IDisposable ) . GetMethod ( nameof ( IDisposable . Dispose ) ) ;
26+ static readonly Expression DisposeCall = IfThen ( ReferenceNotEqual ( Disposable , Null ) , Expression . Call ( Disposable , DisposeMethod ) ) ;
27+ static readonly ParameterExpression Index = Variable ( typeof ( int ) , "sourceArrayIndex" ) ;
28+ static readonly BinaryExpression ResetIndex = Assign ( Index , Zero ) ;
29+ static readonly UnaryExpression IncrementIndex = PostIncrementAssign ( Index ) ;
3630 public static Expression ReplaceParameters ( this IGlobalConfiguration configuration , LambdaExpression initialLambda , Expression newParameter ) =>
3731 configuration . ParameterReplaceVisitor ( ) . Replace ( initialLambda , newParameter ) ;
3832 public static Expression ReplaceParameters ( this IGlobalConfiguration configuration , LambdaExpression initialLambda , Expression [ ] newParameters ) =>
@@ -103,7 +97,7 @@ public static Expression MapExpression(this IGlobalConfiguration configuration,
10397 mapExpression ??= ContextMap ( typePair , source , destination , memberMap ) ;
10498 return nullCheck ? configuration . NullCheckSource ( profileMap , source , destination , mapExpression , memberMap ) : mapExpression ;
10599 }
106- public static Expression NullCheckSource ( this IGlobalConfiguration configuration , ProfileMap profileMap , Expression source , Expression destination ,
100+ public static Expression NullCheckSource ( this IGlobalConfiguration configuration , ProfileMap profileMap , Expression source , Expression destination ,
107101 Expression mapExpression , MemberMap memberMap )
108102 {
109103 var sourceType = source . Type ;
@@ -114,7 +108,7 @@ public static Expression NullCheckSource(this IGlobalConfiguration configuration
114108 var destinationType = destination . Type ;
115109 var isCollection = destinationType . IsCollection ( ) ;
116110 var mustUseDestination = memberMap is { MustUseDestination : true } ;
117- var ifSourceNull = memberMap == null ?
111+ var ifSourceNull = memberMap == null ?
118112 destination . IfNullElse ( DefaultDestination ( ) , ClearDestinationCollection ( ) ) :
119113 mustUseDestination ? ClearDestinationCollection ( ) : DefaultDestination ( ) ;
120114 return source . IfNullElse ( ifSourceNull , mapExpression ) ;
@@ -176,32 +170,29 @@ public static Expression ContextMap(TypePair typePair, Expression sourceParamete
176170 var mapMethod = ContextMapMethod . MakeGenericMethod ( typePair . SourceType , typePair . DestinationType ) ;
177171 return Expression . Call ( ContextParameter , mapMethod , sourceParameter , destinationParameter , Constant ( memberMap , typeof ( MemberMap ) ) ) ;
178172 }
179- public static Expression CheckContext ( TypeMap typeMap )
180- {
181- if ( typeMap . MaxDepth > 0 || typeMap . PreserveReferences )
182- {
183- return CheckContextCall ;
184- }
185- return null ;
186- }
187- public static Expression OverMaxDepth ( TypeMap typeMap ) => typeMap ? . MaxDepth > 0 ? Expression . Call ( ContextParameter , OverTypeDepthMethod , Constant ( typeMap ) ) : null ;
173+ public static Expression CheckContext ( TypeMap typeMap ) => typeMap . PreserveReferences || typeMap . MaxDepth > 0 ? CheckContextCall : null ;
174+ public static Expression OverMaxDepth ( TypeMap typeMap ) => typeMap ? . MaxDepth > 0 ?
175+ Expression . Call ( ContextParameter , OverTypeDepthMethod , Constant ( typeMap ) ) : null ;
188176 public static Expression NullSubstitute ( this MemberMap memberMap , Expression sourceExpression ) =>
189177 Coalesce ( sourceExpression , ToType ( Constant ( memberMap . NullSubstitute ) , sourceExpression . Type ) ) ;
190178 public static Expression ApplyTransformers ( this MemberMap memberMap , Expression source , IGlobalConfiguration configuration )
191179 {
192180 var perMember = memberMap . ValueTransformers ;
193181 var perMap = memberMap . TypeMap . ValueTransformers ;
194- var perProfile = memberMap . TypeMap . Profile . ValueTransformers ;
195- if ( perMember . Count == 0 && perMap . Count == 0 && perProfile . Count == 0 )
182+ var perProfile = memberMap . Profile . ValueTransformers ;
183+ var result = source ;
184+ if ( perMember . Count > 0 || perMap . Count > 0 || perProfile . Count > 0 )
196185 {
197- return source ;
186+ foreach ( var transformer in perMember . Concat ( perMap ) . Concat ( perProfile ) )
187+ {
188+ if ( transformer . IsMatch ( memberMap ) )
189+ {
190+ result = ToType ( configuration . ReplaceParameters ( transformer . TransformerExpression , ToType ( result , transformer . ValueType ) ) , memberMap . DestinationType ) ;
191+ }
192+ }
198193 }
199- var transformers = perMember . Concat ( perMap ) . Concat ( perProfile ) ;
200- return memberMap . ApplyTransformers ( source , configuration , transformers ) ;
194+ return result ;
201195 }
202- static Expression ApplyTransformers ( this MemberMap memberMap , Expression source , IGlobalConfiguration configuration , IEnumerable < ValueTransformerConfiguration > transformers ) =>
203- transformers . Where ( vt => vt . IsMatch ( memberMap ) ) . Aggregate ( source , ( current , vtConfig ) =>
204- ToType ( configuration . ReplaceParameters ( vtConfig . TransformerExpression , ToType ( current , vtConfig . ValueType ) ) , memberMap . DestinationType ) ) ;
205196 public static LambdaExpression Lambda ( this MemberInfo member ) => new [ ] { member } . Lambda ( ) ;
206197 public static LambdaExpression Lambda ( this MemberInfo [ ] members )
207198 {
0 commit comments