public static Expression<Func<TFrom, TTo>> AndLambdas<TFrom, TTo>(this Expression<Func<TFrom, TTo>> first, Expression<Func<TFrom, TTo>> second)
 {    
   ParameterExpression paramToUse = first.Parameters[0];
   Expression bodyLeft = first.Body;
   ConversionVisitor visitor = new ConversionVisitor(paramToUse, second.Parameters[0]);
   Expression bodyRight = visitor.Visit(second.Body);
   return Expression.Lambda<Func<TFrom, TTo>>(Expression.MakeBinary(ExpressionType.AndAlso, bodyLeft, bodyRight), first.Parameters);
 }
    public static Expression <Func <TTo, TR> > Convert <TFrom, TR>(
        Expression <Func <TFrom, TR> > e
        )
    {
        var oldParameter = e.Parameters[0];
        var newParameter = Expression.Parameter(typeof(TTo), oldParameter.Name);
        var converter    = new ConversionVisitor(newParameter, oldParameter);
        var newBody      = converter.Visit(e.Body);

        return(Expression.Lambda <Func <TTo, TR> >(newBody, newParameter));
    }
        public static Expression <Func <TTo, TR> > Convert <TFrom, TR>(Expression <Func <TFrom, TR> > e)
        {
            if (e == null)
            {
                throw new ArgumentNullException(nameof(e));
            }

            var oldParameter = e.Parameters[0];
            var newParameter = Expression.Parameter(typeof(TTo), oldParameter.Name);
            var converter    = new ConversionVisitor(newParameter, oldParameter);
            var newBody      = converter.Visit(e.Body);

            return(Expression.Lambda <Func <TTo, TR> >(newBody, newParameter));
        }
        /// <summary>
        /// Convert expression from type [TFrom] to type [TTo]
        /// </summary>
        /// <typeparam name="TFrom"></typeparam>
        /// <typeparam name="TTo"></typeparam>
        /// <typeparam name="TReturn"></typeparam>
        /// <param name="e"></param>
        /// <returns></returns>
        public static Expression <Func <TTo, TResult> > Convert <TFrom, TTo, TResult>(Expression <Func <TFrom, TResult> > e)
        {
            if (e == null)
            {
                return(null);
            }
            var oldParameter = e.Parameters[0];
            var newParameter = Expression.Parameter(typeof(TTo), oldParameter.Name);
            var converter    = new ConversionVisitor(newParameter, oldParameter);

            try
            {
                var newBody = converter.Visit(e.Body);
                return(Expression.Lambda <Func <TTo, TResult> >(newBody, newParameter));
            }
            catch (ArgumentException)
            {
                return(null);
            }
        }
Exemple #5
0
        public ExpressionResolutionResult ResolveExpression(Type currentType, Expression instanceParameter)
        {
            Expression currentChild     = instanceParameter;
            Type       currentChildType = currentType;

            foreach (var resolver in GetSourceValueResolvers())
            {
                var getter = resolver as IMemberGetter;
                if (getter != null)
                {
                    var memberInfo = getter.MemberInfo;

                    var propertyInfo = memberInfo as PropertyInfo;
                    if (propertyInfo != null)
                    {
                        currentChild     = Expression.Property(currentChild, propertyInfo);
                        currentChildType = propertyInfo.PropertyType;
                    }
                    else
                    {
                        throw new NotImplementedException("Expressions mapping from methods not supported yet.");
                    }
                }
                else
                {
                    var oldParameter = CustomExpression.Parameters.Single();
                    var newParameter = instanceParameter;
                    var converter    = new ConversionVisitor(newParameter, oldParameter);

                    currentChild     = converter.Visit(CustomExpression.Body);
                    currentChildType = currentChild.Type;
                }
            }

            return(new ExpressionResolutionResult(currentChild, currentChildType));
        }
