예제 #1
0
        public void TestLambdaExpressionAccept()
        {
            Mock <KoraliumSqlVisitor> mock             = new Mock <KoraliumSqlVisitor>();
            LambdaExpression          lambdaExpression = new LambdaExpression();

            lambdaExpression.Accept(mock.Object);
            mock.Verify(x => x.VisitLambdaExpression(lambdaExpression));
        }
예제 #2
0
        // InvocationExpression
        private Result RewriteInvocationExpression(Expression expr, Stack stack)
        {
            InvocationExpression node = (InvocationExpression)expr;

            ChildRewriter cr;

#if LINQ // NB: Our compiler doesn't inline; this could still happen at a later stage in the LINQ compiler after lowering async lambdas to sync ones.
            // See if the lambda will be inlined
            LambdaExpression lambda = node.LambdaOperand();
            if (lambda != null)
            {
                // Arguments execute on current stack
                cr = new ChildRewriter(this, stack, node.Arguments.Count);
                cr.Add(node.Arguments);

                if (cr.Action == RewriteAction.SpillStack)
                {
                    RequireNoRefArgs(ExpressionStubs.GetInvokeMethod(node.Expression));
                }

                // Lambda body also executes on current stack
                var spiller = new StackSpiller(stack);
                lambda = lambda.Accept(spiller);

                if (cr.Rewrite || spiller._lambdaRewrite != RewriteAction.None)
                {
                    node = node.Rewrite(lambda, cr[0, -1]);
                }

                Result result = cr.Finish(node);
                return(new Result(result.Action | spiller._lambdaRewrite, result.Node));
            }
#endif

            cr = new ChildRewriter(this, stack, node.Arguments.Count + 1);

            // first argument starts on stack as provided
            cr.Add(node.Expression);

            // rest of arguments have non-empty stack (delegate instance on the stack)
            cr.Add(node.Arguments);

            if (cr.Action == RewriteAction.SpillStack)
            {
#if LINQ
                RequireNoRefArgs(ExpressionStubs.GetInvokeMethod(node.Expression));
#else
                MarkRefArgs(cr, ExpressionStubs.GetInvokeMethod(node.Expression), 1);
#endif
            }

            return(cr.Finish(cr.Rewrite ? node.Rewrite(cr[0], cr[1, -1]) : expr));
        }
예제 #3
0
        private Result RewriteInvocationExpression(Expression expr, Stack stack)
        {
            var node = (InvocationExpression)expr;

            ChildRewriter cr;

            // See if the lambda will be inlined.
            LambdaExpression lambda = node.LambdaOperand;

            if (lambda != null)
            {
                // Arguments execute on current stack.
                cr = new ChildRewriter(this, stack, node.ArgumentCount);
                cr.AddArguments(node);

                if (cr.Action == RewriteAction.SpillStack)
                {
                    cr.MarkRefArgs(Expression.GetInvokeMethod(node.Expression), startIndex: 0);
                }

                // Lambda body also executes on current stack.
                var spiller = new StackSpiller(stack);
                lambda = lambda.Accept(spiller);

                if (cr.Rewrite || spiller._lambdaRewrite != RewriteAction.None)
                {
                    node = new InvocationExpressionN(lambda, cr[0, -1], node.Type);
                }

                Result result = cr.Finish(node);
                return(new Result(result.Action | spiller._lambdaRewrite, result.Node));
            }

            cr = new ChildRewriter(this, stack, node.ArgumentCount + 1);

            // First argument starts on stack as provided.
            cr.Add(node.Expression);

            // Rest of arguments have non-empty stack (the delegate instance is on the stack).
            cr.AddArguments(node);

            if (cr.Action == RewriteAction.SpillStack)
            {
                cr.MarkRefArgs(Expression.GetInvokeMethod(node.Expression), startIndex: 1);
            }

            return(cr.Finish(cr.Rewrite ? new InvocationExpressionN(cr[0], cr[1, -1], node.Type) : expr));
        }
예제 #4
0
        // InvocationExpression
        private Result RewriteInvocationExpression(Expression expr, Stack stack)
        {
            InvocationExpression node = (InvocationExpression)expr;

            ChildRewriter cr;

            // See if the lambda will be inlined
            LambdaExpression lambda = node.LambdaOperand;

            if (lambda != null)
            {
                // Arguments execute on current stack
                cr = new ChildRewriter(this, stack, node.Arguments.Count);
                cr.Add(node.Arguments);

                if (cr.Action == RewriteAction.SpillStack)
                {
                    RequireNoRefArgs(Expression.GetInvokeMethod(node.Expression));
                }

                // Lambda body also executes on current stack
                var spiller = new StackSpiller(stack);
                lambda = lambda.Accept(spiller);

                if (cr.Rewrite || spiller._lambdaRewrite != RewriteAction.None)
                {
                    node = node.Rewrite(lambda, cr[0, -1]);
                }

                Result result = cr.Finish(node);
                return(new Result(result.Action | spiller._lambdaRewrite, result.Node));
            }

            cr = new ChildRewriter(this, stack, node.Arguments.Count + 1);

            // first argument starts on stack as provided
            cr.Add(node.Expression);

            // rest of arguments have non-empty stack (delegate instance on the stack)
            cr.Add(node.Arguments);

            if (cr.Action == RewriteAction.SpillStack)
            {
                RequireNoRefArgs(Expression.GetInvokeMethod(node.Expression));
            }

            return(cr.Finish(cr.Rewrite ? node.Rewrite(cr[0], cr[1, -1]) : expr));
        }
예제 #5
0
        public void TestLambdas()
        {
            SortedSet <string> variables;
            var test = new LambdaExpression("x", x);
            VariableLister <bool> lister = new VariableLister <bool>();

            test.Accept(lister);
            Assert.AreEqual(1, lister.Variables.Count);
            Assert.IsTrue(lister.Variables.Contains("x"));

            test = new LambdaExpression("x", x);
            FreeVariableLister freeLister = new FreeVariableLister();

            variables = test.Accept(freeLister);
            Assert.AreEqual(0, variables.Count);

            test       = new LambdaExpression("x", logicLoop);
            freeLister = new FreeVariableLister();
            variables  = test.Accept(freeLister);
            Assert.AreEqual(0, variables.Count);
        }
예제 #6
0
 /// <summary>
 /// Analyzes a lambda, producing a new one that has correct invariants
 /// for codegen. In particular, it spills the IL stack to temps in
 /// places where it's invalid to have a non-empty stack (for example,
 /// entering a try statement).
 /// </summary>
 internal static LambdaExpression AnalyzeLambda(LambdaExpression lambda)
 {
     return(lambda.Accept(new StackSpiller(Stack.Empty)));
 }
예제 #7
0
        public void VisitorWithReturnIsImplemented()
        {
            var sut = new LambdaExpression();

            sut.Accept(23).VerifyWithReturn(v => v.Visit(sut, 23));
        }