Skip to content

Commit 8f40b61

Browse files
authored
Merge pull request #43 from BlaiseD/master
Code cleanup for VisitMember.
2 parents 4f422cf + 7a619f9 commit 8f40b61

File tree

6 files changed

+120
-103
lines changed

6 files changed

+120
-103
lines changed

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<PropertyGroup>
33
<Authors>Jimmy Bogard</Authors>
44
<LangVersion>latest</LangVersion>
5-
<VersionPrefix>3.0.2-preview01</VersionPrefix>
5+
<VersionPrefix>3.0.2-preview02</VersionPrefix>
66
<WarningsAsErrors>true</WarningsAsErrors>
77
<NoWarn>$(NoWarn);1701;1702;1591</NoWarn>
88
</PropertyGroup>

src/AutoMapper.Extensions.ExpressionMapping/MapIncludesVisitor.cs

Lines changed: 28 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -23,60 +23,45 @@ protected override Expression VisitMember(MemberExpression node)
2323
return base.VisitMember(node);
2424

2525
InfoDictionary.Add(parameterExpression, TypeMappings);
26-
string sourcePath = node.GetPropertyFullName();
27-
Expression baseParentExpr = node.GetBaseOfMemberExpression();
28-
Expression visitedParentExpr = this.Visit(baseParentExpr);
29-
Type sType = baseParentExpr.Type;
30-
Type dType = visitedParentExpr.Type;
26+
return GetMappedMemberExpression(node.GetBaseOfMemberExpression(), new List<PropertyMapInfo>());
3127

32-
var propertyMapInfoList = new List<PropertyMapInfo>();
33-
FindDestinationFullName(sType, dType, sourcePath, propertyMapInfoList);
34-
string fullName;
35-
36-
if (propertyMapInfoList.Any(x => x.CustomExpression != null))//CustomExpression takes precedence over DestinationPropertyInfo
28+
Expression GetMappedMemberExpression(Expression parentExpression, List<PropertyMapInfo> propertyMapInfoList)
3729
{
38-
var last = propertyMapInfoList.Last(x => x.CustomExpression != null);
39-
var beforeCustExpression = propertyMapInfoList.Aggregate(new List<PropertyMapInfo>(), (list, next) =>
40-
{
41-
if (propertyMapInfoList.IndexOf(next) < propertyMapInfoList.IndexOf(last))
42-
list.Add(next);
43-
return list;
44-
});
30+
Expression mappedParentExpression = this.Visit(parentExpression);
31+
FindDestinationFullName(parentExpression.Type, mappedParentExpression.Type, node.GetPropertyFullName(), propertyMapInfoList);
4532

46-
var afterCustExpression = propertyMapInfoList.Aggregate(new List<PropertyMapInfo>(), (list, next) =>
33+
if (propertyMapInfoList.Any(x => x.CustomExpression != null))//CustomExpression takes precedence over DestinationPropertyInfo
4734
{
48-
if (propertyMapInfoList.IndexOf(next) > propertyMapInfoList.IndexOf(last))
49-
list.Add(next);
50-
return list;
51-
});
52-
53-
54-
fullName = BuildFullName(beforeCustExpression);
35+
return GetMemberExpression
36+
(
37+
new FindMemberExpressionsVisitor(mappedParentExpression),
38+
GetMemberExpressionFromCustomExpression
39+
(
40+
propertyMapInfoList,
41+
propertyMapInfoList.Last(x => x.CustomExpression != null),
42+
mappedParentExpression
43+
)
44+
);
45+
}
5546

56-
var visitor = new PrependParentNameVisitor
47+
return GetExpressionForInclude
5748
(
58-
last.CustomExpression.Parameters[0].Type/*Parent type of current property*/,
59-
fullName,
60-
visitedParentExpr
49+
GetMemberExpressionFromMemberMaps
50+
(
51+
BuildFullName(propertyMapInfoList),
52+
mappedParentExpression
53+
)
6154
);
55+
}
6256

63-
var ex = propertyMapInfoList[propertyMapInfoList.Count - 1] != last
64-
? visitor.Visit(last.CustomExpression.Body.MemberAccesses(afterCustExpression))
65-
: visitor.Visit(last.CustomExpression.Body);
66-
67-
var v = new FindMemberExpressionsVisitor(visitedParentExpr);
68-
v.Visit(ex);
57+
Expression GetExpressionForInclude(MemberExpression memberExpression)
58+
=> memberExpression.Type.IsLiteralType() ? memberExpression.Expression : memberExpression;
6959

70-
return v.Result;
71-
}
72-
fullName = BuildFullName(propertyMapInfoList);
73-
var me = ExpressionHelpers.MemberAccesses(fullName, InfoDictionary[parameterExpression].NewParameter);
74-
if (me.Expression.NodeType == ExpressionType.MemberAccess && me.Type.IsLiteralType())
60+
MemberExpression GetMemberExpression(FindMemberExpressionsVisitor visitor, Expression mappedExpression)
7561
{
76-
return me.Expression;
62+
visitor.Visit(mappedExpression);
63+
return visitor.Result;
7764
}
78-
79-
return me;
8065
}
8166
}
8267
}