Exemple #6
0
        private static ExpressionResolutionResult ResolveExpression(PropertyMap propertyMap, Type currentType, Expression instanceParameter)
        {
            Expression currentChild     = instanceParameter;
            Type       currentChildType = currentType;

            foreach (var resolver in propertyMap.GetSourceValueResolvers())
            {
                var getter = resolver as IMemberGetter;
                if (getter != null)
                {
                    var memberInfo = getter.MemberInfo;

                    var propertyInfo = memberInfo as PropertyInfo;
                    if (propertyInfo != null)
                    {
                        currentChild     = Expression.Property(currentChild, propertyInfo);
                        currentChildType = propertyInfo.PropertyType;
                    }
                    else
                    {
                        currentChildType = currentChild.Type;
                    }
                }
                else
                {
                    var oldParameter = propertyMap.CustomExpression.Parameters.Single();
                    var newParameter = instanceParameter;
                    var converter    = new ConversionVisitor(newParameter, oldParameter);

                    currentChild     = converter.Visit(propertyMap.CustomExpression.Body);
                    currentChildType = currentChild.Type;
                }
            }

            return(new ExpressionResolutionResult(currentChild, currentChildType));
        }
        private LambdaExpression CreateMapExpression(
            Type typeIn, Type typeOut)
        {
            var typeMap = ConfigurationProvider.FindTypeMapFor(typeIn, typeOut);

            // this is the input parameter of this expression with name <variableName>
            ParameterExpression instanceParameter = Expression.Parameter(typeIn);

            var bindings = new List <MemberBinding>();

            foreach (var propertyMap in typeMap.GetPropertyMaps().Where(pm => pm.CanResolveValue()))
            {
                var destinationProperty = propertyMap.DestinationProperty;
                var destinationMember   = destinationProperty.MemberInfo;

                Expression currentChild     = instanceParameter;
                Type       currentChildType = typeIn;
                foreach (var resolver in propertyMap.GetSourceValueResolvers())
                {
                    var getter = resolver as IMemberGetter;
                    if (getter != null)
                    {
                        var memberInfo = getter.MemberInfo;

                        var propertyInfo = memberInfo as PropertyInfo;
                        if (propertyInfo != null)
                        {
                            currentChild     = Expression.Property(currentChild, propertyInfo);
                            currentChildType = propertyInfo.PropertyType;
                        }
                    }
                    else
                    {
                        var oldParameter =
                            ((LambdaExpression)propertyMap.CustomExpression).Parameters.Single();
                        var newParameter = instanceParameter;
                        var converter    = new ConversionVisitor(newParameter, oldParameter);
                        currentChild = converter.Visit(((LambdaExpression)propertyMap.CustomExpression).Body);
                        var propertyInfo = propertyMap.SourceMember as PropertyInfo;
                        if (propertyInfo != null)
                        {
                            currentChildType = propertyInfo.PropertyType;
                        }
                    }
                }

                var prop = destinationProperty.MemberInfo as PropertyInfo;

                // next to lists, also arrays
                // and objects!!!
                if (prop != null &&
                    prop.PropertyType.GetInterface("IEnumerable", true) != null &&
                    prop.PropertyType != typeof(string))
                {
                    Type destinationListType = prop.PropertyType.GetGenericArguments().First();
                    Type sourceListType      = null;
                    // is list

                    sourceListType = currentChildType.GetGenericArguments().First();

                    //var newVariableName = "t" + (i++);
                    var transformedExpression = CreateMapExpression(sourceListType, destinationListType);

                    MethodCallExpression selectExpression = Expression.Call(
                        typeof(Enumerable),
                        "Select",
                        new[] { sourceListType, destinationListType },
                        currentChild,
                        transformedExpression);

                    if (typeof(IList).IsAssignableFrom(prop.PropertyType))
                    {
                        MethodCallExpression toListCallExpression = Expression.Call(
                            typeof(Enumerable),
                            "ToList",
                            new Type[] { destinationListType },
                            selectExpression);

                        // todo .ToArray()
                        bindings.Add(Expression.Bind(destinationMember, toListCallExpression));
                    }
                    else
                    {
                        // destination type implements ienumerable, but is not an ilist. allow deferred enumeration
                        bindings.Add(Expression.Bind(destinationMember, selectExpression));
                    }
                }
                else
                {
                    // does of course not work for subclasses etc./generic ...
                    if (currentChildType != prop.PropertyType &&
                        // avoid nullable etc.
                        prop.PropertyType.BaseType != typeof(ValueType) &&
                        prop.PropertyType.BaseType != typeof(Enum))
                    {
                        var transformedExpression = CreateMapExpression(currentChildType, prop.PropertyType);
                        var expr2 = Expression.Invoke(
                            transformedExpression,
                            currentChild
                            );
                        bindings.Add(Expression.Bind(destinationMember, expr2));
                    }
                    else
                    {
                        bindings.Add(Expression.Bind(destinationMember, currentChild));
                    }
                }
            }
            var total = Expression.MemberInit(
                Expression.New(typeOut),
                bindings.ToArray()
                );

            return(Expression.Lambda(total, instanceParameter));
        }
