public void TestLambdaExpressionAccept() { Mock <KoraliumSqlVisitor> mock = new Mock <KoraliumSqlVisitor>(); LambdaExpression lambdaExpression = new LambdaExpression(); lambdaExpression.Accept(mock.Object); mock.Verify(x => x.VisitLambdaExpression(lambdaExpression)); }
// 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)); }
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)); }
// 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)); }
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); }
/// <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))); }
public void VisitorWithReturnIsImplemented() { var sut = new LambdaExpression(); sut.Accept(23).VerifyWithReturn(v => v.Visit(sut, 23)); }