41 import com.sun.tools.javac.resources.CompilerProperties.Warnings; |
41 import com.sun.tools.javac.resources.CompilerProperties.Warnings; |
42 import com.sun.tools.javac.tree.*; |
42 import com.sun.tools.javac.tree.*; |
43 import com.sun.tools.javac.tree.JCTree.*; |
43 import com.sun.tools.javac.tree.JCTree.*; |
44 import com.sun.tools.javac.util.*; |
44 import com.sun.tools.javac.util.*; |
45 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; |
45 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; |
|
46 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; |
46 import com.sun.tools.javac.util.JCDiagnostic.Error; |
47 import com.sun.tools.javac.util.JCDiagnostic.Error; |
47 import com.sun.tools.javac.util.JCDiagnostic.Warning; |
48 import com.sun.tools.javac.util.JCDiagnostic.Warning; |
|
49 import com.sun.tools.javac.util.JCDiagnostic.Fragment; |
48 import com.sun.tools.javac.util.List; |
50 import com.sun.tools.javac.util.List; |
49 import com.sun.tools.javac.util.JCDiagnostic.Fragment; |
|
50 |
51 |
51 import static com.sun.tools.javac.parser.Tokens.TokenKind.*; |
52 import static com.sun.tools.javac.parser.Tokens.TokenKind.*; |
52 import static com.sun.tools.javac.parser.Tokens.TokenKind.ASSERT; |
53 import static com.sun.tools.javac.parser.Tokens.TokenKind.ASSERT; |
53 import static com.sun.tools.javac.parser.Tokens.TokenKind.CASE; |
54 import static com.sun.tools.javac.parser.Tokens.TokenKind.CASE; |
54 import static com.sun.tools.javac.parser.Tokens.TokenKind.CATCH; |
55 import static com.sun.tools.javac.parser.Tokens.TokenKind.CATCH; |
287 |
288 |
288 private JCErroneous errorTree; |
289 private JCErroneous errorTree; |
289 |
290 |
290 /** Skip forward until a suitable stop token is found. |
291 /** Skip forward until a suitable stop token is found. |
291 */ |
292 */ |
292 protected void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement, boolean stopAtLambdaBody) { |
293 protected void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement) { |
293 while (true) { |
294 while (true) { |
294 switch (token.kind) { |
295 switch (token.kind) { |
295 case ARROW: |
|
296 if (stopAtLambdaBody) { |
|
297 //find end of lambda expression; this could be either a comma or an rparen (if in method context), |
|
298 //or a semi colon (if in assignment context). |
|
299 int depth = 0; |
|
300 while (true) { |
|
301 switch (token.kind) { |
|
302 case EOF: |
|
303 case LBRACE: depth++; break; |
|
304 case RBRACE: depth--; break; |
|
305 case COMMA: |
|
306 case RPAREN: |
|
307 case SEMI: |
|
308 if (depth == 0) { |
|
309 return; |
|
310 } |
|
311 break; |
|
312 } |
|
313 nextToken(); |
|
314 } |
|
315 } |
|
316 break; |
|
317 case SEMI: |
296 case SEMI: |
318 nextToken(); |
297 nextToken(); |
319 return; |
298 return; |
320 case PUBLIC: |
299 case PUBLIC: |
321 case FINAL: |
300 case FINAL: |
1115 } |
1093 } |
1116 accept(RPAREN); |
1094 accept(RPAREN); |
1117 mode = EXPR; |
1095 mode = EXPR; |
1118 JCExpression t1 = term3(); |
1096 JCExpression t1 = term3(); |
1119 return F.at(pos).TypeCast(t, t1); |
1097 return F.at(pos).TypeCast(t, t1); |
1120 case BAD_LAMBDA: |
|
1121 Assert.checkNonNull(lambdaClassifier.diagFragment); |
|
1122 t = syntaxError(pos, List.nil(), Errors.InvalidLambdaParameterDeclaration(lambdaClassifier.diagFragment)); |
|
1123 skip(false, false, false, false, true); |
|
1124 break; |
|
1125 case IMPLICIT_LAMBDA: |
1098 case IMPLICIT_LAMBDA: |
1126 case EXPLICIT_LAMBDA: |
1099 case EXPLICIT_LAMBDA: |
1127 case IMPLICIT_LAMBDA_ALL_VAR: |
1100 t = lambdaExpressionOrStatement(true, pres == ParensResult.EXPLICIT_LAMBDA, pos); |
1128 t = lambdaExpressionOrStatement(true, pres != ParensResult.IMPLICIT_LAMBDA, pos); |
|
1129 break; |
1101 break; |
1130 default: //PARENS |
1102 default: //PARENS |
1131 accept(LPAREN); |
1103 accept(LPAREN); |
1132 mode = EXPR; |
1104 mode = EXPR; |
1133 t = termRest(term1Rest(term2Rest(term3(), TreeInfo.orPrec))); |
1105 t = termRest(term1Rest(term2Rest(term3(), TreeInfo.orPrec))); |
1535 * If we see an identifier followed by a '<' it could be an unbound |
1507 * If we see an identifier followed by a '<' it could be an unbound |
1536 * method reference or a binary expression. To disambiguate, look for a |
1508 * method reference or a binary expression. To disambiguate, look for a |
1537 * matching '>' and see if the subsequent terminal is either '.' or '::'. |
1509 * matching '>' and see if the subsequent terminal is either '.' or '::'. |
1538 */ |
1510 */ |
1539 @SuppressWarnings("fallthrough") |
1511 @SuppressWarnings("fallthrough") |
1540 ParensResult analyzeParens(LambdaClassfier lambdaClassifier) { |
1512 ParensResult analyzeParens() { |
1541 int depth = 0; |
1513 int depth = 0; |
1542 boolean type = false; |
1514 boolean type = false; |
1543 outer: for (int lookahead = 0 ; ; lookahead++) { |
1515 outer: for (int lookahead = 0 ; ; lookahead++) { |
1544 Token lookaheadToken = S.token(lookahead); |
1516 TokenKind tk = S.token(lookahead).kind; |
1545 TokenKind tk = lookaheadToken.kind; |
|
1546 switch (tk) { |
1517 switch (tk) { |
1547 case COMMA: |
1518 case COMMA: |
1548 type = true; |
1519 type = true; |
1549 break; |
1520 case EXTENDS: case SUPER: case DOT: case AMP: |
1550 case FINAL: case EXTENDS: case SUPER: case DOT: case AMP: |
|
1551 //skip |
1521 //skip |
1552 break; |
1522 break; |
1553 case QUES: |
1523 case QUES: |
1554 if (peekToken(lookahead, EXTENDS) || |
1524 if (peekToken(lookahead, EXTENDS) || |
1555 peekToken(lookahead, SUPER)) { |
1525 peekToken(lookahead, SUPER)) { |
1562 if (peekToken(lookahead, RPAREN)) { |
1532 if (peekToken(lookahead, RPAREN)) { |
1563 //Type, ')' -> cast |
1533 //Type, ')' -> cast |
1564 return ParensResult.CAST; |
1534 return ParensResult.CAST; |
1565 } else if (peekToken(lookahead, LAX_IDENTIFIER)) { |
1535 } else if (peekToken(lookahead, LAX_IDENTIFIER)) { |
1566 //Type, Identifier/'_'/'assert'/'enum' -> explicit lambda |
1536 //Type, Identifier/'_'/'assert'/'enum' -> explicit lambda |
1567 lambdaClassifier.addExplicitParameter(); |
1537 return ParensResult.EXPLICIT_LAMBDA; |
1568 lookahead++; //skip Identifier |
|
1569 } |
1538 } |
1570 break; |
1539 break; |
1571 case LPAREN: |
1540 case LPAREN: |
1572 if (lookahead != 0) { |
1541 if (lookahead != 0) { |
1573 // '(' in a non-starting position -> parens |
1542 // '(' in a non-starting position -> parens |
1576 // '(', ')' -> explicit lambda |
1545 // '(', ')' -> explicit lambda |
1577 return ParensResult.EXPLICIT_LAMBDA; |
1546 return ParensResult.EXPLICIT_LAMBDA; |
1578 } |
1547 } |
1579 break; |
1548 break; |
1580 case RPAREN: |
1549 case RPAREN: |
1581 if (peekToken(lookahead, ARROW)) { |
1550 // if we have seen something that looks like a type, |
1582 //this is a lambda |
1551 // then it's a cast expression |
1583 return lambdaClassifier.result(); |
1552 if (type) return ParensResult.CAST; |
1584 } else { |
1553 // otherwise, disambiguate cast vs. parenthesized expression |
1585 // if we have seen something that looks like a type, |
1554 // based on subsequent token. |
1586 // then it's a cast expression |
1555 switch (S.token(lookahead + 1).kind) { |
1587 if (type) return ParensResult.CAST; |
1556 /*case PLUSPLUS: case SUBSUB: */ |
1588 // otherwise, disambiguate cast vs. parenthesized expression |
1557 case BANG: case TILDE: |
1589 // based on subsequent token. |
1558 case LPAREN: case THIS: case SUPER: |
1590 switch (S.token(lookahead + 1).kind) { |
1559 case INTLITERAL: case LONGLITERAL: case FLOATLITERAL: |
1591 /*case PLUSPLUS: case SUBSUB: */ |
1560 case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL: |
1592 case BANG: case TILDE: |
1561 case TRUE: case FALSE: case NULL: |
1593 case LPAREN: case THIS: case SUPER: |
1562 case NEW: case IDENTIFIER: case ASSERT: case ENUM: case UNDERSCORE: |
1594 case INTLITERAL: case LONGLITERAL: case FLOATLITERAL: |
1563 case BYTE: case SHORT: case CHAR: case INT: |
1595 case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL: |
1564 case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID: |
1596 case TRUE: case FALSE: case NULL: |
1565 return ParensResult.CAST; |
1597 case NEW: case IDENTIFIER: case ASSERT: case ENUM: case UNDERSCORE: |
1566 default: |
1598 case BYTE: case SHORT: case CHAR: case INT: |
1567 return ParensResult.PARENS; |
1599 case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID: |
|
1600 return ParensResult.CAST; |
|
1601 default: |
|
1602 return ParensResult.PARENS; |
|
1603 } |
|
1604 } |
1568 } |
1605 case UNDERSCORE: |
1569 case UNDERSCORE: |
1606 case ASSERT: |
1570 case ASSERT: |
1607 case ENUM: |
1571 case ENUM: |
1608 case IDENTIFIER: |
1572 case IDENTIFIER: |
1609 if (peekToken(lookahead, LAX_IDENTIFIER)) { |
1573 if (peekToken(lookahead, LAX_IDENTIFIER)) { |
1610 // Identifier, Identifier/'_'/'assert'/'enum' -> explicit lambda |
1574 // Identifier, Identifier/'_'/'assert'/'enum' -> explicit lambda |
1611 if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source) && |
1575 return ParensResult.EXPLICIT_LAMBDA; |
1612 lookaheadToken.name() == names.var) { |
1576 } else if (peekToken(lookahead, RPAREN, ARROW)) { |
1613 lambdaClassifier.addImplicitVarParameter(); |
1577 // Identifier, ')' '->' -> implicit lambda |
1614 } else { |
1578 return ParensResult.IMPLICIT_LAMBDA; |
1615 lambdaClassifier.addExplicitParameter(); |
|
1616 } |
|
1617 lookahead++; //skip Identifier |
|
1618 } else if ((!type && peekToken(lookahead, COMMA)) || peekToken(lookahead, RPAREN)) { |
|
1619 lambdaClassifier.addImplicitParameter(); |
|
1620 } |
1579 } |
1621 type = false; |
1580 type = false; |
1622 break; |
1581 break; |
|
1582 case FINAL: |
1623 case ELLIPSIS: |
1583 case ELLIPSIS: |
1624 //those can only appear in explicit, non-var, lambdas |
1584 //those can only appear in explicit lambdas |
1625 lambdaClassifier.addExplicitParameter(); |
1585 return ParensResult.EXPLICIT_LAMBDA; |
1626 lookahead++; //skip Identifier |
|
1627 break; |
|
1628 case MONKEYS_AT: |
1586 case MONKEYS_AT: |
1629 type = true; |
1587 type = true; |
1630 lookahead += 1; //skip '@' |
1588 lookahead += 1; //skip '@' |
1631 while (peekToken(lookahead, DOT)) { |
1589 while (peekToken(lookahead, DOT)) { |
1632 lookahead += 2; |
1590 lookahead += 2; |
1654 } |
1612 } |
1655 break; |
1613 break; |
1656 case LBRACKET: |
1614 case LBRACKET: |
1657 if (peekToken(lookahead, RBRACKET, LAX_IDENTIFIER)) { |
1615 if (peekToken(lookahead, RBRACKET, LAX_IDENTIFIER)) { |
1658 // '[', ']', Identifier/'_'/'assert'/'enum' -> explicit lambda |
1616 // '[', ']', Identifier/'_'/'assert'/'enum' -> explicit lambda |
1659 lambdaClassifier.addExplicitParameter(); |
1617 return ParensResult.EXPLICIT_LAMBDA; |
1660 lookahead += 2; //skip ']' Identifier |
|
1661 break; |
|
1662 } else if (peekToken(lookahead, RBRACKET, RPAREN) || |
1618 } else if (peekToken(lookahead, RBRACKET, RPAREN) || |
1663 peekToken(lookahead, RBRACKET, AMP)) { |
1619 peekToken(lookahead, RBRACKET, AMP)) { |
1664 // '[', ']', ')' -> cast |
1620 // '[', ']', ')' -> cast |
1665 // '[', ']', '&' -> cast (intersection type) |
1621 // '[', ']', '&' -> cast (intersection type) |
1666 return ParensResult.CAST; |
1622 return ParensResult.CAST; |
1685 peekToken(lookahead, AMP)) { |
1641 peekToken(lookahead, AMP)) { |
1686 // '>', ')' -> cast |
1642 // '>', ')' -> cast |
1687 // '>', '&' -> cast |
1643 // '>', '&' -> cast |
1688 return ParensResult.CAST; |
1644 return ParensResult.CAST; |
1689 } else if (peekToken(lookahead, LAX_IDENTIFIER, COMMA) || |
1645 } else if (peekToken(lookahead, LAX_IDENTIFIER, COMMA) || |
1690 peekToken(lookahead, LAX_IDENTIFIER, RPAREN, ARROW)) { |
1646 peekToken(lookahead, LAX_IDENTIFIER, RPAREN, ARROW) || |
|
1647 peekToken(lookahead, ELLIPSIS)) { |
1691 // '>', Identifier/'_'/'assert'/'enum', ',' -> explicit lambda |
1648 // '>', Identifier/'_'/'assert'/'enum', ',' -> explicit lambda |
1692 // '>', Identifier/'_'/'assert'/'enum', ')', '->' -> explicit lambda |
1649 // '>', Identifier/'_'/'assert'/'enum', ')', '->' -> explicit lambda |
1693 lambdaClassifier.addExplicitParameter(); |
|
1694 lookahead++; //skip Identifier |
|
1695 break; |
|
1696 } else if (peekToken(lookahead, ELLIPSIS)) { |
|
1697 // '>', '...' -> explicit lambda |
1650 // '>', '...' -> explicit lambda |
1698 break; //this is handled in the outer switch |
1651 return ParensResult.EXPLICIT_LAMBDA; |
1699 } |
1652 } |
1700 //it looks a type, but could still be (i) a cast to generic type, |
1653 //it looks a type, but could still be (i) a cast to generic type, |
1701 //(ii) an unbound method reference or (iii) an explicit lambda |
1654 //(ii) an unbound method reference or (iii) an explicit lambda |
1702 type = true; |
1655 type = true; |
1703 break; |
1656 break; |
1711 return ParensResult.PARENS; |
1664 return ParensResult.PARENS; |
1712 } |
1665 } |
1713 } |
1666 } |
1714 } |
1667 } |
1715 |
1668 |
1716 class LambdaClassfier { |
|
1717 ParensResult kind; |
|
1718 Fragment diagFragment; |
|
1719 |
|
1720 void addExplicitParameter() { |
|
1721 reduce(ParensResult.EXPLICIT_LAMBDA); |
|
1722 } |
|
1723 |
|
1724 void addImplicitVarParameter() { |
|
1725 reduce(ParensResult.IMPLICIT_LAMBDA_ALL_VAR); |
|
1726 } |
|
1727 |
|
1728 void addImplicitParameter() { |
|
1729 reduce(ParensResult.IMPLICIT_LAMBDA); |
|
1730 } |
|
1731 |
|
1732 private void reduce(ParensResult newKind) { |
|
1733 if (kind == null) { |
|
1734 kind = newKind; |
|
1735 } else if (kind != newKind && kind != ParensResult.BAD_LAMBDA) { |
|
1736 ParensResult currentKind = kind; |
|
1737 kind = ParensResult.BAD_LAMBDA; |
|
1738 switch (currentKind) { |
|
1739 case EXPLICIT_LAMBDA: |
|
1740 if (newKind == ParensResult.IMPLICIT_LAMBDA) { |
|
1741 diagFragment = Fragments.ImplicitAndExplicitNotAllowed; |
|
1742 } else if (newKind == ParensResult.IMPLICIT_LAMBDA_ALL_VAR) { |
|
1743 diagFragment = Fragments.VarAndExplicitNotAllowed; |
|
1744 } |
|
1745 break; |
|
1746 case IMPLICIT_LAMBDA: |
|
1747 if (newKind == ParensResult.EXPLICIT_LAMBDA) { |
|
1748 diagFragment = Fragments.ImplicitAndExplicitNotAllowed; |
|
1749 } else if (newKind == ParensResult.IMPLICIT_LAMBDA_ALL_VAR) { |
|
1750 diagFragment = Fragments.VarAndImplicitNotAllowed; |
|
1751 } |
|
1752 break; |
|
1753 case IMPLICIT_LAMBDA_ALL_VAR: |
|
1754 if (newKind == ParensResult.EXPLICIT_LAMBDA) { |
|
1755 diagFragment = Fragments.VarAndExplicitNotAllowed; |
|
1756 } else if (newKind == ParensResult.IMPLICIT_LAMBDA) { |
|
1757 diagFragment = Fragments.VarAndImplicitNotAllowed; |
|
1758 } |
|
1759 break; |
|
1760 default: |
|
1761 throw new AssertionError("unexpected option for field kind"); |
|
1762 } |
|
1763 } |
|
1764 } |
|
1765 |
|
1766 ParensResult result() { |
|
1767 return kind; |
|
1768 } |
|
1769 } |
|
1770 |
|
1771 /** Accepts all identifier-like tokens */ |
1669 /** Accepts all identifier-like tokens */ |
1772 protected Filter<TokenKind> LAX_IDENTIFIER = t -> t == IDENTIFIER || t == UNDERSCORE || t == ASSERT || t == ENUM; |
1670 protected Filter<TokenKind> LAX_IDENTIFIER = t -> t == IDENTIFIER || t == UNDERSCORE || t == ASSERT || t == ENUM; |
1773 |
1671 |
1774 enum ParensResult { |
1672 enum ParensResult { |
1775 CAST, |
1673 CAST, |
1776 EXPLICIT_LAMBDA, |
1674 EXPLICIT_LAMBDA, |
1777 IMPLICIT_LAMBDA, |
1675 IMPLICIT_LAMBDA, |
1778 IMPLICIT_LAMBDA_ALL_VAR, |
1676 PARENS |
1779 BAD_LAMBDA, |
|
1780 PARENS; |
|
1781 } |
|
1782 |
|
1783 enum BAD_LAMBDA_KIND { |
|
1784 EXPLICIT_AND_VAR, |
|
1785 IMPLICIT_AND_VAR, |
|
1786 EXPLICIT_AND_IMPLICIT, |
|
1787 } |
1677 } |
1788 |
1678 |
1789 JCExpression lambdaExpressionOrStatement(boolean hasParens, boolean explicitParams, int pos) { |
1679 JCExpression lambdaExpressionOrStatement(boolean hasParens, boolean explicitParams, int pos) { |
1790 List<JCVariableDecl> params = explicitParams ? |
1680 List<JCVariableDecl> params = explicitParams ? |
1791 formalParameters(true) : |
1681 formalParameters(true) : |
2004 private JCExpression bracketsOpt(JCExpression t, |
1894 private JCExpression bracketsOpt(JCExpression t, |
2005 List<JCAnnotation> annotations) { |
1895 List<JCAnnotation> annotations) { |
2006 List<JCAnnotation> nextLevelAnnotations = typeAnnotationsOpt(); |
1896 List<JCAnnotation> nextLevelAnnotations = typeAnnotationsOpt(); |
2007 |
1897 |
2008 if (token.kind == LBRACKET) { |
1898 if (token.kind == LBRACKET) { |
2009 if (t == null) { |
|
2010 log.error(token.pos, Errors.VarNotAllowedArray); |
|
2011 } |
|
2012 int pos = token.pos; |
1899 int pos = token.pos; |
2013 nextToken(); |
1900 nextToken(); |
2014 t = bracketsOptCont(t, pos, nextLevelAnnotations); |
1901 t = bracketsOptCont(t, pos, nextLevelAnnotations); |
2015 } else if (!nextLevelAnnotations.isEmpty()) { |
1902 } else if (!nextLevelAnnotations.isEmpty()) { |
2016 if (permitTypeAnnotationsPushBack) { |
1903 if (permitTypeAnnotationsPushBack) { |
3244 boolean checkForImports = true; |
3131 boolean checkForImports = true; |
3245 boolean firstTypeDecl = true; |
3132 boolean firstTypeDecl = true; |
3246 while (token.kind != EOF) { |
3133 while (token.kind != EOF) { |
3247 if (token.pos <= endPosTable.errorEndPos) { |
3134 if (token.pos <= endPosTable.errorEndPos) { |
3248 // error recovery |
3135 // error recovery |
3249 skip(checkForImports, false, false, false, false); |
3136 skip(checkForImports, false, false, false); |
3250 if (token.kind == EOF) |
3137 if (token.kind == EOF) |
3251 break; |
3138 break; |
3252 } |
3139 } |
3253 if (checkForImports && mods == null && token.kind == IMPORT) { |
3140 if (checkForImports && mods == null && token.kind == IMPORT) { |
3254 seenImport = true; |
3141 seenImport = true; |
3381 List<JCExpression> implNames = qualidentList(false); |
3268 List<JCExpression> implNames = qualidentList(false); |
3382 accept(SEMI); |
3269 accept(SEMI); |
3383 defs.append(toP(F.at(pos).Provides(serviceName, implNames))); |
3270 defs.append(toP(F.at(pos).Provides(serviceName, implNames))); |
3384 } else { |
3271 } else { |
3385 log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.ExpectedStr("'" + names.with + "'")); |
3272 log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.ExpectedStr("'" + names.with + "'")); |
3386 skip(false, false, false, false, false); |
3273 skip(false, false, false, false); |
3387 } |
3274 } |
3388 } else if (token.name() == names.uses) { |
3275 } else if (token.name() == names.uses) { |
3389 nextToken(); |
3276 nextToken(); |
3390 JCExpression service = qualident(false); |
3277 JCExpression service = qualident(false); |
3391 accept(SEMI); |
3278 accept(SEMI); |
3648 */ |
3535 */ |
3649 List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) { |
3536 List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) { |
3650 accept(LBRACE); |
3537 accept(LBRACE); |
3651 if (token.pos <= endPosTable.errorEndPos) { |
3538 if (token.pos <= endPosTable.errorEndPos) { |
3652 // error recovery |
3539 // error recovery |
3653 skip(false, true, false, false, false); |
3540 skip(false, true, false, false); |
3654 if (token.kind == LBRACE) |
3541 if (token.kind == LBRACE) |
3655 nextToken(); |
3542 nextToken(); |
3656 } |
3543 } |
3657 ListBuffer<JCTree> defs = new ListBuffer<>(); |
3544 ListBuffer<JCTree> defs = new ListBuffer<>(); |
3658 while (token.kind != RBRACE && token.kind != EOF) { |
3545 while (token.kind != RBRACE && token.kind != EOF) { |
3659 defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface)); |
3546 defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface)); |
3660 if (token.pos <= endPosTable.errorEndPos) { |
3547 if (token.pos <= endPosTable.errorEndPos) { |
3661 // error recovery |
3548 // error recovery |
3662 skip(false, true, true, false, false); |
3549 skip(false, true, true, false); |
3663 } |
3550 } |
3664 } |
3551 } |
3665 accept(RBRACE); |
3552 accept(RBRACE); |
3666 return defs.toList(); |
3553 return defs.toList(); |
3667 } |
3554 } |
4058 protected JCVariableDecl formalParameter(boolean lambdaParameter) { |
3945 protected JCVariableDecl formalParameter(boolean lambdaParameter) { |
4059 JCModifiers mods = optFinal(Flags.PARAMETER); |
3946 JCModifiers mods = optFinal(Flags.PARAMETER); |
4060 // need to distinguish between vararg annos and array annos |
3947 // need to distinguish between vararg annos and array annos |
4061 // look at typeAnnotationsPushedBack comment |
3948 // look at typeAnnotationsPushedBack comment |
4062 this.permitTypeAnnotationsPushBack = true; |
3949 this.permitTypeAnnotationsPushBack = true; |
4063 JCExpression type = parseType(lambdaParameter); |
3950 JCExpression type = parseType(); |
4064 this.permitTypeAnnotationsPushBack = false; |
3951 this.permitTypeAnnotationsPushBack = false; |
4065 |
3952 |
4066 if (token.kind == ELLIPSIS) { |
3953 if (token.kind == ELLIPSIS) { |
4067 List<JCAnnotation> varargsAnnos = typeAnnotationsPushedBack; |
3954 List<JCAnnotation> varargsAnnos = typeAnnotationsPushedBack; |
4068 typeAnnotationsPushedBack = List.nil(); |
3955 typeAnnotationsPushedBack = List.nil(); |
4074 // if not a var arg, then typeAnnotationsPushedBack should be null |
3961 // if not a var arg, then typeAnnotationsPushedBack should be null |
4075 if (typeAnnotationsPushedBack.nonEmpty()) { |
3962 if (typeAnnotationsPushedBack.nonEmpty()) { |
4076 reportSyntaxError(typeAnnotationsPushedBack.head.pos, Errors.IllegalStartOfType); |
3963 reportSyntaxError(typeAnnotationsPushedBack.head.pos, Errors.IllegalStartOfType); |
4077 } |
3964 } |
4078 typeAnnotationsPushedBack = List.nil(); |
3965 typeAnnotationsPushedBack = List.nil(); |
4079 } |
|
4080 if (lambdaParameter && isRestrictedLocalVarTypeName(type)) { |
|
4081 //implicit lambda parameter type (with 'var') |
|
4082 type = null; |
|
4083 } |
3966 } |
4084 return variableDeclaratorId(mods, type, lambdaParameter); |
3967 return variableDeclaratorId(mods, type, lambdaParameter); |
4085 } |
3968 } |
4086 |
3969 |
4087 protected JCVariableDecl implicitParameter() { |
3970 protected JCVariableDecl implicitParameter() { |