src/share/classes/com/sun/tools/javac/parser/JavacParser.java

changeset 1503
2d2b2be57c78
parent 1444
170e486632d9
child 1511
c7c41a044e7c
equal deleted inserted replaced
1502:916143318f10 1503:2d2b2be57c78
243 public void nextToken() { 243 public void nextToken() {
244 S.nextToken(); 244 S.nextToken();
245 token = S.token(); 245 token = S.token();
246 } 246 }
247 247
248 protected boolean peekToken(TokenKind tk) { 248 protected boolean peekToken(Filter<TokenKind> tk) {
249 return peekToken(0, tk); 249 return peekToken(0, tk);
250 } 250 }
251 251
252 protected boolean peekToken(int lookahead, TokenKind tk) { 252 protected boolean peekToken(int lookahead, Filter<TokenKind> tk) {
253 return S.token(lookahead + 1).kind == tk; 253 return tk.accepts(S.token(lookahead + 1).kind);
254 } 254 }
255 255
256 protected boolean peekToken(TokenKind tk1, TokenKind tk2) { 256 protected boolean peekToken(Filter<TokenKind> tk1, Filter<TokenKind> tk2) {
257 return peekToken(0, tk1, tk2); 257 return peekToken(0, tk1, tk2);
258 } 258 }
259 259
260 protected boolean peekToken(int lookahead, TokenKind tk1, TokenKind tk2) { 260 protected boolean peekToken(int lookahead, Filter<TokenKind> tk1, Filter<TokenKind> tk2) {
261 return S.token(lookahead + 1).kind == tk1 && 261 return tk1.accepts(S.token(lookahead + 1).kind) &&
262 S.token(lookahead + 2).kind == tk2; 262 tk2.accepts(S.token(lookahead + 2).kind);
263 } 263 }
264 264
265 protected boolean peekToken(TokenKind tk1, TokenKind tk2, TokenKind tk3) { 265 protected boolean peekToken(Filter<TokenKind> tk1, Filter<TokenKind> tk2, Filter<TokenKind> tk3) {
266 return peekToken(0, tk1, tk2, tk3); 266 return peekToken(0, tk1, tk2, tk3);
267 } 267 }
268 268
269 protected boolean peekToken(int lookahead, TokenKind tk1, TokenKind tk2, TokenKind tk3) { 269 protected boolean peekToken(int lookahead, Filter<TokenKind> tk1, Filter<TokenKind> tk2, Filter<TokenKind> tk3) {
270 return S.token(lookahead + 1).kind == tk1 && 270 return tk1.accepts(S.token(lookahead + 1).kind) &&
271 S.token(lookahead + 2).kind == tk2 && 271 tk2.accepts(S.token(lookahead + 2).kind) &&
272 S.token(lookahead + 3).kind == tk3; 272 tk3.accepts(S.token(lookahead + 3).kind);
273 } 273 }
274 274
275 protected boolean peekToken(TokenKind... kinds) { 275 @SuppressWarnings("unchecked")
276 protected boolean peekToken(Filter<TokenKind>... kinds) {
276 return peekToken(0, kinds); 277 return peekToken(0, kinds);
277 } 278 }
278 279
279 protected boolean peekToken(int lookahead, TokenKind... kinds) { 280 @SuppressWarnings("unchecked")
281 protected boolean peekToken(int lookahead, Filter<TokenKind>... kinds) {
280 for (; lookahead < kinds.length ; lookahead++) { 282 for (; lookahead < kinds.length ; lookahead++) {
281 if (S.token(lookahead + 1).kind != kinds[lookahead]) { 283 if (!kinds[lookahead].accepts(S.token(lookahead + 1).kind)) {
282 return false; 284 return false;
283 } 285 }
284 } 286 }
285 return true; 287 return true;
286 } 288 }
331 case BOOLEAN: 333 case BOOLEAN:
332 case VOID: 334 case VOID:
333 if (stopAtMemberDecl) 335 if (stopAtMemberDecl)
334 return; 336 return;
335 break; 337 break;
338 case UNDERSCORE:
336 case IDENTIFIER: 339 case IDENTIFIER:
337 if (stopAtIdentifier) 340 if (stopAtIdentifier)
338 return; 341 return;
339 break; 342 break;
340 case CASE: 343 case CASE:
550 warning(token.pos, "enum.as.identifier"); 553 warning(token.pos, "enum.as.identifier");
551 Name name = token.name(); 554 Name name = token.name();
552 nextToken(); 555 nextToken();
553 return name; 556 return name;
554 } 557 }
558 } else if (token.kind == UNDERSCORE) {
559 warning(token.pos, "underscore.as.identifier");
560 Name name = token.name();
561 nextToken();
562 return name;
555 } else { 563 } else {
556 accept(IDENTIFIER); 564 accept(IDENTIFIER);
557 return names.error; 565 return names.error;
558 } 566 }
559 } 567 }
560 568
561 /** 569 /**
562 * Qualident = Ident { DOT Ident } 570 * Qualident = Ident { DOT Ident }
563 */ 571 */
564 public JCExpression qualident() { 572 public JCExpression qualident() {
1054 if (token.kind == LT) typeArgs = typeArguments(false); 1062 if (token.kind == LT) typeArgs = typeArguments(false);
1055 t = creator(pos, typeArgs); 1063 t = creator(pos, typeArgs);
1056 typeArgs = null; 1064 typeArgs = null;
1057 } else return illegal(); 1065 } else return illegal();
1058 break; 1066 break;
1059 case IDENTIFIER: case ASSERT: case ENUM: 1067 case UNDERSCORE: case IDENTIFIER: case ASSERT: case ENUM:
1060 if (typeArgs != null) return illegal(); 1068 if (typeArgs != null) return illegal();
1061 if ((mode & EXPR) != 0 && peekToken(ARROW)) { 1069 if ((mode & EXPR) != 0 && peekToken(ARROW)) {
1062 t = lambdaExpressionOrStatement(false, false, pos); 1070 t = lambdaExpressionOrStatement(false, false, pos);
1063 } else { 1071 } else {
1064 t = toP(F.at(token.pos).Ident(ident())); 1072 t = toP(F.at(token.pos).Ident(ident()));
1272 @SuppressWarnings("fallthrough") 1280 @SuppressWarnings("fallthrough")
1273 boolean isUnboundMemberRef() { 1281 boolean isUnboundMemberRef() {
1274 int pos = 0, depth = 0; 1282 int pos = 0, depth = 0;
1275 for (Token t = S.token(pos) ; ; t = S.token(++pos)) { 1283 for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
1276 switch (t.kind) { 1284 switch (t.kind) {
1277 case IDENTIFIER: case QUES: case EXTENDS: case SUPER: 1285 case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
1278 case DOT: case RBRACKET: case LBRACKET: case COMMA: 1286 case DOT: case RBRACKET: case LBRACKET: case COMMA:
1279 case BYTE: case SHORT: case INT: case LONG: case FLOAT: 1287 case BYTE: case SHORT: case INT: case LONG: case FLOAT:
1280 case DOUBLE: case BOOLEAN: case CHAR: 1288 case DOUBLE: case BOOLEAN: case CHAR:
1281 break; 1289 break;
1282 case LT: 1290 case LT:
1321 case BYTE: case SHORT: case INT: case LONG: case FLOAT: 1329 case BYTE: case SHORT: case INT: case LONG: case FLOAT:
1322 case DOUBLE: case BOOLEAN: case CHAR: 1330 case DOUBLE: case BOOLEAN: case CHAR:
1323 if (peekToken(lookahead, RPAREN)) { 1331 if (peekToken(lookahead, RPAREN)) {
1324 //Type, ')' -> cast 1332 //Type, ')' -> cast
1325 return ParensResult.CAST; 1333 return ParensResult.CAST;
1326 } else if (peekToken(lookahead, IDENTIFIER)) { 1334 } else if (peekToken(lookahead, LAX_IDENTIFIER)) {
1327 //Type, 'Identifier -> explicit lambda 1335 //Type, Identifier/'_'/'assert'/'enum' -> explicit lambda
1328 return ParensResult.EXPLICIT_LAMBDA; 1336 return ParensResult.EXPLICIT_LAMBDA;
1329 } 1337 }
1330 break; 1338 break;
1331 case LPAREN: 1339 case LPAREN:
1332 if (lookahead != 0) { 1340 if (lookahead != 0) {
1348 case BANG: case TILDE: 1356 case BANG: case TILDE:
1349 case LPAREN: case THIS: case SUPER: 1357 case LPAREN: case THIS: case SUPER:
1350 case INTLITERAL: case LONGLITERAL: case FLOATLITERAL: 1358 case INTLITERAL: case LONGLITERAL: case FLOATLITERAL:
1351 case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL: 1359 case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL:
1352 case TRUE: case FALSE: case NULL: 1360 case TRUE: case FALSE: case NULL:
1353 case NEW: case IDENTIFIER: case ASSERT: case ENUM: 1361 case NEW: case IDENTIFIER: case ASSERT: case ENUM: case UNDERSCORE:
1354 case BYTE: case SHORT: case CHAR: case INT: 1362 case BYTE: case SHORT: case CHAR: case INT:
1355 case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID: 1363 case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
1356 return ParensResult.CAST; 1364 return ParensResult.CAST;
1357 default: 1365 default:
1358 return ParensResult.PARENS; 1366 return ParensResult.PARENS;
1359 } 1367 }
1368 case UNDERSCORE:
1369 case ASSERT:
1370 case ENUM:
1360 case IDENTIFIER: 1371 case IDENTIFIER:
1361 if (peekToken(lookahead, IDENTIFIER)) { 1372 if (peekToken(lookahead, LAX_IDENTIFIER)) {
1362 // Identifier, Identifier -> explicit lambda 1373 // Identifier, Identifier/'_'/'assert'/'enum' -> explicit lambda
1363 return ParensResult.EXPLICIT_LAMBDA; 1374 return ParensResult.EXPLICIT_LAMBDA;
1364 } else if (peekToken(lookahead, RPAREN, ARROW)) { 1375 } else if (peekToken(lookahead, RPAREN, ARROW)) {
1365 // Identifier, ')' '->' -> implicit lambda 1376 // Identifier, ')' '->' -> implicit lambda
1366 return ParensResult.IMPLICIT_LAMBDA; 1377 return ParensResult.IMPLICIT_LAMBDA;
1367 } 1378 }
1370 case ELLIPSIS: 1381 case ELLIPSIS:
1371 case MONKEYS_AT: 1382 case MONKEYS_AT:
1372 //those can only appear in explicit lambdas 1383 //those can only appear in explicit lambdas
1373 return ParensResult.EXPLICIT_LAMBDA; 1384 return ParensResult.EXPLICIT_LAMBDA;
1374 case LBRACKET: 1385 case LBRACKET:
1375 if (peekToken(lookahead, RBRACKET, IDENTIFIER)) { 1386 if (peekToken(lookahead, RBRACKET, LAX_IDENTIFIER)) {
1376 // '[', ']', Identifier -> explicit lambda 1387 // '[', ']', Identifier/'_'/'assert'/'enum' -> explicit lambda
1377 return ParensResult.EXPLICIT_LAMBDA; 1388 return ParensResult.EXPLICIT_LAMBDA;
1378 } else if (peekToken(lookahead, RBRACKET, RPAREN) || 1389 } else if (peekToken(lookahead, RBRACKET, RPAREN) ||
1379 peekToken(lookahead, RBRACKET, AMP)) { 1390 peekToken(lookahead, RBRACKET, AMP)) {
1380 // '[', ']', ')' -> cast 1391 // '[', ']', ')' -> cast
1381 // '[', ']', '&' -> cast (intersection type) 1392 // '[', ']', '&' -> cast (intersection type)
1400 if (peekToken(lookahead, RPAREN) || 1411 if (peekToken(lookahead, RPAREN) ||
1401 peekToken(lookahead, AMP)) { 1412 peekToken(lookahead, AMP)) {
1402 // '>', ')' -> cast 1413 // '>', ')' -> cast
1403 // '>', '&' -> cast 1414 // '>', '&' -> cast
1404 return ParensResult.CAST; 1415 return ParensResult.CAST;
1405 } else if (peekToken(lookahead, IDENTIFIER, COMMA) || 1416 } else if (peekToken(lookahead, LAX_IDENTIFIER, COMMA) ||
1406 peekToken(lookahead, IDENTIFIER, RPAREN, ARROW) || 1417 peekToken(lookahead, LAX_IDENTIFIER, RPAREN, ARROW) ||
1407 peekToken(lookahead, ELLIPSIS)) { 1418 peekToken(lookahead, ELLIPSIS)) {
1408 // '>', Identifier, ',' -> explicit lambda 1419 // '>', Identifier/'_'/'assert'/'enum', ',' -> explicit lambda
1409 // '>', Identifier, ')', '->' -> explicit lambda 1420 // '>', Identifier/'_'/'assert'/'enum', ')', '->' -> explicit lambda
1410 // '>', '...' -> explicit lambda 1421 // '>', '...' -> explicit lambda
1411 return ParensResult.EXPLICIT_LAMBDA; 1422 return ParensResult.EXPLICIT_LAMBDA;
1412 } 1423 }
1413 //it looks a type, but could still be (i) a cast to generic type, 1424 //it looks a type, but could still be (i) a cast to generic type,
1414 //(ii) an unbound method reference or (iii) an explicit lambda 1425 //(ii) an unbound method reference or (iii) an explicit lambda
1424 return ParensResult.PARENS; 1435 return ParensResult.PARENS;
1425 } 1436 }
1426 } 1437 }
1427 } 1438 }
1428 1439
1440 /** Accepts all identifier-like tokens */
1441 Filter<TokenKind> LAX_IDENTIFIER = new Filter<TokenKind>() {
1442 public boolean accepts(TokenKind t) {
1443 return t == IDENTIFIER || t == UNDERSCORE || t == ASSERT || t == ENUM;
1444 }
1445 };
1446
1429 enum ParensResult { 1447 enum ParensResult {
1430 CAST, 1448 CAST,
1431 EXPLICIT_LAMBDA, 1449 EXPLICIT_LAMBDA,
1432 IMPLICIT_LAMBDA, 1450 IMPLICIT_LAMBDA,
1433 PARENS; 1451 PARENS;
1434 } 1452 }
1435 1453
1436 JCExpression lambdaExpressionOrStatement(JCVariableDecl firstParam, int pos) {
1437 ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
1438 params.append(firstParam);
1439 JCVariableDecl lastParam = firstParam;
1440 while ((lastParam.mods.flags & Flags.VARARGS) == 0 && token.kind == COMMA) {
1441 nextToken();
1442 params.append(lastParam = formalParameter());
1443 }
1444 accept(RPAREN);
1445 return lambdaExpressionOrStatementRest(params.toList(), pos);
1446 }
1447
1448 JCExpression lambdaExpressionOrStatement(boolean hasParens, boolean explicitParams, int pos) { 1454 JCExpression lambdaExpressionOrStatement(boolean hasParens, boolean explicitParams, int pos) {
1449 List<JCVariableDecl> params = explicitParams ? 1455 List<JCVariableDecl> params = explicitParams ?
1450 formalParameters() : 1456 formalParameters(true) :
1451 implicitParameters(hasParens); 1457 implicitParameters(hasParens);
1452 1458
1453 return lambdaExpressionOrStatementRest(params, pos); 1459 return lambdaExpressionOrStatementRest(params, pos);
1454 } 1460 }
1455 1461
1626 } else if (token.kind == SUPER) { 1632 } else if (token.kind == SUPER) {
1627 TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.SUPER)); 1633 TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.SUPER));
1628 nextToken(); 1634 nextToken();
1629 JCExpression bound = parseType(); 1635 JCExpression bound = parseType();
1630 return F.at(pos).Wildcard(t, bound); 1636 return F.at(pos).Wildcard(t, bound);
1631 } else if (token.kind == IDENTIFIER) { 1637 } else if (LAX_IDENTIFIER.accepts(token.kind)) {
1632 //error recovery 1638 //error recovery
1633 TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND); 1639 TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
1634 JCExpression wc = toP(F.at(pos).Wildcard(t, null)); 1640 JCExpression wc = toP(F.at(pos).Wildcard(t, null));
1635 JCIdent id = toP(F.at(token.pos).Ident(ident())); 1641 JCIdent id = toP(F.at(token.pos).Ident(ident()));
1636 JCErroneous err = F.at(pos).Erroneous(List.<JCTree>of(wc, id)); 1642 JCErroneous err = F.at(pos).Erroneous(List.<JCTree>of(wc, id));
1676 nextToken(); 1682 nextToken();
1677 accept(CLASS); 1683 accept(CLASS);
1678 if (token.pos == endPosTable.errorEndPos) { 1684 if (token.pos == endPosTable.errorEndPos) {
1679 // error recovery 1685 // error recovery
1680 Name name = null; 1686 Name name = null;
1681 if (token.kind == IDENTIFIER) { 1687 if (LAX_IDENTIFIER.accepts(token.kind)) {
1682 name = token.name(); 1688 name = token.name();
1683 nextToken(); 1689 nextToken();
1684 } else { 1690 } else {
1685 name = names.error; 1691 name = names.error;
1686 } 1692 }
2024 JCExpression t = term(EXPR | TYPE); 2030 JCExpression t = term(EXPR | TYPE);
2025 if (token.kind == COLON && t.hasTag(IDENT)) { 2031 if (token.kind == COLON && t.hasTag(IDENT)) {
2026 nextToken(); 2032 nextToken();
2027 JCStatement stat = parseStatement(); 2033 JCStatement stat = parseStatement();
2028 return List.<JCStatement>of(F.at(pos).Labelled(prevToken.name(), stat)); 2034 return List.<JCStatement>of(F.at(pos).Labelled(prevToken.name(), stat));
2029 } else if ((lastmode & TYPE) != 0 && 2035 } else if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
2030 (token.kind == IDENTIFIER ||
2031 token.kind == ASSERT ||
2032 token.kind == ENUM)) {
2033 pos = token.pos; 2036 pos = token.pos;
2034 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0); 2037 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2035 F.at(pos); 2038 F.at(pos);
2036 ListBuffer<JCStatement> stats = 2039 ListBuffer<JCStatement> stats =
2037 variableDeclarators(mods, t, new ListBuffer<JCStatement>()); 2040 variableDeclarators(mods, t, new ListBuffer<JCStatement>());
2181 accept(SEMI); 2184 accept(SEMI);
2182 return t; 2185 return t;
2183 } 2186 }
2184 case BREAK: { 2187 case BREAK: {
2185 nextToken(); 2188 nextToken();
2186 Name label = (token.kind == IDENTIFIER || token.kind == ASSERT || token.kind == ENUM) ? ident() : null; 2189 Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null;
2187 JCBreak t = to(F.at(pos).Break(label)); 2190 JCBreak t = to(F.at(pos).Break(label));
2188 accept(SEMI); 2191 accept(SEMI);
2189 return t; 2192 return t;
2190 } 2193 }
2191 case CONTINUE: { 2194 case CONTINUE: {
2192 nextToken(); 2195 nextToken();
2193 Name label = (token.kind == IDENTIFIER || token.kind == ASSERT || token.kind == ENUM) ? ident() : null; 2196 Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null;
2194 JCContinue t = to(F.at(pos).Continue(label)); 2197 JCContinue t = to(F.at(pos).Continue(label));
2195 accept(SEMI); 2198 accept(SEMI);
2196 return t; 2199 return t;
2197 } 2200 }
2198 case SEMI: 2201 case SEMI:
2349 int pos = token.pos; 2352 int pos = token.pos;
2350 if (token.kind == FINAL || token.kind == MONKEYS_AT) { 2353 if (token.kind == FINAL || token.kind == MONKEYS_AT) {
2351 return variableDeclarators(optFinal(0), parseType(), stats).toList(); 2354 return variableDeclarators(optFinal(0), parseType(), stats).toList();
2352 } else { 2355 } else {
2353 JCExpression t = term(EXPR | TYPE); 2356 JCExpression t = term(EXPR | TYPE);
2354 if ((lastmode & TYPE) != 0 && 2357 if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
2355 (token.kind == IDENTIFIER || token.kind == ASSERT ||
2356 token.kind == ENUM)) {
2357 return variableDeclarators(modifiersOpt(), t, stats).toList(); 2358 return variableDeclarators(modifiersOpt(), t, stats).toList();
2358 } else if ((lastmode & TYPE) != 0 && token.kind == COLON) { 2359 } else if ((lastmode & TYPE) != 0 && token.kind == COLON) {
2359 error(pos, "bad.initializer", "for-loop"); 2360 error(pos, "bad.initializer", "for-loop");
2360 return List.of((JCStatement)F.at(pos).VarDef(null, null, t, null)); 2361 return List.of((JCStatement)F.at(pos).VarDef(null, null, t, null));
2361 } else { 2362 } else {
2607 } 2608 }
2608 2609
2609 /** VariableDeclaratorId = Ident BracketsOpt 2610 /** VariableDeclaratorId = Ident BracketsOpt
2610 */ 2611 */
2611 JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) { 2612 JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
2613 return variableDeclaratorId(mods, type, false);
2614 }
2615 //where
2616 JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean lambdaParameter) {
2612 int pos = token.pos; 2617 int pos = token.pos;
2613 Name name = ident(); 2618 Name name;
2619 if (lambdaParameter && token.kind == UNDERSCORE) {
2620 syntaxError(pos, "expected", IDENTIFIER);
2621 name = token.name();
2622 } else {
2623 name = ident();
2624 }
2614 if ((mods.flags & Flags.VARARGS) != 0 && 2625 if ((mods.flags & Flags.VARARGS) != 0 &&
2615 token.kind == LBRACKET) { 2626 token.kind == LBRACKET) {
2616 log.error(token.pos, "varargs.and.old.array.syntax"); 2627 log.error(token.pos, "varargs.and.old.array.syntax");
2617 } 2628 }
2618 type = bracketsOpt(type); 2629 type = bracketsOpt(type);
2768 if (token.kind == ENUM) { 2779 if (token.kind == ENUM) {
2769 return enumDeclaration(mods, dc); 2780 return enumDeclaration(mods, dc);
2770 } else { 2781 } else {
2771 int pos = token.pos; 2782 int pos = token.pos;
2772 List<JCTree> errs; 2783 List<JCTree> errs;
2773 if (token.kind == IDENTIFIER) { 2784 if (LAX_IDENTIFIER.accepts(token.kind)) {
2774 errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident()))); 2785 errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
2775 setErrorEndPos(token.pos); 2786 setErrorEndPos(token.pos);
2776 } else { 2787 } else {
2777 errs = List.<JCTree>of(mods); 2788 errs = List.<JCTree>of(mods);
2778 } 2789 }
2785 allowEnums = true; 2796 allowEnums = true;
2786 return enumDeclaration(mods, dc); 2797 return enumDeclaration(mods, dc);
2787 } 2798 }
2788 int pos = token.pos; 2799 int pos = token.pos;
2789 List<JCTree> errs; 2800 List<JCTree> errs;
2790 if (token.kind == IDENTIFIER) { 2801 if (LAX_IDENTIFIER.accepts(token.kind)) {
2791 errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident()))); 2802 errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
2792 setErrorEndPos(token.pos); 2803 setErrorEndPos(token.pos);
2793 } else { 2804 } else {
2794 errs = List.<JCTree>of(mods); 2805 errs = List.<JCTree>of(mods);
2795 } 2806 }
3180 /** FormalParameters = "(" [ FormalParameterList ] ")" 3191 /** FormalParameters = "(" [ FormalParameterList ] ")"
3181 * FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter 3192 * FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter
3182 * FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter 3193 * FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter
3183 */ 3194 */
3184 List<JCVariableDecl> formalParameters() { 3195 List<JCVariableDecl> formalParameters() {
3196 return formalParameters(false);
3197 }
3198 List<JCVariableDecl> formalParameters(boolean lambdaParameters) {
3185 ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>(); 3199 ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
3186 JCVariableDecl lastParam = null; 3200 JCVariableDecl lastParam = null;
3187 accept(LPAREN); 3201 accept(LPAREN);
3188 if (token.kind != RPAREN) { 3202 if (token.kind != RPAREN) {
3189 params.append(lastParam = formalParameter()); 3203 params.append(lastParam = formalParameter(lambdaParameters));
3190 while ((lastParam.mods.flags & Flags.VARARGS) == 0 && token.kind == COMMA) { 3204 while ((lastParam.mods.flags & Flags.VARARGS) == 0 && token.kind == COMMA) {
3191 nextToken(); 3205 nextToken();
3192 params.append(lastParam = formalParameter()); 3206 params.append(lastParam = formalParameter(lambdaParameters));
3193 } 3207 }
3194 } 3208 }
3195 accept(RPAREN); 3209 accept(RPAREN);
3196 return params.toList(); 3210 return params.toList();
3197 } 3211 }
3223 3237
3224 /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId 3238 /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId
3225 * LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter 3239 * LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter
3226 */ 3240 */
3227 protected JCVariableDecl formalParameter() { 3241 protected JCVariableDecl formalParameter() {
3242 return formalParameter(false);
3243 }
3244 protected JCVariableDecl formalParameter(boolean lambdaParameter) {
3228 JCModifiers mods = optFinal(Flags.PARAMETER); 3245 JCModifiers mods = optFinal(Flags.PARAMETER);
3229 JCExpression type = parseType(); 3246 JCExpression type = parseType();
3230 if (token.kind == ELLIPSIS) { 3247 if (token.kind == ELLIPSIS) {
3231 checkVarargs(); 3248 checkVarargs();
3232 mods.flags |= Flags.VARARGS; 3249 mods.flags |= Flags.VARARGS;
3233 type = to(F.at(token.pos).TypeArray(type)); 3250 type = to(F.at(token.pos).TypeArray(type));
3234 nextToken(); 3251 nextToken();
3235 } 3252 }
3236 return variableDeclaratorId(mods, type); 3253 return variableDeclaratorId(mods, type, lambdaParameter);
3237 } 3254 }
3238 3255
3239 protected JCVariableDecl implicitParameter() { 3256 protected JCVariableDecl implicitParameter() {
3240 JCModifiers mods = F.at(token.pos).Modifiers(Flags.PARAMETER); 3257 JCModifiers mods = F.at(token.pos).Modifiers(Flags.PARAMETER);
3241 return variableDeclaratorId(mods, null); 3258 return variableDeclaratorId(mods, null, true);
3242 } 3259 }
3243 3260
3244 /* ---------- auxiliary methods -------------- */ 3261 /* ---------- auxiliary methods -------------- */
3245 3262
3246 void error(int pos, String key, Object ... args) { 3263 void error(int pos, String key, Object ... args) {

mercurial