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 AstNode VisitLambdaExpression(LambdaExpression lambdaExpression)
        {
            var clonLambdaExpression = (LambdaExpression)base.VisitLambdaExpression(lambdaExpression);

            if (clonLambdaExpression != null)
            {
                lambdaExpression = clonLambdaExpression;
            }

            if (lambdaExpression.Body.IsNull)
            {
                var l = (LambdaExpression)lambdaExpression.Clone();
                l.Body = new IdentifierExpression(lambdaExpression.Parameters.Last().Name);

                return(l);
            }

            return(lambdaExpression.Clone());
        }
Ejemplo n.º 3
0
        public void TestCloneLambdaExpression()
        {
            LambdaExpression lambdaExpression = new LambdaExpression()
            {
                Expression = new BooleanLiteral()
                {
                    Value = true
                },
                Parameters = new List <string>()
                {
                    "p1"
                }
            };

            var clone = lambdaExpression.Clone() as LambdaExpression;

            Assert.IsFalse(ReferenceEquals(lambdaExpression, clone));
            Assert.IsFalse(ReferenceEquals(lambdaExpression.Expression, clone.Expression));
            Assert.IsFalse(ReferenceEquals(lambdaExpression.Parameters, clone.Parameters));
            Assert.AreEqual(lambdaExpression, clone);
        }
        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));
        }