private static AstNode ModifyLambdaForMinMax(LambdaExpression lambdaExpression,
                                                     ParenthesizedExpression parenthesizedlambdaExpression)
        {
            var node           = new CastExpression(new SimpleType("Func<dynamic, IComparable>"), parenthesizedlambdaExpression.Clone());
            var castExpression = GetAsCastExpression(lambdaExpression.Body);

            if (castExpression != null)
            {
                var castToType = new SimpleType("Func", new SimpleType("dynamic"), castExpression.Type.Clone());
                node = new CastExpression(castToType, parenthesizedlambdaExpression.Clone());
            }
            return(node);
        }
        private static AstNode ModifyLambdaForSelect(ParenthesizedExpression parenthesizedlambdaExpression,
                                                     MemberReferenceExpression target)
        {
            var parentInvocation = target.Target as InvocationExpression;

            if (parentInvocation != null)
            {
                var parentTarget = parentInvocation.Target as MemberReferenceExpression;
                if (parentTarget != null && parentTarget.MemberName == "GroupBy")
                {
                    return(new CastExpression(new SimpleType("Func<IGrouping<dynamic,dynamic>, dynamic>"), parenthesizedlambdaExpression.Clone()));
                }
            }
            return(new CastExpression(new SimpleType("Func<dynamic, dynamic>"), parenthesizedlambdaExpression.Clone()));
        }
        private static AstNode ModifyLambdaForNumerics(LambdaExpression lambdaExpression,
                                                       ParenthesizedExpression parenthesizedlambdaExpression)
        {
            var castExpression = GetAsCastExpression(lambdaExpression.Body);

            if (castExpression != null)
            {
                var castToType = new SimpleType("Func", new SimpleType("dynamic"), castExpression.Type.Clone());
                return(new CastExpression(castToType, parenthesizedlambdaExpression.Clone()));
            }
            var expression = new LambdaExpression
            {
                Body = new CastExpression(new PrimitiveType("decimal"), new ParenthesizedExpression((Expression)lambdaExpression.Body.Clone())),
            };

            expression.Parameters.AddRange(lambdaExpression.Parameters.Select(x => (ParameterDeclaration)x.Clone()));

            return(new CastExpression(new SimpleType("Func<dynamic, decimal>"),
                                      new ParenthesizedExpression(expression)));
        }
Esempio n. 4
0
        private static AstNode ModifyLambdaForSelect(ParenthesizedExpression parenthesizedlambdaExpression,
                                                     MemberReferenceExpression target)
        {
            var parentInvocation = target.Target as InvocationExpression;

            if (parentInvocation != null)
            {
                var parentTarget = parentInvocation.Target as MemberReferenceExpression;
                if (parentTarget != null)
                {
                    if (parentTarget.MemberName == "GroupBy")
                    {
                        return(new CastExpression(new SimpleType("Func<IGrouping<dynamic,dynamic>, dynamic>"), parenthesizedlambdaExpression.Clone()));
                    }

                    if (parentTarget.MemberName == "Range")
                    {
                        var identifierExpression = parentTarget.Target as IdentifierExpression;
                        if (identifierExpression != null && identifierExpression.Identifier == "Enumerable")
                        {
                            // support for Enumerable.Range(x, y).Select()

                            // convert Enumerable.Range(x, y) to Enumerable.Range(x, y).Cast<dynamic>()

                            var enumerableRange = parentInvocation.Clone();

                            var castToDynamic = new MemberReferenceExpression(enumerableRange, "Cast", new AstType[] { new SimpleType("dynamic") });

                            var dynamicEnumerableRange = new InvocationExpression(castToDynamic);

                            parentInvocation.ReplaceWith(dynamicEnumerableRange);
                        }
                    }
                }
            }
            return(new CastExpression(new SimpleType("Func<dynamic, dynamic>"), parenthesizedlambdaExpression.Clone()));
        }
        private static AstNode ModifyLambdaForSelectMany(LambdaExpression lambdaExpression,
                                                         ParenthesizedExpression parenthesizedlambdaExpression,
                                                         InvocationExpression invocationExpression)
        {
            AstNode node = lambdaExpression;

            if (invocationExpression.Arguments.Count > 0 && invocationExpression.Arguments.ElementAt(0) == lambdaExpression)           // first one, select the collection
            {
                // need to enter a cast for (IEnumerable<dynamic>) on the end of the lambda body
                var selectManyExpression = new LambdaExpression
                {
                    Body =
                        new CastExpression(new SimpleType("IEnumerable<dynamic>"),
                                           new ParenthesizedExpression((Expression)lambdaExpression.Body.Clone())),
                };
                selectManyExpression.Parameters.AddRange(lambdaExpression.Parameters.Select(x => (ParameterDeclaration)x.Clone()));

                node = new CastExpression(new SimpleType("Func<dynamic, IEnumerable<dynamic>>"),
                                          new ParenthesizedExpression(selectManyExpression.Clone()));
            }
            else if (invocationExpression.Arguments.Count > 1 && invocationExpression.Arguments.ElementAt(1) == lambdaExpression)            // first one, select the collection
            {
                node = new CastExpression(new SimpleType("Func<dynamic, dynamic, dynamic>"), parenthesizedlambdaExpression.Clone());
            }
            return(node);
        }
        public override object VisitLambdaExpression(LambdaExpression lambdaExpression, object data)
        {
            var invocationExpression = lambdaExpression.Parent as InvocationExpression;

            if (invocationExpression == null)
            {
                return(base.VisitLambdaExpression(lambdaExpression, data));
            }

            var target = invocationExpression.Target as MemberReferenceExpression;

            if (target == null)
            {
                return(base.VisitLambdaExpression(lambdaExpression, data));
            }

            AstNode node = lambdaExpression;
            var     parenthesizedlambdaExpression = new ParenthesizedExpression(lambdaExpression.Clone());

            switch (target.MemberName)
            {
            case "Sum":
            case "Average":
                node = ModifyLambdaForNumerics(lambdaExpression, parenthesizedlambdaExpression);
                break;

            case "Max":
            case "Min":
                node = ModifyLambdaForMinMax(lambdaExpression, parenthesizedlambdaExpression);
                break;

            case "OrderBy":
            case "OrderByDescending":
            case "GroupBy":
            case "Recurse":
            case "Select":
                node = ModifyLambdaForSelect(parenthesizedlambdaExpression, target);
                break;

            case "SelectMany":
                node = ModifyLambdaForSelectMany(lambdaExpression, parenthesizedlambdaExpression, invocationExpression);
                break;

            case "Any":
            case "all":
            case "First":
            case "FirstOrDefault":
            case "Last":
            case "LastOfDefault":
            case "Single":
            case "Where":
            case "Count":
            case "SingleOrDefault":
                node = new CastExpression(new SimpleType("Func<dynamic, bool>"), parenthesizedlambdaExpression.Clone());
                break;
            }
            lambdaExpression.ReplaceWith(node);

            if (node != lambdaExpression)
            {
                return(node.AcceptVisitor(this, null));
            }
            return(base.VisitLambdaExpression(lambdaExpression, null));
        }