Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ on:
push:
branches:
- master
- v4.1.3
- v6.0.3
pull_request:
branches:
- master
- v4.1.3
- v6.0.3

jobs:
build:
Expand Down
Binary file added icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<SignAssembly>true</SignAssembly>
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
<PackageId>AutoMapper.Extensions.ExpressionMapping</PackageId>
<PackageIconUrl>https://s3.amazonaws.com/automapper/icon.png</PackageIconUrl>
<PackageIcon>icon.png</PackageIcon>
<PackageProjectUrl>http://automapper.org</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/AutoMapper/AutoMapper.Extensions.ExpressionMapping/blob/master/LICENSE</PackageLicenseUrl>
<RepositoryType>git</RepositoryType>
Expand All @@ -24,13 +24,32 @@
<ContinuousIntegrationBuild Condition="'$(GITHUB_ACTIONS)' == 'true'">true</ContinuousIntegrationBuild>
</PropertyGroup>

<ItemGroup>
<None Include="..\..\icon.png" Pack="true" PackagePath="" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="AutoMapper" Version="[11.0.0,12.0.0)" />
<PackageReference Include="AutoMapper" Version="[12.0.0,13.0.0)" />
<PackageReference Include="MinVer" Version="2.3.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
</ItemGroup>

<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>

<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ protected override Expression VisitBinary(BinaryExpression node)
var newLeft = Visit(node.Left);
var newRight = Visit(node.Right);

// check if the non-string expression is a null constent
// check if the non-string expression is a null constant
// as this would lead to a "null.ToString()" and thus an error when executing the expression
if (newLeft.Type != newRight.Type && newRight.Type == typeof(string) && !IsNullConstant(newLeft))
newLeft = Call(newLeft, typeof(object).GetDeclaredMethod("ToString"));
Expand Down Expand Up @@ -206,7 +206,7 @@ protected override Expression VisitMember(MemberExpression node)
if (constantVisitor.IsConstant)
return node;

SetSorceSubTypes(propertyMap);
SetSourceSubTypes(propertyMap);

var replacedExpression = Visit(node.Expression);
if (replacedExpression == node.Expression)
Expand Down Expand Up @@ -282,7 +282,7 @@ private PropertyMap GetExistingPropertyMapFor(MemberInfo destinationProperty, Ty
return typeMap.PropertyMaps.FirstOrDefault(pm => pm.DestinationName == destinationProperty.Name);
}

private void SetSorceSubTypes(PropertyMap propertyMap)
private void SetSourceSubTypes(PropertyMap propertyMap)
{
if (propertyMap.SourceMember is PropertyInfo info)
_destSubTypes = info.PropertyType.GetTypeInfo().GenericTypeArguments.Concat(new[] { info.PropertyType }).ToList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public MemberExpression Result
if (string.IsNullOrEmpty(result) || next.Contains(result))
result = next;
else throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture,
Resource.includeExpressionTooComplex,
Properties.Resources.includeExpressionTooComplex,
string.Concat(_newParentExpression.Type.Name, period, result),
string.Concat(_newParentExpression.Type.Name, period, next)));

Expand All @@ -50,7 +50,7 @@ protected override Expression VisitMember(MemberExpression node)
if (node.Expression.NodeType == ExpressionType.MemberAccess && node.Type.IsLiteralType())
_memberExpressions.Add((MemberExpression)node.Expression);
else if (node.Expression.NodeType == ExpressionType.Parameter && node.Type.IsLiteralType())
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resource.mappedMemberIsChildOfTheParameterFormat, node.GetPropertyFullName(), node.Type.FullName, sType.FullName));
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Properties.Resources.mappedMemberIsChildOfTheParameterFormat, node.GetPropertyFullName(), node.Type.FullName, sType.FullName));
else
_memberExpressions.Add(node);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using AutoMapper.Internal;
using AutoMapper.Extensions.ExpressionMapping.Extensions;
using AutoMapper.Extensions.ExpressionMapping.Structures;

