protected override Expression VisitMethodCall(MethodCallExpression node)
        {
            var parameterExpression = node.GetParameterExpression();

            if (parameterExpression == null)
            {
                return(base.VisitMethodCall(node));
            }

            InfoDictionary.Add(parameterExpression, TypeMappings);

            var listOfArgumentsForNewMethod = node.Arguments.Aggregate(new List <Expression>(), (lst, next) =>
            {
                var mappedNext = ArgumentMapper.Create(this, next).MappedArgumentExpression;
                TypeMappings.AddTypeMapping(next.Type, mappedNext.Type);

                lst.Add(mappedNext);
                return(lst);
            });//Arguments could be expressions or other objects. e.g. s => s.UserId  or a string "ZZZ".  For extention methods node.Arguments[0] is usually the helper object itself

            //type args are the generic type args e.g. T1 and T2 MethodName<T1, T2>(method arguments);
            var typeArgsForNewMethod = node.Method.IsGenericMethod
                ? node.Method.GetGenericArguments().Select(i => TypeMappings.ContainsKey(i) ? TypeMappings[i] : i).ToList()//not converting the type it is not in the typeMappings dictionary
                : null;

            MethodCallExpression resultExp;

            if (!node.Method.IsStatic)
            {
                var instance = ArgumentMapper.Create(this, node.Object).MappedArgumentExpression;

                resultExp = node.Method.IsGenericMethod
                    ? Expression.Call(instance, node.Method.Name, typeArgsForNewMethod.ToArray(), listOfArgumentsForNewMethod.ToArray())
                    : Expression.Call(instance, node.Method, listOfArgumentsForNewMethod.ToArray());
            }
            else
            {
                resultExp = node.Method.IsGenericMethod
                    ? Expression.Call(node.Method.DeclaringType, node.Method.Name, typeArgsForNewMethod.ToArray(), listOfArgumentsForNewMethod.ToArray())
                    : Expression.Call(node.Method, listOfArgumentsForNewMethod.ToArray());
            }

            return(resultExp);
        }
示例#2
0
        protected override Expression VisitMethodCall(MethodCallExpression node)
        {
            var parameterExpression = node.GetParameterExpression();

            if (parameterExpression != null)
            {
                InfoDictionary.Add(parameterExpression, TypeMappings);
            }

            var listOfArgumentsForNewMethod = node.Arguments.Aggregate(new List <Expression>(), (lst, next) =>
            {
                var mappedNext = this.Visit(next);
                TypeMappings.AddTypeMapping(ConfigurationProvider, next.Type, mappedNext.Type);

                lst.Add(mappedNext);
                return(lst);
            });//Arguments could be expressions or other objects. e.g. s => s.UserId  or a string "ZZZ".  For extention methods node.Arguments[0] is usually the helper object itself

            //type args are the generic type args e.g. T1 and T2 MethodName<T1, T2>(method arguments);
            var typeArgsForNewMethod = node.Method.IsGenericMethod
                ? node.Method.GetGenericArguments().Select(type => this.TypeMappings.ReplaceType(type)).ToList()//not converting the type it is not in the typeMappings dictionary
                : null;

            ConvertTypesIfNecessary(node.Method.GetParameters(), listOfArgumentsForNewMethod, node.Method);

            return(node.Method.IsStatic
                    ? GetStaticExpression()
                    : GetInstanceExpression(this.Visit(node.Object)));

            MethodCallExpression GetInstanceExpression(Expression instance)
            => node.Method.IsGenericMethod
                    ? Expression.Call(instance, node.Method.Name, typeArgsForNewMethod.ToArray(), listOfArgumentsForNewMethod.ToArray())
                    : Expression.Call(instance, node.Method, listOfArgumentsForNewMethod.ToArray());

            MethodCallExpression GetStaticExpression()
            => node.Method.IsGenericMethod
                    ? Expression.Call(node.Method.DeclaringType, node.Method.Name, typeArgsForNewMethod.ToArray(), listOfArgumentsForNewMethod.ToArray())
                    : Expression.Call(node.Method, listOfArgumentsForNewMethod.ToArray());
        }
        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 (!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);
            }

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