src/AutoMapper.Extensions.ExpressionMapping/PrependParentNameVisitor.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,7 @@ protected override Expression VisitMember(MemberExpression node)
4040
? sourcePath
4141
: string.Concat(ParentFullName, ".", sourcePath);
4242

43-
var me = ExpressionHelpers.MemberAccesses(fullName, NewParameter);
44-
45-
return me;
43+
return ExpressionHelpers.MemberAccesses(fullName, NewParameter);
4644
}
4745
}
4846
}

src/AutoMapper.Extensions.ExpressionMapping/XpressionMapperVisitor.cs

Lines changed: 78 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -45,56 +45,81 @@ protected override Expression VisitMember(MemberExpression node)
4545
return base.VisitMember(node);
4646

4747
InfoDictionary.Add(parameterExpression, TypeMappings);
48+
return GetMappedMemberExpression(node.GetBaseOfMemberExpression(), new List<PropertyMapInfo>());
4849

49-
string sourcePath = node.GetPropertyFullName();
50-
Expression baseParentExpr = node.GetBaseOfMemberExpression();
51-
Expression visitedParentExpr = this.Visit(baseParentExpr);
52-
Type sType = baseParentExpr.Type;
53-
Type dType = visitedParentExpr.Type;
54-
55-
var propertyMapInfoList = new List<PropertyMapInfo>();
56-
FindDestinationFullName(sType, dType, sourcePath, propertyMapInfoList);
57-
string fullName;
58-
59-
if (propertyMapInfoList.Any(x => x.CustomExpression != null))
50+
Expression GetMappedMemberExpression(Expression parentExpression, List<PropertyMapInfo> propertyMapInfoList)
6051
{
61-
var last = propertyMapInfoList.Last(x => x.CustomExpression != null);
62-
var beforeCustExpression = propertyMapInfoList.Aggregate(new List<PropertyMapInfo>(), (list, next) =>
63-
{
64-
if (propertyMapInfoList.IndexOf(next) < propertyMapInfoList.IndexOf(last))
65-
list.Add(next);
66-
return list;
67-
});
52+
Expression mappedParentExpression = this.Visit(parentExpression);
53+
FindDestinationFullName(parentExpression.Type, mappedParentExpression.Type, node.GetPropertyFullName(), propertyMapInfoList);
6854

69-
var afterCustExpression = propertyMapInfoList.Aggregate(new List<PropertyMapInfo>(), (list, next) =>
55+
if (propertyMapInfoList.Any(x => x.CustomExpression != null))
7056
{
71-
if (propertyMapInfoList.IndexOf(next) > propertyMapInfoList.IndexOf(last))
72-
list.Add(next);
73-
return list;
74-
});
75-
76-
fullName = BuildFullName(beforeCustExpression);
77-
var visitor = new PrependParentNameVisitor
78-
(
79-
last.CustomExpression.Parameters[0].Type/*Parent type of current property*/,
80-
fullName,
81-
visitedParentExpr
82-
);
57+
var fromCustomExpression = GetMemberExpressionFromCustomExpression
58+
(
59+
propertyMapInfoList,
60+
propertyMapInfoList.Last(x => x.CustomExpression != null),
61+
mappedParentExpression
62+
);
63+
64+
this.TypeMappings.AddTypeMapping(ConfigurationProvider, node.Type, fromCustomExpression.Type);
65+
return fromCustomExpression;
66+
}
8367

84-
var ex = propertyMapInfoList[propertyMapInfoList.Count - 1] != last
85-
? visitor.Visit(last.CustomExpression.Body.MemberAccesses(afterCustExpression))
86-
: visitor.Visit(last.CustomExpression.Body);
68+
var memberExpression = GetMemberExpressionFromMemberMaps(BuildFullName(propertyMapInfoList), mappedParentExpression);
69+
this.TypeMappings.AddTypeMapping(ConfigurationProvider, node.Type, memberExpression.Type);
8770

88-
this.TypeMappings.AddTypeMapping(ConfigurationProvider, node.Type, ex.Type);
89-
return ex;
71+
return memberExpression;
9072
}
91-
fullName = BuildFullName(propertyMapInfoList);
92-
var me = ExpressionHelpers.MemberAccesses(fullName, visitedParentExpr);
73+
}
74+
75+
protected MemberExpression GetMemberExpressionFromMemberMaps(string fullName, Expression visitedParentExpr)
76+
=> ExpressionHelpers.MemberAccesses(fullName, visitedParentExpr);
9377

