2013/7/16 <[email protected]>
>
> 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);
> + }
> }
>