Author: markt
Date: Thu Jul 18 20:56:44 2013
New Revision: 1504657
URL: http://svn.apache.org/r1504657
Log:
Yet more adventures with lambda expressions.
I suspect - but haven't yet checked - that there is scope to make the code more
efficient and/or reduce duplication.
Modified:
tomcat/trunk/java/org/apache/el/parser/AstFunction.java
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/AstFunction.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/el/parser/AstFunction.java?rev=1504657&r1=1504656&r2=1504657&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/el/parser/AstFunction.java (original)
+++ tomcat/trunk/java/org/apache/el/parser/AstFunction.java Thu Jul 18 20:56:44
2013
@@ -98,12 +98,18 @@ public final class AstFunction extends S
// Build arguments
int i = 0;
while (obj instanceof LambdaExpression &&
- i < this.jjtGetNumChildren()) {
+ i < jjtGetNumChildren()) {
Node args = jjtGetChild(i);
obj = ((LambdaExpression) obj).invoke(
((AstMethodParameters) args).getParameters(ctx));
i++;
}
+ if (i < jjtGetNumChildren()) {
+ // Haven't consumed all the sets of parameters therefore
+ // there were too many sets of parameters
+ throw new ELException(MessageFactory.get(
+ "error.lambda.tooManyMethodParameterSets"));
+ }
return obj;
}
}
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=1504657&r1=1504656&r2=1504657&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java (original)
+++ tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java Thu Jul 18
20:56:44 2013
@@ -36,22 +36,39 @@ public class AstLambdaExpression extends
@Override
public Object getValue(EvaluationContext ctx) throws ELException {
- // Check that there are not more sets of method parameters than there
- // are nested lambda expressions
+ // Check;
+ // - that there are not more sets of method parameters than there are
+ // nested lambda expressions
+ // - if any of the nested expressions declare formal parameters
int methodParameterSetCount = jjtGetNumChildren() - 2;
- if (methodParameterSetCount > 0) {
- // We know this node is an expression
- methodParameterSetCount--;
- Node n = this.jjtGetChild(1);
- while (methodParameterSetCount > 0) {
- if (n.jjtGetNumChildren() <2 ||
- !(n.jjtGetChild(0) instanceof AstLambdaParameters)) {
- throw new ELException(MessageFactory.get(
- "error.lambda.tooManyMethodParameterSets"));
+ boolean declaresParameters = false;
+ // We know this node is an expression
+ int lambdaExpressionCount = 1;
+ // child at index 1 is the expression
+ Node n = jjtGetChild(1);
+ while (n instanceof AstLambdaExpression) {
+ lambdaExpressionCount++;
+ if (n.jjtGetChild(0) instanceof AstLambdaParameters) {
+ if (!declaresParameters &&
+ n.jjtGetChild(0).jjtGetNumChildren() > 0) {
+ declaresParameters = true;
}
n = n.jjtGetChild(1);
- methodParameterSetCount--;
+ } else {
+ n = null;
+ }
+ }
+ if (methodParameterSetCount > lambdaExpressionCount) {
+ throw new ELException(MessageFactory.get(
+ "error.lambda.tooManyMethodParameterSets"));
+ }
+ // Also need to check parents for declaration of formal parameters
+ n = parent;
+ while (!declaresParameters && n instanceof AstLambdaExpression) {
+ if (n.jjtGetChild(0).jjtGetNumChildren() > 0) {
+ declaresParameters = true;
}
+ n = n.jjtGetParent();
}
// First child is always parameters even if there aren't any
@@ -74,10 +91,9 @@ public class AstLambdaExpression extends
le.setELContext(ctx);
if (jjtGetNumChildren() == 2) {
- if (formalParameters.isEmpty() &&
- !(parent instanceof AstLambdaExpression)) {
- // No formal parameters or method parameters and not a nested
- // expression so invoke the expression.
+ if (formalParameters.isEmpty() && !declaresParameters) {
+ // No formal parameters or method parameters and not nested
+ // inside another lambda expression so invoke the expression.
return le.invoke(ctx, (Object[]) null);
} else {
// Has formal parameters but no method parameters or is a
nested
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=1504657&r1=1504656&r2=1504657&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/el/parser/TestAstLambdaExpression.java
(original)
+++ tomcat/trunk/test/org/apache/el/parser/TestAstLambdaExpression.java Thu Jul
18 20:56:44 2013
@@ -147,11 +147,80 @@ public class TestAstLambdaExpression {
@Test
- public void testLambdaAsFunction() {
+ public void testNested07() {
+ ELProcessor processor = new ELProcessor();
+ Object result =
+ processor.getValue("()->()->()->42",
+ Integer.class);
+ Assert.assertEquals(Integer.valueOf(42), result);
+ }
+
+
+ @Test
+ public void testLambdaAsFunction01() {
ELProcessor processor = new ELProcessor();
Object result =
processor.getValue("v = (x->y->x-y); v(2)(1)",
Integer.class);
Assert.assertEquals(Integer.valueOf(1), result);
}
+
+
+ @Test
+ public void testLambdaAsFunction02() {
+ ELProcessor processor = new ELProcessor();
+ Object result =
+ processor.getValue("v = (()->y->2-y); v()(1)",
+ Integer.class);
+ Assert.assertEquals(Integer.valueOf(1), result);
+ }
+
+
+ @Test
+ public void testLambdaAsFunction03() {
+ ELProcessor processor = new ELProcessor();
+ Object result =
+ processor.getValue("v = (()->y->()->2-y); v()(1)()",
+ Integer.class);
+ Assert.assertEquals(Integer.valueOf(1), result);
+ }
+
+
+ @Test(expected=ELException.class)
+ public void testLambdaAsFunction04() {
+ ELProcessor processor = new ELProcessor();
+ // More method parameters than there are nested lambda expressions
+ processor.getValue("v = (()->y->()->2-y); v()(1)()()",
+ Integer.class);
+ }
+
+
+ @Test
+ public void testLambdaAsFunction05() {
+ ELProcessor processor = new ELProcessor();
+ Object result =
+ processor.getValue("v = (()->y->()->x->x-y); v()(1)()(2)",
+ Integer.class);
+ Assert.assertEquals(Integer.valueOf(1), result);
+ }
+
+
+ @Test
+ public void testLambdaAsFunction06() {
+ ELProcessor processor = new ELProcessor();
+ Object result =
+ processor.getValue("v = (()->y->()->()->x->x-y);
v()(1)()()(2)",
+ Integer.class);
+ Assert.assertEquals(Integer.valueOf(1), result);
+ }
+
+
+ @Test
+ public void testLambdaAsFunction07() {
+ ELProcessor processor = new ELProcessor();
+ Object result =
+ processor.getValue("v = (()->y->()->()->x->x-y);
v()(1)()(3)(2)",
+ Integer.class);
+ Assert.assertEquals(Integer.valueOf(1), result);
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]