94-
this.TypeMappings.AddTypeMapping(ConfigurationProvider, node.Type, me.Type);
95-
return me;
78+
private Expression GetMemberExpressionFromCustomExpression(PropertyMapInfo lastWithCustExpression,
79+
PropertyMapInfo lastInList,
80+
List<PropertyMapInfo> beforeCustExpression,
81+
List<PropertyMapInfo> afterCustExpression,
82+
Expression visitedParentExpr)
83+
{
84+
return PrependParentMemberExpression
85+
(
86+
new PrependParentNameVisitor
87+
(
88+
lastWithCustExpression.CustomExpression.Parameters[0].Type/*Parent type of current property*/,
89+
BuildFullName(beforeCustExpression),
90+
visitedParentExpr
91+
)
92+
);
93+
94+
Expression PrependParentMemberExpression(PrependParentNameVisitor visitor)
95+
=> visitor.Visit
96+
(
97+
lastInList != lastWithCustExpression
98+
? lastWithCustExpression.CustomExpression.Body.MemberAccesses(afterCustExpression)
99+
: lastWithCustExpression.CustomExpression.Body
100+
);
96101
}
97102

103+
protected Expression GetMemberExpressionFromCustomExpression(List<PropertyMapInfo> propertyMapInfoList, PropertyMapInfo lastWithCustExpression, Expression mappedParentExpr)
104+
=> GetMemberExpressionFromCustomExpression
105+
(
106+
lastWithCustExpression,
107+
propertyMapInfoList.Last(),
108+
propertyMapInfoList.Aggregate(new List<PropertyMapInfo>(), (list, next) =>
109+
{
110+
if (propertyMapInfoList.IndexOf(next) < propertyMapInfoList.IndexOf(lastWithCustExpression))
111+
list.Add(next);
112+
return list;
113+
}),
114+
propertyMapInfoList.Aggregate(new List<PropertyMapInfo>(), (list, next) =>
115+
{
116+
if (propertyMapInfoList.IndexOf(next) > propertyMapInfoList.IndexOf(lastWithCustExpression))
117+
list.Add(next);
118+
return list;
119+
}),
120+
mappedParentExpr
121+
);
122+
98123
protected override Expression VisitLambda<T>(Expression<T> node)
99124
{
100125
var ex = this.Visit(node.Body);
@@ -148,10 +173,19 @@ protected override Expression VisitUnary(UnaryExpression node)
148173

149174
Expression DoVisitUnary(Expression updated)
150175
{
151-
if (updated != node.Operand)
152-
return node.Update(updated);
153-
154-
return node;
176+
if (this.TypeMappings.TryGetValue(node.Type, out Type mappedType))
177+
return Expression.MakeUnary
178+
(
179+
node.NodeType,
180+
updated != node.Operand
181+
? updated
182+
: node.Operand,
183+
mappedType
184+
);
185+
186+
return updated != node.Operand
187+
? node.Update(updated)
188+
: base.VisitUnary(node);
155189
}
156190
}
157191

tests/AutoMapper.Extensions.ExpressionMapping.UnitTests/Impl/SourceInjectedQuery.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -607,20 +607,20 @@ public void Shoud_convert_type_changes()
607607
destItem.DestValue.ShouldBe(sourceItem.SrcValue);
608608
}
609609

610-
[Fact(Skip="Conventions not available like this.")]
611-
public void Shoud_work_with_conventions()
612-
{
613-
//var mapper = new MapperConfiguration(cfg => cfg.AddConditionalObjectMapper()
614-
// .Where((s, d) => s.Name == d.Name + "Model" || s.Name + "Model" == d.Name)).CreateMapper();
610+
//[Fact(Skip="Conventions not available like this.")]
611+
//public void Shoud_work_with_conventions()
612+
//{
613+
// //var mapper = new MapperConfiguration(cfg => cfg.AddConditionalObjectMapper()
614+
// // .Where((s, d) => s.Name == d.Name + "Model" || s.Name + "Model" == d.Name)).CreateMapper();
615615

616616

617-
//IQueryable<Destination> result = _source.AsQueryable()
618-
// .UseAsDataSource(Mapper).For<Destination>()
619-
// .Where(s => s.DestValue > 6);
617+
// //IQueryable<Destination> result = _source.AsQueryable()
618+
// // .UseAsDataSource(Mapper).For<Destination>()
619+
// // .Where(s => s.DestValue > 6);
620620

621-
//result.Count().ShouldBe(1);
622-
//result.Any(s => s.DestValue > 6).ShouldBeTrue();
623-
}
621+
// //result.Count().ShouldBe(1);
622+
// //result.Any(s => s.DestValue > 6).ShouldBeTrue();
623+
//}
624624

625625
private static IMapper SetupAutoMapper()
626626
{

tests/AutoMapper.Extensions.ExpressionMapping.UnitTests/XpressionMapperTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,7 @@ public void Can_map_expression_when_mapped_when_members_parent_is_a_method()
715715
emp.Events.First(e => e.EventType.Equals("Stop")).EventDate < DateTime.Today.AddYears(-1);
716716

717717
//Act
718-
Expression<Func<EmployeeEntity, bool>> mappedFilter = mapper.MapExpression<Expression<Func<EmployeeEntity, bool>>>(filter);
718+
Expression<Func<EmployeeEntity, bool>> mappedFilter = mapper.MapExpression<Expression<Func<EmployeeEntity, bool>>>(filter);
719719
List<EmployeeEntity> res = empEntity.AsQueryable().Where(mappedFilter).ToList();
720720

721721
//Assert

0 commit comments

Comments
 (0)