You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2013/07/17 23:12:22 UTC

svn commit: r1504281 - in /tomcat/trunk: java/org/apache/el/parser/AstLambdaExpression.java test/org/apache/el/parser/TestAstLambdaExpression.java

Author: markt
Date: Wed Jul 17 21:12:22 2013
New Revision: 1504281

URL: http://svn.apache.org/r1504281
Log:
More fun and games with nested lambda expressions.
Each invocation of a nested expression consumes a set of method parameters. Therefore nested lambda expressions that are invoked immediately (because they have no formal parameetrs) need to inform the outer expression of the invocation so the next invocation uses the correct method parameters.

Modified:
    tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java
    tomcat/trunk/test/org/apache/el/parser/TestAstLambdaExpression.java

Modified: tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java?rev=1504281&r1=1504280&r2=1504281&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java (original)
+++ tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java Wed Jul 17 21:12:22 2013
@@ -29,6 +29,8 @@ import org.apache.el.util.MessageFactory
 
 public class AstLambdaExpression extends SimpleNode {
 
+    private int methodParameterIndex = 0;
+
     public AstLambdaExpression(int id) {
         super(id);
     }
@@ -73,37 +75,70 @@ public class AstLambdaExpression extends
         LambdaExpression le = new LambdaExpression(formalParameters, ve);
         le.setELContext(ctx);
 
-        if (formalParameters.isEmpty() && jjtGetNumChildren() == 2) {
-            // No formal parameters - invoke the expression
-            return le.invoke(ctx, (Object[]) null);
-        }
-
-        // If there are method parameters, need to invoke the expression with
-        // those parameters. If there are multiple sets of method parameters
-        // there should be at least that many nested expressions.
-        // If there are more nested expressions than sets of method parameters
-        // this may return a LambdaExpression.
-        // If there are more sets of method parameters than nested expressions
-        // an ELException will have been thrown by the check at the start of
-        // this method.
-        // If the inner most expression(s) do not require parameters then a
-        // value will be returned once the outermost expression that does
-        // require a parameter has been evaluated.
-        Object result = le;
-        int i = 2;
-        while (result instanceof LambdaExpression && i < jjtGetNumChildren()) {
-            result = ((LambdaExpression) result).invoke(
-                    ((AstMethodParameters) children[i]).getParameters(ctx));
-            i++;
-            while (i < jjtGetNumChildren() && children[i].jjtGetNumChildren() == 0) {
-                i++;
+        if (jjtGetNumChildren() == 2) {
+            if (formalParameters.isEmpty()) {
+                // No formal parameters or method parameters so invoke the
+                // expression. If this is a nested expression inform the outer
+                // expression that an invocation has occurred so the correct set
+                // of method parameters are used for the next invocation.
+                incMethodParameterIndex();
+                return le.invoke(ctx, (Object[]) null);
+            } else {
+                // Has formal parameters but no method parameters so return the
+                // expression for later evaluation
+                return le;
             }
         }
 
+
+        // Always have to invoke the outer-most expression
+        methodParameterIndex = 2;
+        Object result = le.invoke(((AstMethodParameters)
+                children[methodParameterIndex]).getParameters(ctx));
+        methodParameterIndex++;
+
+        /*
+         * If there are multiple sets of method parameters there should be at
+         * least that many nested expressions.
+         *
+         * If there are more nested expressions than sets of method parameters
+         * this may return a LambdaExpression.
+         *
+         * If there are more sets of method parameters than nested expressions
+         * an ELException will have been thrown by the check at the start of
+         * this method.
+         *
+         * If the inner most expression(s) do not require parameters then a
+         * value will be returned once the outermost expression that does
+         * require a parameter has been evaluated.
+         *
+         * When invoking an expression if it has nested expressions that do not
+         * have formal parameters then they will be evaluated as as part of that
+         * invocation. In this case the method parameters associated with those
+         * nested expressions need to be skipped.
+         */
+        while (result instanceof LambdaExpression &&
+                methodParameterIndex < jjtGetNumChildren()) {
+            result = ((LambdaExpression) result).invoke(((AstMethodParameters)
+                    children[methodParameterIndex]).getParameters(ctx));
+            methodParameterIndex++;
+        }
+
         return result;
     }
 
 
+    public void incMethodParameterIndex() {
+        Node parent = jjtGetParent();
+        if (parent instanceof AstLambdaExpression) {
+            // Method parameter index is maintained by outermost lambda
+            // expressions as that is where the parameters are
+            ((AstLambdaExpression) parent).incMethodParameterIndex();
+        } else {
+            methodParameterIndex++;
+        }
+    }
+
     @Override
     public String toString() {
         // Purely for debug purposes. May not be complete or correct. Certainly

Modified: tomcat/trunk/test/org/apache/el/parser/TestAstLambdaExpression.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/el/parser/TestAstLambdaExpression.java?rev=1504281&r1=1504280&r2=1504281&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/el/parser/TestAstLambdaExpression.java (original)
+++ tomcat/trunk/test/org/apache/el/parser/TestAstLambdaExpression.java Wed Jul 17 21:12:22 2013
@@ -134,4 +134,14 @@ public class TestAstLambdaExpression {
                         Integer.class);
         Assert.assertEquals(Integer.valueOf(1), result);
     }
+
+
+    @Test
+    public void testNested06() {
+        ELProcessor processor = new ELProcessor();
+        Object result =
+                processor.getValue("(()->y->()->()->x->x-y)()(1)()(3)(2)",
+                        Integer.class);
+        Assert.assertEquals(Integer.valueOf(1), result);
+    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org