Expand All @@ -18,6 +16,9 @@ public MapIncludesVisitor(IMapper mapper, IConfigurationProvider configurationPr

protected override Expression VisitLambda<T>(Expression<T> node)
{
if (!node.Body.Type.IsLiteralType())
return base.VisitLambda(node);

var ex = this.Visit(node.Body);

var mapped = Expression.Lambda(ex, node.GetDestinationParameterExpressions(this.InfoDictionary, this.TypeMappings));
Expand All @@ -27,6 +28,9 @@ protected override Expression VisitLambda<T>(Expression<T> node)

protected override Expression VisitMember(MemberExpression node)
{
if (!node.Type.IsLiteralType())
return base.VisitMember(node);

var parameterExpression = node.GetParameterExpression();
if (parameterExpression == null)
return base.VisitMember(node);
Expand Down
12 changes: 6 additions & 6 deletions src/AutoMapper.Extensions.ExpressionMapping/MapperExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ TDestDelegate MapBody(Dictionary<Type, Type> typeMappings, XpressionMapperVisito
TDestDelegate GetLambda(Dictionary<Type, Type> typeMappings, XpressionMapperVisitor visitor, Expression mappedBody)
{
if (mappedBody == null)
throw new InvalidOperationException(Resource.cantRemapExpression);
throw new InvalidOperationException(Properties.Resources.cantRemapExpression);

return (TDestDelegate)Lambda
(
Expand Down Expand Up @@ -255,7 +255,7 @@ public static List<ParameterExpression> GetDestinationParameterExpressions(this
/// <returns></returns>
public static Dictionary<Type, Type> AddTypeMapping<TSource, TDest>(this Dictionary<Type, Type> typeMappings, IConfigurationProvider configurationProvider)
=> typeMappings == null
? throw new ArgumentException(Resource.typeMappingsDictionaryIsNull)
? throw new ArgumentException(Properties.Resources.typeMappingsDictionaryIsNull)
: typeMappings.AddTypeMapping(configurationProvider, typeof(TSource), typeof(TDest));

private static bool HasUnderlyingType(this Type type)
Expand Down Expand Up @@ -284,7 +284,7 @@ private static void AddUnderlyingTypes(this Dictionary<Type, Type> typeMappings,
public static Dictionary<Type, Type> AddTypeMapping(this Dictionary<Type, Type> typeMappings, IConfigurationProvider configurationProvider, Type sourceType, Type destType)
{
if (typeMappings == null)
throw new ArgumentException(Resource.typeMappingsDictionaryIsNull);
throw new ArgumentException(Properties.Resources.typeMappingsDictionaryIsNull);

if (sourceType.GetTypeInfo().IsGenericType && sourceType.GetGenericTypeDefinition() == typeof(Expression<>))
{
Expand Down Expand Up @@ -357,7 +357,7 @@ public static Type ReplaceType(this Dictionary<Type, Type> typeMappings, Type so
private static Dictionary<Type, Type> AddTypeMappingsFromDelegates(this Dictionary<Type, Type> typeMappings, IConfigurationProvider configurationProvider, Type sourceType, Type destType)
{
if (typeMappings == null)
throw new ArgumentException(Resource.typeMappingsDictionaryIsNull);
throw new ArgumentException(Properties.Resources.typeMappingsDictionaryIsNull);

typeMappings.DoAddTypeMappingsFromDelegates
(
Expand All @@ -372,7 +372,7 @@ private static Dictionary<Type, Type> AddTypeMappingsFromDelegates(this Dictiona
private static void DoAddTypeMappingsFromDelegates(this Dictionary<Type, Type> typeMappings, IConfigurationProvider configurationProvider, List<Type> sourceArguments, List<Type> destArguments)
{
if (sourceArguments.Count != destArguments.Count)
throw new ArgumentException(Resource.invalidArgumentCount);
throw new ArgumentException(Properties.Resources.invalidArgumentCount);

for (int i = 0; i < sourceArguments.Count; i++)
{
Expand All @@ -396,7 +396,7 @@ private static void DoAddTypeMappings(this Dictionary<Type, Type> typeMappings,
private static Type GetSourceMemberType(this PropertyMap propertyMap)
=> propertyMap.CustomMapExpression != null
? propertyMap.CustomMapExpression.ReturnType
: propertyMap.SourceMember.GetMemberType();
: propertyMap.SourceMembers.Last().GetMemberType();

private static void FindChildPropertyTypeMaps(this Dictionary<Type, Type> typeMappings, IConfigurationProvider ConfigurationProvider, Type source, Type dest)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
using AutoMapper.Extensions.ExpressionMapping.Extensions;
using System.Linq;
using System.Linq.Expressions;
using System.Runtime.CompilerServices;
using System.Linq.Expressions;

namespace AutoMapper.Extensions.ExpressionMapping
{
Expand All @@ -18,111 +15,16 @@ public PrependParentNameVisitor(ParameterExpression currentParameter, string par
public string ParentFullName { get; }
public Expression NewParameter { get; }

protected override Expression VisitTypeBinary(TypeBinaryExpression node)
protected override Expression VisitParameter(ParameterExpression node)
{
if (!(node.Expression is ParameterExpression))
return base.VisitTypeBinary(node);

if (!object.ReferenceEquals(CurrentParameter, node.GetParameterExpression()))
return base.VisitTypeBinary(node);

return Expression.TypeIs
(
string.IsNullOrEmpty(ParentFullName)
? NewParameter
: ExpressionHelpers.MemberAccesses(ParentFullName, NewParameter),
node.TypeOperand
);
}

protected override Expression VisitMember(MemberExpression node)
{
if (node.NodeType == ExpressionType.Constant)
return base.VisitMember(node);

if (!object.ReferenceEquals(CurrentParameter, node.GetParameterExpression()) || !node.IsMemberExpression())
return base.VisitMember(node);

return ExpressionHelpers.MemberAccesses
(
string.IsNullOrEmpty(ParentFullName)
? node.GetPropertyFullName()
: $"{ParentFullName}.{node.GetPropertyFullName()}",
NewParameter
);
}

protected override Expression VisitMethodCall(MethodCallExpression node)
{
if (!IsParentParameterExpression())
return base.VisitMethodCall(node);

if (!object.ReferenceEquals(CurrentParameter, node.GetParameterExpression()))
return base.VisitMethodCall(node);

if (node.Method.IsStatic)
if (object.ReferenceEquals(CurrentParameter, node))
{
if (!IsExtentionMethod())
return base.VisitMethodCall(node);

if (node.Method.IsGenericMethod)
return Expression.Call
(
node.Method.DeclaringType,
node.Method.Name,
node.Method.GetGenericArguments(),
GetNewArgumentsForExtensionMethod()
);
else
return Expression.Call(node.Method, GetNewArgumentsForExtensionMethod());
}

//instance method
if (node.Method.IsGenericMethod)
{
return Expression.Call
(
GetNewParent(),
node.Method.Name,
node.Method.GetGenericArguments(),
node.Arguments.ToArray()
);
}
else
{
return Expression.Call
(
GetNewParent(),
node.Method,
node.Arguments
);
}

Expression[] GetNewArgumentsForExtensionMethod()
{
Expression[] arguments = node.Arguments.ToArray();
arguments[0] = GetNewParent();
return arguments.ToArray();
}

Expression GetNewParent()
=> string.IsNullOrEmpty(ParentFullName)
? NewParameter
: ExpressionHelpers.MemberAccesses(ParentFullName, NewParameter);

bool IsParentParameterExpression()
{
if (node.Method.IsStatic)
return node.Arguments[0] is ParameterExpression;

if (!node.Method.IsStatic)
return node.Object is ParameterExpression;

return false;
return string.IsNullOrEmpty(ParentFullName)
? NewParameter
: ExpressionHelpers.MemberAccesses(ParentFullName, NewParameter);
}

bool IsExtentionMethod()
=> node.Method.IsDefined(typeof(ExtensionAttribute), true);
return base.VisitParameter(node);
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading