Author: markt
Date: Fri Jul 19 11:23:37 2013
New Revision: 1504834
URL: http://svn.apache.org/r1504834
Log:
Do the scanning to count nesting levels and presence of formal parameters just
once.
Simplify the checks during getValue() using the results of this new scan.
Modified:
tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.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=1504834&r1=1504833&r2=1504834&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java (original)
+++ tomcat/trunk/java/org/apache/el/parser/AstLambdaExpression.java Fri Jul 19
11:23:37 2013
@@ -29,6 +29,8 @@ import org.apache.el.util.MessageFactory
public class AstLambdaExpression extends SimpleNode {
+ private NestedState nestedState = null;
+
public AstLambdaExpression(int id) {
super(id);
}
@@ -36,40 +38,17 @@ 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
- // - if any of the nested expressions declare formal parameters
+ // Correct evaluation requires knowledge of the whole set of nested
+ // expressions, not just the current expression
+ NestedState state = getNestedState();
+
+ // Check that there are not more sets of parameters than there are
+ // nested expressions.
int methodParameterSetCount = jjtGetNumChildren() - 2;
- 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);
- } else {
- n = null;
- }
- }
- if (methodParameterSetCount > lambdaExpressionCount) {
+ if (methodParameterSetCount > state.getNestingCount()) {
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
AstLambdaParameters formalParametersNode =
@@ -91,17 +70,27 @@ public class AstLambdaExpression extends
le.setELContext(ctx);
if (jjtGetNumChildren() == 2) {
- 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
- // expression so return the expression for later evaluation
+ // No method parameters
+ // Can only invoke the expression if none of the lambda expressions
+ // in the nesting declare parameters
+ if (state.getHasFormalParameters()) {
return le;
+ } else {
+ return le.invoke(ctx, (Object[]) null);
}
}
+ /*
+ * This is a (possibly nested) lambda expression with one or more sets
+ * of parameters provided.
+ *
+ * If there are more nested expressions than sets of parameters this
may
+ * return a LambdaExpression.
+ *
+ * If there are more sets of parameters than nested expressions an
+ * ELException will have been thrown by the check at the start of this
+ * method.
+ */
// Always have to invoke the outer-most expression
int methodParameterIndex = 2;
@@ -109,21 +98,6 @@ public class AstLambdaExpression extends
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.
- */
while (result instanceof LambdaExpression &&
methodParameterIndex < jjtGetNumChildren()) {
result = ((LambdaExpression) result).invoke(((AstMethodParameters)
@@ -135,6 +109,42 @@ public class AstLambdaExpression extends
}
+ private NestedState getNestedState() {
+ if (nestedState == null) {
+ setNestedState(new NestedState());
+ }
+ return nestedState;
+ }
+
+
+ private void setNestedState(NestedState nestedState) {
+ if (this.nestedState != null) {
+ // Should never happen
+ throw new IllegalStateException("nestedState may only be set
once");
+ }
+ this.nestedState = nestedState;
+
+ // Increment the nesting count for the current expression
+ nestedState.incrementNestingCount();
+
+ if (jjtGetNumChildren() > 1) {
+ Node firstChild = jjtGetChild(0);
+ if (firstChild instanceof AstLambdaParameters) {
+ if (firstChild.jjtGetNumChildren() > 0) {
+ nestedState.setHasFormalParameters();
+ }
+ } else {
+ // Can't be a lambda expression
+ return;
+ }
+ Node secondChild = jjtGetChild(1);
+ if (secondChild instanceof AstLambdaExpression) {
+ ((AstLambdaExpression)
secondChild).setNestedState(nestedState);
+ }
+ }
+ }
+
+
@Override
public String toString() {
// Purely for debug purposes. May not be complete or correct. Certainly
@@ -145,5 +155,28 @@ public class AstLambdaExpression extends
}
return result.toString();
}
+
+
+ private static class NestedState {
+
+ private int nestingCount = 0;
+ private boolean hasFormalParameters = false;
+
+ private void incrementNestingCount() {
+ nestingCount++;
+ }
+
+ private int getNestingCount() {
+ return nestingCount;
+ }
+
+ private void setHasFormalParameters() {
+ hasFormalParameters = true;
+ }
+
+ private boolean getHasFormalParameters() {
+ return hasFormalParameters;
+ }
+ }
}
/* JavaCC - OriginalChecksum=071159eff10c8e15ec612c765ae4480a (do not edit
this line) */
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]