2013/7/16 <ma...@apache.org>
>
> Author: markt
> Date: Tue Jul 16 20:01:47 2013
> New Revision: 1503857
>
> URL: http://svn.apache.org/r1503857
> Log:
> Fix handling of nested lambda expressions with method parameters.
>
> Removed:
>
tomcat/trunk/java/org/apache/el/parser/AstLambdaExpressionOrInvocation.java
> Modified:
>     tomcat/trunk/java/javax/el/LambdaExpression.java
>     tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java
>     tomcat/trunk/java/org/apache/el/parser/ELParser.java
>     tomcat/trunk/java/org/apache/el/parser/ELParser.jjt
>     tomcat/trunk/java/org/apache/el/parser/ELParserTreeConstants.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=1503857&r1=1503856&r2=1503857&view=diff
>
==============================================================================
> --- tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java
(original)
> +++ tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java Tue
Jul 16 20:01:47 2013
> @@ -35,11 +35,15 @@ public class AstLambdaExpression extends
>      @Override
>      public Object getValue(EvaluationContext ctx) throws ELException {
>
> -        // Two children - the formal parameters and the expression
> +        // First child is always parameters even if there aren't any
>          AstLambdaParameters formalParametersNode =
>                  (AstLambdaParameters) children[0];
>          Node[] formalParamNodes = formalParametersNode.children;
>
> +        // Second child is a value expression
> +        ValueExpressionImpl ve = new ValueExpressionImpl("", children[1],
> +                ctx.getFunctionMapper(), ctx.getVariableMapper(), null);
> +
>          // Build a LambdaExpression
>          List<String> formalParameters = new ArrayList<>();
>          if (formalParamNodes != null) {
> @@ -47,30 +51,29 @@ public class AstLambdaExpression extends
>                  formalParameters.add(formalParamNode.getImage());
>              }
>          }
> -
> -        ValueExpressionImpl ve = new ValueExpressionImpl("", children[1],
> -                ctx.getFunctionMapper(), ctx.getVariableMapper(), null);
>          LambdaExpression le = new LambdaExpression(formalParameters, ve);
>          le.setELContext(ctx);
>
>          if (formalParameters.isEmpty()) {
> -            // No formal parameters - should be able to simply invoke
this
> +            // No formal parameters - invoke the expression
>              return le.invoke(ctx, (Object[]) null);
> -        } else {
> -            // Has parameters but they aren't provided so return the
> -            // LambdaExpression
> -            return le;
>          }
> -    }
>
> -    @Override
> -    public Object invoke(EvaluationContext ctx, Class<?>[] paramTypes,
> -            Object[] paramValues) throws ELException {
> -
> -        Object result = getValue(ctx);
> +        // If there are method parameters, need to invoke the expression
with
> +        // those parameters. If there are multiple method parameters
there
> +        // should be that many nested expressions.
> +        // If there are more nested expressions that parameters this
will return
> +        // a LambdaExpression
> +        Object result = le;
> +        int i = 2;
> +        while (result instanceof LambdaExpression && i <
jjtGetNumChildren()) {
> +            result = ((LambdaExpression) result).invoke(
> +                    ((AstMethodParameters)
children[i]).getParameters(ctx));
> +            i++;
> +        }
>
> -        if (result instanceof LambdaExpression) {
> -            result = ((LambdaExpression) result).invoke(ctx,
paramValues);
> +        if (i < jjtGetNumChildren()) {
> +            throw new ELException();
>          }
>
>          return result;


Having the example from the test:
(x->y->x-y)(2)(1)

We may transform it like this:
(()->y->2-y)()(1)

So instead of returning right way when formalParameters.isEmpty()

Shouldn't we have something like the one below in order to continue
evaluation of the nested expression:



--- org/apache/el/parser/AstLambdaExpression.java (revision 1504024)
+++ org/apache/el/parser/AstLambdaExpression.java (working copy)
@@ -54,9 +54,12 @@
         LambdaExpression le = new LambdaExpression(formalParameters, ve);
         le.setELContext(ctx);

+        Object result = le;
+        int i = 2;
         if (formalParameters.isEmpty()) {
             // No formal parameters - invoke the expression
-            return le.invoke(ctx, (Object[]) null);
+            result = ((LambdaExpression) result).invoke(ctx, (Object[])
null);
+            i++;
         }

         // If there are method parameters, need to invoke the expression
with
@@ -64,8 +67,6 @@
         // should be that many nested expressions.
         // If there are more nested expressions that parameters this will
return
         // a LambdaExpression
-        Object result = le;
-        int i = 2;
         while (result instanceof LambdaExpression && i <
jjtGetNumChildren()) {
             result = ((LambdaExpression) result).invoke(
                     ((AstMethodParameters)
children[i]).getParameters(ctx));


Regards
Violeta

>
> 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=1503857&r1=1503856&r2=1503857&view=diff
>
==============================================================================
> --- tomcat/trunk/test/org/apache/el/parser/TestAstLambdaExpression.java
(original)
> +++ tomcat/trunk/test/org/apache/el/parser/TestAstLambdaExpression.java
Tue Jul 16 20:01:47 2013
> @@ -64,4 +64,14 @@ public class TestAstLambdaExpression {
>                          Integer.class);
>          Assert.assertEquals(Integer.valueOf(120), result);
>      }
> +
> +
> +    @Test
> +    public void testSpec06() {
> +        ELProcessor processor = new ELProcessor();
> +        Object result =
> +                processor.getValue("(x->y->x-y)(2)(1)",
> +                        Integer.class);
> +        Assert.assertEquals(Integer.valueOf(1), result);
> +    }
>  }
>

Reply via email to