Exemple #8
0
		void InsertComments(CompilerCompilationUnit top, ConversionVisitor conversionVisitor)
		{
			AstNode insertionPoint = conversionVisitor.Unit.FirstChild;
			foreach (var special in top.SpecialsBag.Specials) {
				AstNode newLeaf = null;
				Role role = null;
				bool isDocumentationComment = false;
				var comment = special as SpecialsBag.Comment;
				if (comment != null) {
					// HACK: multiline documentation comment detection; better move this logic into the mcs tokenizer
					bool isMultilineDocumentationComment = (comment.CommentType == SpecialsBag.CommentType.Multi && comment.Content.StartsWith("*", StringComparison.Ordinal) && !comment.Content.StartsWith("**", StringComparison.Ordinal));
					isDocumentationComment = comment.CommentType == SpecialsBag.CommentType.Documentation || isMultilineDocumentationComment;
					if (conversionVisitor.convertTypeSystemMode && !isDocumentationComment)
						continue;
					var type = isMultilineDocumentationComment ? CommentType.MultiLineDocumentation : (CommentType)comment.CommentType;
					var start = new TextLocation(comment.Line, comment.Col);
					var end = new TextLocation(comment.EndLine, comment.EndCol);
					newLeaf = new Comment(type, start, end) {
						StartsLine = comment.StartsLine,
						Content = isMultilineDocumentationComment ? comment.Content.Substring(1) : comment.Content
					};
					role = Roles.Comment;
				} else if (!GenerateTypeSystemMode) {
					var pragmaDirective = special as SpecialsBag.PragmaPreProcessorDirective;
					if (pragmaDirective != null) {
						var pragma = new PragmaWarningPreprocessorDirective(new TextLocation(pragmaDirective.Line, pragmaDirective.Col), new TextLocation(pragmaDirective.EndLine, pragmaDirective.EndCol));
						pragma.AddChild(new CSharpTokenNode(new TextLocation(pragmaDirective.Line, pragmaDirective.Col), PragmaWarningPreprocessorDirective.PragmaKeywordRole), PragmaWarningPreprocessorDirective.PragmaKeywordRole);
						pragma.AddChild(new CSharpTokenNode(new TextLocation(pragmaDirective.Line, pragmaDirective.WarningColumn), PragmaWarningPreprocessorDirective.WarningKeywordRole), PragmaWarningPreprocessorDirective.WarningKeywordRole);
						var pragmaRole = pragmaDirective.Disalbe ? PragmaWarningPreprocessorDirective.DisableKeywordRole : PragmaWarningPreprocessorDirective.RestoreKeywordRole;
						pragma.AddChild(new CSharpTokenNode(new TextLocation(pragmaDirective.Line, pragmaDirective.DisableRestoreColumn), pragmaRole), pragmaRole);
						foreach (var code in pragmaDirective.Codes) {
							pragma.AddChild((PrimitiveExpression)conversionVisitor.Visit(code), PragmaWarningPreprocessorDirective.WarningRole);
						}
						newLeaf = pragma;
						role = Roles.PreProcessorDirective;
						goto end;
					}
					var lineDirective = special as SpecialsBag.LineProcessorDirective;
					if (lineDirective != null) {
						var pragma = new LinePreprocessorDirective(new TextLocation(lineDirective.Line, lineDirective.Col), new TextLocation(lineDirective.EndLine, lineDirective.EndCol));
						pragma.LineNumber = lineDirective.LineNumber;
						pragma.FileName = lineDirective.FileName;
						newLeaf = pragma;
						role = Roles.PreProcessorDirective;
						goto end;
					}
					var directive = special as SpecialsBag.PreProcessorDirective;
					if (directive != null) {
						newLeaf = new PreProcessorDirective((PreProcessorDirectiveType)((int)directive.Cmd & 0xF), new TextLocation(directive.Line, directive.Col), new TextLocation(directive.EndLine, directive.EndCol)) {
							Argument = directive.Arg,
							Take = directive.Take
						};
						role = Roles.PreProcessorDirective;
					}
					end:
					;
				}
				if (newLeaf != null) {
					InsertComment(ref insertionPoint, newLeaf, role, isDocumentationComment, conversionVisitor.Unit);
				}
			}
			if (!GenerateTypeSystemMode) {
				// We cannot insert newlines in the same loop as comments/preprocessor directives
				// because they are not correctly ordered in the specials bag
				insertionPoint = conversionVisitor.Unit.FirstChild;
				for (int i = 0; i < top.SpecialsBag.Specials.Count; i++) {
					var newLine = top.SpecialsBag.Specials [i] as SpecialsBag.NewLineToken;
					if (newLine != null) {
						var newLeaf = new NewLineNode(new TextLocation(newLine.Line, newLine.Col + 1));
						newLeaf.NewLineType = newLine.NewLine == SpecialsBag.NewLine.Unix ? UnicodeNewline.LF : UnicodeNewline.CRLF;
						InsertComment(ref insertionPoint, newLeaf, Roles.NewLine, false, conversionVisitor.Unit);
					}
				}
			}
		}
        private LambdaExpression CreateMapExpression(
            Type typeIn, Type typeOut)
        {
            var typeMap = ConfigurationProvider.FindTypeMapFor(typeIn, typeOut);

            if (typeMap == null)
            {
                throw new ArgumentException(string.Format("Type map for converting from \"{0}\" to \"{1}\" was not found. Please use Mapper.CreateMap<{0}, {1}>() to register a type map.", typeIn.Name, typeOut.Name));
            }

            // this is the input parameter of this expression with name <variableName>
            ParameterExpression instanceParameter = Expression.Parameter(typeIn);

            var bindings = new List <MemberBinding>();

            foreach (var propertyMap in typeMap.GetPropertyMaps().Where(pm => pm.CanResolveValue()))
            {
                var destinationProperty = propertyMap.DestinationProperty;
                var destinationMember   = destinationProperty.MemberInfo;

                Expression currentChild     = instanceParameter;
                Type       currentChildType = typeIn;
                foreach (var resolver in propertyMap.GetSourceValueResolvers())
                {
                    var getter = resolver as IMemberGetter;
                    if (getter != null)
                    {
                        var memberInfo = getter.MemberInfo;

                        var propertyInfo = memberInfo as PropertyInfo;
                        if (propertyInfo != null)
                        {
                            currentChild     = Expression.Property(currentChild, propertyInfo);
                            currentChildType = propertyInfo.PropertyType;
                        }
                    }
                    else
                    {
                        var oldParameter = propertyMap.CustomExpression.Parameters.Single();
                        var newParameter = instanceParameter;
                        var converter    = new ConversionVisitor(newParameter, oldParameter);
                        currentChild = converter.Visit(propertyMap.CustomExpression.Body);
                        var propertyInfo = propertyMap.SourceMember as PropertyInfo;
                        if (propertyInfo != null)
                        {
                            currentChildType = propertyInfo.PropertyType;
                        }
                        else
                        {
                            currentChildType = currentChild.Type;
                        }
                    }
                }

                var prop = destinationProperty.MemberInfo as PropertyInfo;

                // next to lists, also arrays
                // and objects!!!
                if (prop != null &&
                    prop.PropertyType.GetInterface("IEnumerable", true) != null &&
                    prop.PropertyType != typeof(string))
                {
                    Type destinationListType = prop.PropertyType.GetGenericArguments().FirstOrDefault() ?? prop.PropertyType.GetElementType();
Exemple #10
0
        private LambdaExpression CreateMapExpression(
            Type typeIn, Type typeOut)
        {
            var typeMap = ConfigurationProvider.FindTypeMapFor(typeIn, typeOut);

            // this is the input parameter of this expression with name <variableName>
            ParameterExpression instanceParameter = Expression.Parameter(typeIn);

            var bindings = new List <MemberBinding>();

            foreach (var propertyMap in typeMap.GetPropertyMaps().Where(pm => pm.CanResolveValue()))
            {
                var destinationProperty = propertyMap.DestinationProperty;
                var destinationMember   = destinationProperty.MemberInfo;

                Expression currentChild     = instanceParameter;
                Type       currentChildType = typeIn;
                foreach (var resolver in propertyMap.GetSourceValueResolvers())
                {
                    var getter = resolver as IMemberGetter;
                    if (getter != null)
                    {
                        var memberInfo = getter.MemberInfo;

                        var propertyInfo = memberInfo as PropertyInfo;
                        if (propertyInfo != null)
                        {
                            currentChild     = Expression.Property(currentChild, propertyInfo);
                            currentChildType = propertyInfo.PropertyType;
                        }
                    }
                    else
                    {
                        var oldParameter =
                            ((LambdaExpression)propertyMap.CustomExpression).Parameters.Single();
                        var newParameter = instanceParameter;
                        var converter    = new ConversionVisitor(newParameter, oldParameter);
                        currentChild = converter.Visit(((LambdaExpression)propertyMap.CustomExpression).Body);
                        var propertyInfo = propertyMap.SourceMember as PropertyInfo;
                        if (propertyInfo != null)
                        {
                            currentChildType = propertyInfo.PropertyType;
                        }
                    }
                }

                var prop = destinationProperty.MemberInfo as PropertyInfo;

                // next to lists, also arrays
                // and objects!!!
                if (prop != null &&
                    prop.PropertyType.GetInterface("IEnumerable", true) != null &&
                    prop.PropertyType != typeof(string))
                {
                    Type destinationListType = prop.PropertyType.GetGenericArguments().First();
                    Type sourceListType      = null;
                    // is list

                    sourceListType = currentChildType.GetGenericArguments().First();

                    //var newVariableName = "t" + (i++);
                    var transformedExpression = CreateMapExpression(sourceListType, destinationListType);

                    MethodCallExpression selectExpression = Expression.Call(
                        typeof(Enumerable),
                        "Select",
                        new[] { sourceListType, destinationListType },
                        currentChild,
                        transformedExpression);

                    if (typeof(IList).IsAssignableFrom(prop.PropertyType))
                    {
                        MethodCallExpression toListCallExpression = Expression.Call(
                            typeof(Enumerable),
                            "ToList",
                            new Type[] { destinationListType },
                            selectExpression);

                        // todo .ToArray()
                        bindings.Add(Expression.Bind(destinationMember, toListCallExpression));
                    }
                    else
                    {
                        // destination type implements ienumerable, but is not an ilist. allow deferred enumeration
                        bindings.Add(Expression.Bind(destinationMember, selectExpression));
                    }
                }
                else
                {
                    // does of course not work for subclasses etc./generic ...
                    if (currentChildType != prop.PropertyType &&
                        // avoid nullable etc.
                        prop.PropertyType.BaseType != typeof(ValueType) &&
                        prop.PropertyType.BaseType != typeof(Enum))
                    {
                        var transformedExpression = CreateMapExpression(currentChildType, prop.PropertyType);
                        var expr2 = Expression.Invoke(
                            transformedExpression,
                            currentChild
                            );
                        bindings.Add(Expression.Bind(destinationMember, expr2));
                    }
                    else
                    {
                        bindings.Add(Expression.Bind(destinationMember, currentChild));
                    }
                }
            }
            Expression total;

            if (typeOut.IsAbstract)
            {
                if (typeMap.CustomMapper == null)
                {
                    throw new AutoMapperMappingException(
                              String.Format("Abstract type {0} can not be mapped without custom mapper (tip: use ConvertUsing)", typeOut.Name));
                }
                // We are going to return roughly following expression
                // typeOut (typeIn)x => (typeOut)(typeMap.CustomMapper.Invoke(new ResolutionContext(typeMap, x, typeIn, typeOut, options)))

                // This expression generates a new ResolutionContext
                // for the custom mapper (ResolveCore)
                var context = Expression.MemberInit(
                    Expression.New(
                        typeof(ResolutionContext).GetConstructor(BindingFlags.Instance | BindingFlags.Public, null,
                                                                 new Type[]
                {
                    typeof(TypeMap), typeof(object),
                    typeof(Type),
                    typeof(Type),
                    typeof(MappingOperationOptions)
                },
                                                                 null),
                        new List <Expression>
                {
                    Expression.Constant(typeMap),
                    instanceParameter,             // Using the original parameter
                    Expression.Constant(typeIn),
                    Expression.Constant(typeOut),
                    Expression.Constant(new MappingOperationOptions())
                })
                    );
                // This expression gets the CustomMapper from the typeMap
                Expression <Func <TypeMap, Func <ResolutionContext, object> > > method = x => x.CustomMapper;
                var customMapper = Expression.Invoke(method, Expression.Constant(typeMap));
                // This expression calls the Invoke method from the CustomMapper func
                var invoke = Expression.Call(customMapper,
                                             typeof(Func <ResolutionContext, object>).GetMethod("Invoke"), context);
                // We have to convert the object from Invoke to typeOut
                total = Expression.Convert(invoke, typeOut);
            }
            else
            {
                total = Expression.MemberInit(
                    Expression.New(typeOut),
                    bindings.ToArray()
                    );
            }

            return(Expression.Lambda(total, instanceParameter));
        }