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/javax/el/LambdaExpression.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/javax/el/LambdaExpression.java?rev=1503857&r1=1503856&r2=1503857&view=diff ============================================================================== --- tomcat/trunk/java/javax/el/LambdaExpression.java (original) +++ tomcat/trunk/java/javax/el/LambdaExpression.java Tue Jul 16 20:01:47 2013 @@ -24,12 +24,14 @@ public class LambdaExpression { private final List<String> formalParameters; private final ValueExpression expression; + private final Map<String,Object> nestedArguments = new HashMap<>(); private ELContext context = null; public LambdaExpression(List<String> formalParameters, ValueExpression expression) { this.formalParameters = formalParameters; this.expression = expression; + } public void setELContext(ELContext context) { @@ -62,7 +64,10 @@ public class LambdaExpression { } // Build the argument map + // Start with the arguments from any outer expressions so if there is + // any overlap the local arguments have priority Map<String,Object> lambdaArguments = new HashMap<>(); + lambdaArguments.putAll(nestedArguments); for (int i = 0; i < formalParamCount; i++) { lambdaArguments.put(formalParameters.get(i), args[i]); } @@ -70,7 +75,14 @@ public class LambdaExpression { context.enterLambdaScope(lambdaArguments); try { - return expression.getValue(context); + Object result = expression.getValue(context); + // Make arguments from this expression available to any nested + // expression + if (result instanceof LambdaExpression) { + ((LambdaExpression) result).nestedArguments.putAll( + lambdaArguments); + } + return result; } finally { context.exitLambdaScope(); } 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; Modified: tomcat/trunk/java/org/apache/el/parser/ELParser.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/el/parser/ELParser.java?rev=1503857&r1=1503856&r2=1503857&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/el/parser/ELParser.java (original) +++ tomcat/trunk/java/org/apache/el/parser/ELParser.java Tue Jul 16 20:01:47 2013 @@ -410,13 +410,40 @@ public class ELParser/*@bgen(jjtree)*/im * being bracketed does not mean it is an invocation. */ final public void LambdaExpressionOrInvocation() throws ParseException { - /*@bgen(jjtree) LambdaExpressionOrInvocation */ - AstLambdaExpressionOrInvocation jjtn000 = new AstLambdaExpressionOrInvocation(JJTLAMBDAEXPRESSIONORINVOCATION); + /*@bgen(jjtree) LambdaExpression */ + AstLambdaExpression jjtn000 = new AstLambdaExpression(JJTLAMBDAEXPRESSION); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { jj_consume_token(LPAREN); - LambdaExpression(); + LambdaParameters(); + jj_consume_token(ARROW); + if (jj_2_4(3)) { + LambdaExpression(); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case START_SET_OR_MAP: + case INTEGER_LITERAL: + case FLOATING_POINT_LITERAL: + case STRING_LITERAL: + case TRUE: + case FALSE: + case NULL: + case LPAREN: + case LBRACK: + case NOT0: + case NOT1: + case EMPTY: + case MINUS: + case IDENTIFIER: + Choice(); + break; + default: + jj_la1[8] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } jj_consume_token(RPAREN); label_5: while (true) { @@ -425,7 +452,7 @@ public class ELParser/*@bgen(jjtree)*/im ; break; default: - jj_la1[8] = jj_gen; + jj_la1[9] = jj_gen; break label_5; } MethodParameters(); @@ -459,7 +486,7 @@ public class ELParser/*@bgen(jjtree)*/im Or(); label_6: while (true) { - if (jj_2_4(3)) { + if (jj_2_5(3)) { ; } else { break label_6; @@ -508,7 +535,7 @@ public class ELParser/*@bgen(jjtree)*/im ; break; default: - jj_la1[9] = jj_gen; + jj_la1[10] = jj_gen; break label_7; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -519,7 +546,7 @@ public class ELParser/*@bgen(jjtree)*/im jj_consume_token(OR1); break; default: - jj_la1[10] = jj_gen; + jj_la1[11] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -564,7 +591,7 @@ public class ELParser/*@bgen(jjtree)*/im ; break; default: - jj_la1[11] = jj_gen; + jj_la1[12] = jj_gen; break label_8; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -575,7 +602,7 @@ public class ELParser/*@bgen(jjtree)*/im jj_consume_token(AND1); break; default: - jj_la1[12] = jj_gen; + jj_la1[13] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -622,7 +649,7 @@ public class ELParser/*@bgen(jjtree)*/im ; break; default: - jj_la1[13] = jj_gen; + jj_la1[14] = jj_gen; break label_9; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -636,7 +663,7 @@ public class ELParser/*@bgen(jjtree)*/im jj_consume_token(EQ1); break; default: - jj_la1[14] = jj_gen; + jj_la1[15] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -675,7 +702,7 @@ public class ELParser/*@bgen(jjtree)*/im jj_consume_token(NE1); break; default: - jj_la1[15] = jj_gen; + jj_la1[16] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -705,7 +732,7 @@ public class ELParser/*@bgen(jjtree)*/im } break; default: - jj_la1[16] = jj_gen; + jj_la1[17] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -732,7 +759,7 @@ public class ELParser/*@bgen(jjtree)*/im ; break; default: - jj_la1[17] = jj_gen; + jj_la1[18] = jj_gen; break label_10; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -746,7 +773,7 @@ public class ELParser/*@bgen(jjtree)*/im jj_consume_token(LT1); break; default: - jj_la1[18] = jj_gen; + jj_la1[19] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -785,7 +812,7 @@ public class ELParser/*@bgen(jjtree)*/im jj_consume_token(GT1); break; default: - jj_la1[19] = jj_gen; + jj_la1[20] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -824,7 +851,7 @@ public class ELParser/*@bgen(jjtree)*/im jj_consume_token(LE1); break; default: - jj_la1[20] = jj_gen; + jj_la1[21] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -863,7 +890,7 @@ public class ELParser/*@bgen(jjtree)*/im jj_consume_token(GE1); break; default: - jj_la1[21] = jj_gen; + jj_la1[22] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -893,7 +920,7 @@ public class ELParser/*@bgen(jjtree)*/im } break; default: - jj_la1[22] = jj_gen; + jj_la1[23] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -914,7 +941,7 @@ public class ELParser/*@bgen(jjtree)*/im ; break; default: - jj_la1[23] = jj_gen; + jj_la1[24] = jj_gen; break label_11; } jj_consume_token(CONCAT); @@ -959,7 +986,7 @@ public class ELParser/*@bgen(jjtree)*/im ; break; default: - jj_la1[24] = jj_gen; + jj_la1[25] = jj_gen; break label_12; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -1018,7 +1045,7 @@ public class ELParser/*@bgen(jjtree)*/im } break; default: - jj_la1[25] = jj_gen; + jj_la1[26] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -1042,7 +1069,7 @@ public class ELParser/*@bgen(jjtree)*/im ; break; default: - jj_la1[26] = jj_gen; + jj_la1[27] = jj_gen; break label_13; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -1083,7 +1110,7 @@ public class ELParser/*@bgen(jjtree)*/im jj_consume_token(DIV1); break; default: - jj_la1[27] = jj_gen; + jj_la1[28] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -1122,7 +1149,7 @@ public class ELParser/*@bgen(jjtree)*/im jj_consume_token(MOD1); break; default: - jj_la1[28] = jj_gen; + jj_la1[29] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -1152,7 +1179,7 @@ public class ELParser/*@bgen(jjtree)*/im } break; default: - jj_la1[29] = jj_gen; + jj_la1[30] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -1202,7 +1229,7 @@ public class ELParser/*@bgen(jjtree)*/im jj_consume_token(NOT1); break; default: - jj_la1[30] = jj_gen; + jj_la1[31] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -1271,7 +1298,7 @@ public class ELParser/*@bgen(jjtree)*/im Value(); break; default: - jj_la1[31] = jj_gen; + jj_la1[32] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -1295,7 +1322,7 @@ public class ELParser/*@bgen(jjtree)*/im ; break; default: - jj_la1[32] = jj_gen; + jj_la1[33] = jj_gen; break label_14; } ValueSuffix(); @@ -1342,7 +1369,7 @@ public class ELParser/*@bgen(jjtree)*/im NonLiteral(); break; default: - jj_la1[33] = jj_gen; + jj_la1[34] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -1361,7 +1388,7 @@ public class ELParser/*@bgen(jjtree)*/im BracketSuffix(); break; default: - jj_la1[34] = jj_gen; + jj_la1[35] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -1370,7 +1397,7 @@ public class ELParser/*@bgen(jjtree)*/im MethodParameters(); break; default: - jj_la1[35] = jj_gen; + jj_la1[36] = jj_gen; ; } } @@ -1464,7 +1491,7 @@ public class ELParser/*@bgen(jjtree)*/im ; break; default: - jj_la1[36] = jj_gen; + jj_la1[37] = jj_gen; break label_15; } jj_consume_token(COMMA); @@ -1472,7 +1499,7 @@ public class ELParser/*@bgen(jjtree)*/im } break; default: - jj_la1[37] = jj_gen; + jj_la1[38] = jj_gen; ; } jj_consume_token(RPAREN); @@ -1502,7 +1529,7 @@ public class ELParser/*@bgen(jjtree)*/im * For Grouped Operations, Identifiers, and Functions */ final public void NonLiteral() throws ParseException { - if (jj_2_5(3)) { + if (jj_2_6(3)) { LambdaExpressionOrInvocation(); } else { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -1512,8 +1539,8 @@ public class ELParser/*@bgen(jjtree)*/im jj_consume_token(RPAREN); break; default: - jj_la1[38] = jj_gen; - if (jj_2_6(2147483647)) { + jj_la1[39] = jj_gen; + if (jj_2_7(2147483647)) { Function(); } else { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -1521,8 +1548,8 @@ public class ELParser/*@bgen(jjtree)*/im Identifier(); break; default: - jj_la1[39] = jj_gen; - if (jj_2_7(3)) { + jj_la1[40] = jj_gen; + if (jj_2_8(3)) { SetData(); } else { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -1533,7 +1560,7 @@ public class ELParser/*@bgen(jjtree)*/im MapData(); break; default: - jj_la1[40] = jj_gen; + jj_la1[41] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -1544,6 +1571,11 @@ public class ELParser/*@bgen(jjtree)*/im } } +/* + * Note that both an empty Set and an empty Map are represented by {}. The + * parser will always parse {} as an empty Set and special handling is required + * to convert it to an empty Map when appropriate. + */ final public void SetData() throws ParseException { /*@bgen(jjtree) SetData */ AstSetData jjtn000 = new AstSetData(JJTSETDATA); @@ -1574,7 +1606,7 @@ public class ELParser/*@bgen(jjtree)*/im ; break; default: - jj_la1[41] = jj_gen; + jj_la1[42] = jj_gen; break label_16; } jj_consume_token(COMMA); @@ -1582,7 +1614,7 @@ public class ELParser/*@bgen(jjtree)*/im } break; default: - jj_la1[42] = jj_gen; + jj_la1[43] = jj_gen; ; } jj_consume_token(RBRACE); @@ -1637,7 +1669,7 @@ public class ELParser/*@bgen(jjtree)*/im ; break; default: - jj_la1[43] = jj_gen; + jj_la1[44] = jj_gen; break label_17; } jj_consume_token(COMMA); @@ -1645,7 +1677,7 @@ public class ELParser/*@bgen(jjtree)*/im } break; default: - jj_la1[44] = jj_gen; + jj_la1[45] = jj_gen; ; } jj_consume_token(RBRACK); @@ -1670,6 +1702,11 @@ public class ELParser/*@bgen(jjtree)*/im } } +/* + * Note that both an empty Set and an empty Map are represented by {}. The + * parser will always parse {} as an empty Set and special handling is required + * to convert it to an empty Map when appropriate. + */ final public void MapData() throws ParseException { /*@bgen(jjtree) MapData */ AstMapData jjtn000 = new AstMapData(JJTMAPDATA); @@ -1700,7 +1737,7 @@ public class ELParser/*@bgen(jjtree)*/im ; break; default: - jj_la1[45] = jj_gen; + jj_la1[46] = jj_gen; break label_18; } jj_consume_token(COMMA); @@ -1708,7 +1745,7 @@ public class ELParser/*@bgen(jjtree)*/im } break; default: - jj_la1[46] = jj_gen; + jj_la1[47] = jj_gen; ; } jj_consume_token(RBRACE); @@ -1795,7 +1832,7 @@ public class ELParser/*@bgen(jjtree)*/im jjtree.openNodeScope(jjtn000);Token t0 = null; Token t1 = null; try { - if (jj_2_8(2)) { + if (jj_2_9(2)) { t0 = jj_consume_token(IDENTIFIER); jj_consume_token(COLON); } else { @@ -1832,7 +1869,7 @@ public class ELParser/*@bgen(jjtree)*/im ; break; default: - jj_la1[47] = jj_gen; + jj_la1[48] = jj_gen; break label_19; } jj_consume_token(COMMA); @@ -1840,7 +1877,7 @@ public class ELParser/*@bgen(jjtree)*/im } break; default: - jj_la1[48] = jj_gen; + jj_la1[49] = jj_gen; ; } jj_consume_token(RPAREN); @@ -1888,7 +1925,7 @@ public class ELParser/*@bgen(jjtree)*/im Null(); break; default: - jj_la1[49] = jj_gen; + jj_la1[50] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -1925,7 +1962,7 @@ public class ELParser/*@bgen(jjtree)*/im } break; default: - jj_la1[50] = jj_gen; + jj_la1[51] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -2068,49 +2105,11 @@ public class ELParser/*@bgen(jjtree)*/im finally { jj_save(7, xla); } } - private boolean jj_3R_49() { - Token xsp; - xsp = jj_scanpos; - if (jj_scan_token(35)) { - jj_scanpos = xsp; - if (jj_scan_token(36)) return true; - } - return false; - } - - private boolean jj_3_8() { - if (jj_scan_token(IDENTIFIER)) return true; - if (jj_scan_token(COLON)) return true; - return false; - } - - private boolean jj_3R_96() { - Token xsp; - xsp = jj_scanpos; - if (jj_3_8()) jj_scanpos = xsp; - if (jj_scan_token(IDENTIFIER)) return true; - if (jj_scan_token(LPAREN)) return true; - return false; - } - - private boolean jj_3R_44() { - Token xsp; - xsp = jj_scanpos; - if (jj_3R_48()) { - jj_scanpos = xsp; - if (jj_3R_49()) return true; - } - return false; - } - - private boolean jj_3R_48() { - Token xsp; - xsp = jj_scanpos; - if (jj_scan_token(33)) { - jj_scanpos = xsp; - if (jj_scan_token(34)) return true; - } - return false; + private boolean jj_2_9(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_9(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(8, xla); } } private boolean jj_3R_40() { @@ -2133,13 +2132,18 @@ public class ELParser/*@bgen(jjtree)*/im return false; } - private boolean jj_3R_42() { - if (jj_scan_token(COMMA)) return true; + private boolean jj_3R_103() { + if (jj_3R_35()) return true; return false; } - private boolean jj_3R_37() { - if (jj_scan_token(IDENTIFIER)) return true; + private boolean jj_3R_102() { + if (jj_3R_103()) return true; + return false; + } + + private boolean jj_3R_42() { + if (jj_scan_token(COMMA)) return true; return false; } @@ -2153,6 +2157,11 @@ public class ELParser/*@bgen(jjtree)*/im return false; } + private boolean jj_3R_36() { + if (jj_scan_token(COMMA)) return true; + return false; + } + private boolean jj_3R_34() { Token xsp; xsp = jj_scanpos; @@ -2163,21 +2172,20 @@ public class ELParser/*@bgen(jjtree)*/im return false; } - private boolean jj_3R_36() { - if (jj_scan_token(COMMA)) return true; + private boolean jj_3R_98() { + if (jj_scan_token(START_SET_OR_MAP)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_102()) jj_scanpos = xsp; + if (jj_scan_token(RBRACE)) return true; return false; } - private boolean jj_3R_103() { + private boolean jj_3R_101() { if (jj_3R_35()) return true; return false; } - private boolean jj_3R_102() { - if (jj_3R_103()) return true; - return false; - } - private boolean jj_3R_29() { if (jj_3R_33()) return true; Token xsp; @@ -2188,39 +2196,39 @@ public class ELParser/*@bgen(jjtree)*/im return false; } - private boolean jj_3R_38() { - if (jj_3R_37()) return true; - Token xsp; - while (true) { - xsp = jj_scanpos; - if (jj_3R_42()) { jj_scanpos = xsp; break; } - } - return false; - } - - private boolean jj_3_4() { + private boolean jj_3_5() { if (jj_scan_token(QUESTIONMARK)) return true; if (jj_3R_22()) return true; if (jj_scan_token(COLON)) return true; return false; } - private boolean jj_3R_101() { - if (jj_3R_35()) return true; + private boolean jj_3R_97() { + if (jj_scan_token(LBRACK)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_101()) jj_scanpos = xsp; + if (jj_scan_token(RBRACK)) return true; return false; } - private boolean jj_3R_98() { - if (jj_scan_token(START_SET_OR_MAP)) return true; + private boolean jj_3R_38() { + if (jj_3R_37()) return true; Token xsp; - xsp = jj_scanpos; - if (jj_3R_102()) jj_scanpos = xsp; - if (jj_scan_token(RBRACE)) return true; + while (true) { + xsp = jj_scanpos; + if (jj_3R_42()) { jj_scanpos = xsp; break; } + } return false; } - private boolean jj_3_3() { - if (jj_3R_21()) return true; + private boolean jj_3R_30() { + if (jj_3R_35()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_36()) { jj_scanpos = xsp; break; } + } return false; } @@ -2229,36 +2237,27 @@ public class ELParser/*@bgen(jjtree)*/im Token xsp; while (true) { xsp = jj_scanpos; - if (jj_3_4()) { jj_scanpos = xsp; break; } + if (jj_3_5()) { jj_scanpos = xsp; break; } } return false; } - private boolean jj_3R_97() { - if (jj_scan_token(LBRACK)) return true; - Token xsp; - xsp = jj_scanpos; - if (jj_3R_101()) jj_scanpos = xsp; - if (jj_scan_token(RBRACK)) return true; + private boolean jj_3_3() { + if (jj_3R_21()) return true; return false; } - private boolean jj_3R_30() { - if (jj_3R_35()) return true; + private boolean jj_3R_25() { + if (jj_scan_token(START_SET_OR_MAP)) return true; Token xsp; - while (true) { - xsp = jj_scanpos; - if (jj_3R_36()) { jj_scanpos = xsp; break; } - } + xsp = jj_scanpos; + if (jj_3R_30()) jj_scanpos = xsp; + if (jj_scan_token(RBRACE)) return true; return false; } - private boolean jj_3R_32() { - if (jj_scan_token(LPAREN)) return true; - Token xsp; - xsp = jj_scanpos; - if (jj_3R_38()) jj_scanpos = xsp; - if (jj_scan_token(RPAREN)) return true; + private boolean jj_3_4() { + if (jj_3R_21()) return true; return false; } @@ -2268,7 +2267,7 @@ public class ELParser/*@bgen(jjtree)*/im return false; } - private boolean jj_3_6() { + private boolean jj_3_7() { Token xsp; xsp = jj_scanpos; if (jj_3R_24()) jj_scanpos = xsp; @@ -2277,18 +2276,12 @@ public class ELParser/*@bgen(jjtree)*/im return false; } - private boolean jj_3R_23() { + private boolean jj_3R_32() { if (jj_scan_token(LPAREN)) return true; - if (jj_3R_21()) return true; - return false; - } - - private boolean jj_3R_25() { - if (jj_scan_token(START_SET_OR_MAP)) return true; Token xsp; xsp = jj_scanpos; - if (jj_3R_30()) jj_scanpos = xsp; - if (jj_scan_token(RBRACE)) return true; + if (jj_3R_38()) jj_scanpos = xsp; + if (jj_scan_token(RPAREN)) return true; return false; } @@ -2302,7 +2295,14 @@ public class ELParser/*@bgen(jjtree)*/im return false; } - private boolean jj_3_7() { + private boolean jj_3R_23() { + if (jj_scan_token(LPAREN)) return true; + if (jj_3R_27()) return true; + if (jj_scan_token(ARROW)) return true; + return false; + } + + private boolean jj_3_8() { if (jj_3R_25()) return true; return false; } @@ -2323,22 +2323,7 @@ public class ELParser/*@bgen(jjtree)*/im return false; } - private boolean jj_3R_31() { - if (jj_3R_37()) return true; - return false; - } - - private boolean jj_3R_27() { - Token xsp; - xsp = jj_scanpos; - if (jj_3R_31()) { - jj_scanpos = xsp; - if (jj_3R_32()) return true; - } - return false; - } - - private boolean jj_3_5() { + private boolean jj_3_6() { if (jj_3R_23()) return true; return false; } @@ -2346,7 +2331,7 @@ public class ELParser/*@bgen(jjtree)*/im private boolean jj_3R_76() { Token xsp; xsp = jj_scanpos; - if (jj_3_5()) { + if (jj_3_6()) { jj_scanpos = xsp; if (jj_3R_84()) { jj_scanpos = xsp; @@ -2354,7 +2339,7 @@ public class ELParser/*@bgen(jjtree)*/im jj_scanpos = xsp; if (jj_3R_86()) { jj_scanpos = xsp; - if (jj_3_7()) { + if (jj_3_8()) { jj_scanpos = xsp; if (jj_3R_87()) { jj_scanpos = xsp; @@ -2368,6 +2353,21 @@ public class ELParser/*@bgen(jjtree)*/im return false; } + private boolean jj_3R_31() { + if (jj_3R_37()) return true; + return false; + } + + private boolean jj_3R_27() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_31()) { + jj_scanpos = xsp; + if (jj_3R_32()) return true; + } + return false; + } + private boolean jj_3_1() { if (jj_scan_token(ASSIGN)) return true; if (jj_3R_20()) return true; @@ -2391,6 +2391,11 @@ public class ELParser/*@bgen(jjtree)*/im return false; } + private boolean jj_3R_90() { + if (jj_scan_token(LBRACK)) return true; + return false; + } + private boolean jj_3R_26() { if (jj_3R_22()) return true; Token xsp; @@ -2401,6 +2406,11 @@ public class ELParser/*@bgen(jjtree)*/im return false; } + private boolean jj_3R_78() { + if (jj_3R_90()) return true; + return false; + } + private boolean jj_3_2() { if (jj_3R_21()) return true; return false; @@ -2416,13 +2426,8 @@ public class ELParser/*@bgen(jjtree)*/im return false; } - private boolean jj_3R_90() { - if (jj_scan_token(LBRACK)) return true; - return false; - } - - private boolean jj_3R_78() { - if (jj_3R_90()) return true; + private boolean jj_3R_89() { + if (jj_scan_token(DOT)) return true; return false; } @@ -2436,16 +2441,6 @@ public class ELParser/*@bgen(jjtree)*/im return false; } - private boolean jj_3R_89() { - if (jj_scan_token(DOT)) return true; - return false; - } - - private boolean jj_3R_35() { - if (jj_3R_41()) return true; - return false; - } - private boolean jj_3R_77() { if (jj_3R_89()) return true; return false; @@ -2461,6 +2456,11 @@ public class ELParser/*@bgen(jjtree)*/im return false; } + private boolean jj_3R_35() { + if (jj_3R_41()) return true; + return false; + } + private boolean jj_3R_71() { if (jj_3R_74()) return true; return false; @@ -2496,6 +2496,11 @@ public class ELParser/*@bgen(jjtree)*/im return false; } + private boolean jj_3R_95() { + if (jj_scan_token(NULL)) return true; + return false; + } + private boolean jj_3R_65() { if (jj_3R_69()) return true; return false; @@ -2540,8 +2545,8 @@ public class ELParser/*@bgen(jjtree)*/im return false; } - private boolean jj_3R_95() { - if (jj_scan_token(NULL)) return true; + private boolean jj_3R_94() { + if (jj_scan_token(STRING_LITERAL)) return true; return false; } @@ -2555,6 +2560,11 @@ public class ELParser/*@bgen(jjtree)*/im return false; } + private boolean jj_3R_93() { + if (jj_scan_token(INTEGER_LITERAL)) return true; + return false; + } + private boolean jj_3R_67() { Token xsp; xsp = jj_scanpos; @@ -2565,11 +2575,6 @@ public class ELParser/*@bgen(jjtree)*/im return false; } - private boolean jj_3R_94() { - if (jj_scan_token(STRING_LITERAL)) return true; - return false; - } - private boolean jj_3R_59() { Token xsp; xsp = jj_scanpos; @@ -2598,8 +2603,8 @@ public class ELParser/*@bgen(jjtree)*/im return false; } - private boolean jj_3R_93() { - if (jj_scan_token(INTEGER_LITERAL)) return true; + private boolean jj_3R_92() { + if (jj_scan_token(FLOATING_POINT_LITERAL)) return true; return false; } @@ -2608,6 +2613,11 @@ public class ELParser/*@bgen(jjtree)*/im return false; } + private boolean jj_3R_100() { + if (jj_scan_token(FALSE)) return true; + return false; + } + private boolean jj_3R_57() { Token xsp; xsp = jj_scanpos; @@ -2623,31 +2633,6 @@ public class ELParser/*@bgen(jjtree)*/im return false; } - private boolean jj_3R_92() { - if (jj_scan_token(FLOATING_POINT_LITERAL)) return true; - return false; - } - - private boolean jj_3R_50() { - if (jj_3R_56()) return true; - Token xsp; - while (true) { - xsp = jj_scanpos; - if (jj_3R_57()) { jj_scanpos = xsp; break; } - } - return false; - } - - private boolean jj_3R_100() { - if (jj_scan_token(FALSE)) return true; - return false; - } - - private boolean jj_3R_51() { - if (jj_scan_token(CONCAT)) return true; - return false; - } - private boolean jj_3R_99() { if (jj_scan_token(TRUE)) return true; return false; @@ -2663,12 +2648,12 @@ public class ELParser/*@bgen(jjtree)*/im return false; } - private boolean jj_3R_46() { - if (jj_3R_50()) return true; + private boolean jj_3R_50() { + if (jj_3R_56()) return true; Token xsp; while (true) { xsp = jj_scanpos; - if (jj_3R_51()) { jj_scanpos = xsp; break; } + if (jj_3R_57()) { jj_scanpos = xsp; break; } } return false; } @@ -2683,6 +2668,11 @@ public class ELParser/*@bgen(jjtree)*/im return false; } + private boolean jj_3R_51() { + if (jj_scan_token(CONCAT)) return true; + return false; + } + private boolean jj_3R_81() { if (jj_3R_93()) return true; return false; @@ -2693,16 +2683,6 @@ public class ELParser/*@bgen(jjtree)*/im return false; } - private boolean jj_3R_55() { - Token xsp; - xsp = jj_scanpos; - if (jj_scan_token(29)) { - jj_scanpos = xsp; - if (jj_scan_token(30)) return true; - } - return false; - } - private boolean jj_3R_75() { Token xsp; xsp = jj_scanpos; @@ -2727,6 +2707,26 @@ public class ELParser/*@bgen(jjtree)*/im return false; } + private boolean jj_3R_46() { + if (jj_3R_50()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_51()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_55() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(29)) { + jj_scanpos = xsp; + if (jj_scan_token(30)) return true; + } + return false; + } + private boolean jj_3R_54() { Token xsp; xsp = jj_scanpos; @@ -2773,6 +2773,21 @@ public class ELParser/*@bgen(jjtree)*/im return false; } + private boolean jj_3_9() { + if (jj_scan_token(IDENTIFIER)) return true; + if (jj_scan_token(COLON)) return true; + return false; + } + + private boolean jj_3R_96() { + Token xsp; + xsp = jj_scanpos; + if (jj_3_9()) jj_scanpos = xsp; + if (jj_scan_token(IDENTIFIER)) return true; + if (jj_scan_token(LPAREN)) return true; + return false; + } + private boolean jj_3R_43() { if (jj_3R_46()) return true; Token xsp; @@ -2783,11 +2798,46 @@ public class ELParser/*@bgen(jjtree)*/im return false; } + private boolean jj_3R_49() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(35)) { + jj_scanpos = xsp; + if (jj_scan_token(36)) return true; + } + return false; + } + + private boolean jj_3R_44() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_48()) { + jj_scanpos = xsp; + if (jj_3R_49()) return true; + } + return false; + } + + private boolean jj_3R_48() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(33)) { + jj_scanpos = xsp; + if (jj_scan_token(34)) return true; + } + return false; + } + private boolean jj_3R_28() { if (jj_3R_22()) return true; return false; } + private boolean jj_3R_37() { + if (jj_scan_token(IDENTIFIER)) return true; + return false; + } + /** Generated Token Manager. */ public ELParserTokenManager token_source; SimpleCharStream jj_input_stream; @@ -2799,7 +2849,7 @@ public class ELParser/*@bgen(jjtree)*/im private Token jj_scanpos, jj_lastpos; private int jj_la; private int jj_gen; - final private int[] jj_la1 = new int[51]; + final private int[] jj_la1 = new int[52]; static private int[] jj_la1_0; static private int[] jj_la1_1; static { @@ -2807,12 +2857,12 @@ public class ELParser/*@bgen(jjtree)*/im jj_la1_init_1(); } private static void jj_la1_init_0() { - jj_la1_0 = new int[] {0xe,0xe,0x800000,0x15ed00,0x15ed00,0x1000000,0x0,0x40000,0x40000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfe000000,0x18000000,0x6000000,0x80000000,0x60000000,0xfe000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x15ed00,0x120000,0x15ed00,0x120000,0x40000,0x1000000,0x15ed00,0x40000,0x0,0x100100,0x1000000,0x15ed00,0x1000000,0x15ed00,0x1000000,0x15ed00,0x1000000,0x15ed00,0x1ec00,0xc000,}; + jj_la1_0 = new int[] {0xe,0xe,0x800000,0x15ed00,0x15ed00,0x1000000,0x0,0x40000,0x15ed00,0x40000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfe000000,0x18000000,0x6000000,0x80000000,0x60000000,0xfe000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x15ed00,0x120000,0x15ed00,0x120000,0x40000,0x1000000,0x15ed00,0x40000,0x0,0x100100,0x1000000,0x15ed00,0x1000000,0x15ed00,0x1000000,0x15ed00,0x1000000,0x15ed00,0x1ec00,0xc000,}; } private static void jj_la1_init_1() { - jj_la1_1 = new int[] {0x0,0x0,0x0,0x1008860,0x1008860,0x0,0x1000000,0x1000000,0x0,0x600,0x600,0x180,0x180,0x1e,0x6,0x18,0x1e,0x1,0x0,0x0,0x1,0x0,0x1,0x200000,0xc000,0xc000,0x1e2000,0x60000,0x180000,0x1e2000,0x60,0x1008860,0x0,0x1000000,0x0,0x0,0x0,0x1008860,0x0,0x1000000,0x0,0x0,0x1008860,0x0,0x1008860,0x0,0x1008860,0x0,0x1008860,0x0,0x0,}; + jj_la1_1 = new int[] {0x0,0x0,0x0,0x1008860,0x1008860,0x0,0x1000000,0x1000000,0x1008860,0x0,0x600,0x600,0x180,0x180,0x1e,0x6,0x18,0x1e,0x1,0x0,0x0,0x1,0x0,0x1,0x200000,0xc000,0xc000,0x1e2000,0x60000,0x180000,0x1e2000,0x60,0x1008860,0x0,0x1000000,0x0,0x0,0x0,0x1008860,0x0,0x1000000,0x0,0x0,0x1008860,0x0,0x1008860,0x0,0x1008860,0x0,0x1008860,0x0,0x0,}; } - final private JJCalls[] jj_2_rtns = new JJCalls[8]; + final private JJCalls[] jj_2_rtns = new JJCalls[9]; private boolean jj_rescan = false; private int jj_gc = 0; @@ -2827,7 +2877,7 @@ public class ELParser/*@bgen(jjtree)*/im token = new Token(); jj_ntk = -1; jj_gen = 0; - for (int i = 0; i < 51; i++) jj_la1[i] = -1; + for (int i = 0; i < 52; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } @@ -2843,7 +2893,7 @@ public class ELParser/*@bgen(jjtree)*/im jj_ntk = -1; jjtree.reset(); jj_gen = 0; - for (int i = 0; i < 51; i++) jj_la1[i] = -1; + for (int i = 0; i < 52; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } @@ -2854,7 +2904,7 @@ public class ELParser/*@bgen(jjtree)*/im token = new Token(); jj_ntk = -1; jj_gen = 0; - for (int i = 0; i < 51; i++) jj_la1[i] = -1; + for (int i = 0; i < 52; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } @@ -2866,7 +2916,7 @@ public class ELParser/*@bgen(jjtree)*/im jj_ntk = -1; jjtree.reset(); jj_gen = 0; - for (int i = 0; i < 51; i++) jj_la1[i] = -1; + for (int i = 0; i < 52; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } @@ -2876,7 +2926,7 @@ public class ELParser/*@bgen(jjtree)*/im token = new Token(); jj_ntk = -1; jj_gen = 0; - for (int i = 0; i < 51; i++) jj_la1[i] = -1; + for (int i = 0; i < 52; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } @@ -2887,7 +2937,7 @@ public class ELParser/*@bgen(jjtree)*/im jj_ntk = -1; jjtree.reset(); jj_gen = 0; - for (int i = 0; i < 51; i++) jj_la1[i] = -1; + for (int i = 0; i < 52; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } @@ -3004,7 +3054,7 @@ public class ELParser/*@bgen(jjtree)*/im la1tokens[jj_kind] = true; jj_kind = -1; } - for (int i = 0; i < 51; i++) { + for (int i = 0; i < 52; i++) { if (jj_la1[i] == jj_gen) { for (int j = 0; j < 32; j++) { if ((jj_la1_0[i] & (1<<j)) != 0) { @@ -3043,7 +3093,7 @@ public class ELParser/*@bgen(jjtree)*/im private void jj_rescan_token() { jj_rescan = true; - for (int i = 0; i < 8; i++) { + for (int i = 0; i < 9; i++) { try { JJCalls p = jj_2_rtns[i]; do { @@ -3058,6 +3108,7 @@ public class ELParser/*@bgen(jjtree)*/im case 5: jj_3_6(); break; case 6: jj_3_7(); break; case 7: jj_3_8(); break; + case 8: jj_3_9(); break; } } p = p.next; Modified: tomcat/trunk/java/org/apache/el/parser/ELParser.jjt URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/el/parser/ELParser.jjt?rev=1503857&r1=1503856&r2=1503857&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/el/parser/ELParser.jjt (original) +++ tomcat/trunk/java/org/apache/el/parser/ELParser.jjt Tue Jul 16 20:01:47 2013 @@ -136,9 +136,14 @@ void LambdaParameters() #LambdaParameter * Possible invocation of lambda expression. Invocations must be bracketed but * being bracketed does not mean it is an invocation. */ -void LambdaExpressionOrInvocation() #LambdaExpressionOrInvocation : {} +void LambdaExpressionOrInvocation() #LambdaExpression : {} { - <LPAREN> LambdaExpression() <RPAREN> ( MethodParameters() )* + <LPAREN> + LambdaParameters() + <ARROW> + ( LOOKAHEAD(3) LambdaExpression() | Choice() ) + <RPAREN> + ( MethodParameters() )* } /* Modified: tomcat/trunk/java/org/apache/el/parser/ELParserTreeConstants.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/el/parser/ELParserTreeConstants.java?rev=1503857&r1=1503856&r2=1503857&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/el/parser/ELParserTreeConstants.java (original) +++ tomcat/trunk/java/org/apache/el/parser/ELParserTreeConstants.java Tue Jul 16 20:01:47 2013 @@ -12,41 +12,40 @@ public interface ELParserTreeConstants public int JJTASSIGN = 6; public int JJTLAMBDAEXPRESSION = 7; public int JJTLAMBDAPARAMETERS = 8; - public int JJTLAMBDAEXPRESSIONORINVOCATION = 9; - public int JJTCHOICE = 10; - public int JJTOR = 11; - public int JJTAND = 12; - public int JJTEQUAL = 13; - public int JJTNOTEQUAL = 14; - public int JJTLESSTHAN = 15; - public int JJTGREATERTHAN = 16; - public int JJTLESSTHANEQUAL = 17; - public int JJTGREATERTHANEQUAL = 18; - public int JJTCONCATENATION = 19; - public int JJTPLUS = 20; - public int JJTMINUS = 21; - public int JJTMULT = 22; - public int JJTDIV = 23; - public int JJTMOD = 24; - public int JJTNEGATIVE = 25; - public int JJTNOT = 26; - public int JJTEMPTY = 27; - public int JJTVALUE = 28; - public int JJTDOTSUFFIX = 29; - public int JJTBRACKETSUFFIX = 30; - public int JJTMETHODPARAMETERS = 31; - public int JJTSETDATA = 32; - public int JJTLISTDATA = 33; - public int JJTMAPDATA = 34; - public int JJTMAPENTRY = 35; - public int JJTIDENTIFIER = 36; - public int JJTFUNCTION = 37; - public int JJTTRUE = 38; - public int JJTFALSE = 39; - public int JJTFLOATINGPOINT = 40; - public int JJTINTEGER = 41; - public int JJTSTRING = 42; - public int JJTNULL = 43; + public int JJTCHOICE = 9; + public int JJTOR = 10; + public int JJTAND = 11; + public int JJTEQUAL = 12; + public int JJTNOTEQUAL = 13; + public int JJTLESSTHAN = 14; + public int JJTGREATERTHAN = 15; + public int JJTLESSTHANEQUAL = 16; + public int JJTGREATERTHANEQUAL = 17; + public int JJTCONCATENATION = 18; + public int JJTPLUS = 19; + public int JJTMINUS = 20; + public int JJTMULT = 21; + public int JJTDIV = 22; + public int JJTMOD = 23; + public int JJTNEGATIVE = 24; + public int JJTNOT = 25; + public int JJTEMPTY = 26; + public int JJTVALUE = 27; + public int JJTDOTSUFFIX = 28; + public int JJTBRACKETSUFFIX = 29; + public int JJTMETHODPARAMETERS = 30; + public int JJTSETDATA = 31; + public int JJTLISTDATA = 32; + public int JJTMAPDATA = 33; + public int JJTMAPENTRY = 34; + public int JJTIDENTIFIER = 35; + public int JJTFUNCTION = 36; + public int JJTTRUE = 37; + public int JJTFALSE = 38; + public int JJTFLOATINGPOINT = 39; + public int JJTINTEGER = 40; + public int JJTSTRING = 41; + public int JJTNULL = 42; public String[] jjtNodeName = { @@ -59,7 +58,6 @@ public interface ELParserTreeConstants "Assign", "LambdaExpression", "LambdaParameters", - "LambdaExpressionOrInvocation", "Choice", "Or", "And", @@ -96,4 +94,4 @@ public interface ELParserTreeConstants "Null", }; } -/* JavaCC - OriginalChecksum=23b494fccd3ecfb960d2779462d5457d (do not edit this line) */ +/* JavaCC - OriginalChecksum=96680d397165a1214a1ad1f24011d5c1 (do not edit this line) */ 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); + } } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org