< prev index next >

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

Print this page

  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.parser;
  27 
  28 import java.util.*;
  29 import java.util.function.Function;
  30 import java.util.function.Predicate;
  31 import java.util.stream.Collectors;
  32 
  33 import com.sun.source.tree.CaseTree;
  34 import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
  35 import com.sun.source.tree.ModuleTree.ModuleKind;
  36 
  37 import com.sun.tools.javac.code.*;

  38 import com.sun.tools.javac.code.Source.Feature;
  39 import com.sun.tools.javac.parser.Tokens.*;
  40 import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
  41 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  42 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  43 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
  44 import com.sun.tools.javac.tree.*;
  45 import com.sun.tools.javac.tree.JCTree.*;
  46 import com.sun.tools.javac.util.*;
  47 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
  48 import com.sun.tools.javac.util.JCDiagnostic.Error;
  49 import com.sun.tools.javac.util.JCDiagnostic.Fragment;
  50 import com.sun.tools.javac.util.List;
  51 

  52 import static com.sun.tools.javac.parser.Tokens.TokenKind.*;
  53 import static com.sun.tools.javac.parser.Tokens.TokenKind.ASSERT;
  54 import static com.sun.tools.javac.parser.Tokens.TokenKind.CASE;
  55 import static com.sun.tools.javac.parser.Tokens.TokenKind.CATCH;
  56 import static com.sun.tools.javac.parser.Tokens.TokenKind.EQ;
  57 import static com.sun.tools.javac.parser.Tokens.TokenKind.GT;
  58 import static com.sun.tools.javac.parser.Tokens.TokenKind.IMPORT;
  59 import static com.sun.tools.javac.parser.Tokens.TokenKind.LT;

  60 import static com.sun.tools.javac.tree.JCTree.Tag.*;
  61 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.ImplicitAndExplicitNotAllowed;
  62 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.VarAndExplicitNotAllowed;
  63 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.VarAndImplicitNotAllowed;
  64 import java.util.function.BiFunction;
  65 
  66 /**
  67  * The parser maps a token sequence into an abstract syntax tree.
  68  * The parser is a hand-written recursive-descent parser that
  69  * implements the grammar described in the Java Language Specification.
  70  * For efficiency reasons, an operator precedence scheme is used
  71  * for parsing binary operation expressions.
  72  *
  73  *  <p><b>This is NOT part of any supported API.
  74  *  If you write code that depends on this, you do so at your own risk.
  75  *  This code and its internal interfaces are subject to change or
  76  *  deletion without notice.</b>
  77  */
  78 public class JavacParser implements Parser {
  79 

 168     protected JavacParser(ParserFactory fac,
 169                      Lexer S,
 170                      boolean keepDocComments,
 171                      boolean keepLineMap,
 172                      boolean keepEndPositions,
 173                      boolean parseModuleInfo) {
 174         this.S = S;
 175         nextToken(); // prime the pump
 176         this.F = fac.F;
 177         this.log = fac.log;
 178         this.names = fac.names;
 179         this.source = fac.source;
 180         this.preview = fac.preview;
 181         this.allowStringFolding = fac.options.getBoolean("allowStringFolding", true);
 182         this.keepDocComments = keepDocComments;
 183         this.parseModuleInfo = parseModuleInfo;
 184         docComments = newDocCommentTable(keepDocComments, fac);
 185         this.keepLineMap = keepLineMap;
 186         this.errorTree = F.Erroneous();
 187         endPosTable = newEndPosTable(keepEndPositions);

 188         this.allowYieldStatement = Feature.SWITCH_EXPRESSION.allowedInSource(source);
 189         this.allowRecords = Feature.RECORDS.allowedInSource(source);
 190         this.allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);


 191     }
 192 
 193     protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) {
 194         return  keepEndPositions
 195                 ? new SimpleEndPosTable(this)
 196                 : new EmptyEndPosTable(this);
 197     }
 198 
 199     protected DocCommentTable newDocCommentTable(boolean keepDocComments, ParserFactory fac) {
 200         return keepDocComments ? new LazyDocCommentTable(fac) : null;
 201     }
 202 
 203     /** Switch: should we fold strings?
 204      */
 205     boolean allowStringFolding;
 206 




 207     /** Switch: should we keep docComments?
 208      */
 209     boolean keepDocComments;
 210 
 211     /** Switch: should we keep line table?
 212      */
 213     boolean keepLineMap;
 214 
 215     /** Switch: is "this" allowed as an identifier?
 216      * This is needed to parse receiver types.
 217      */
 218     boolean allowThisIdent;
 219 
 220     /** Switch: is yield statement allowed in this source level?
 221      */
 222     boolean allowYieldStatement;
 223 
 224     /** Switch: are records allowed in this source level?
 225      */
 226     boolean allowRecords;
 227 




 228     /** Switch: are sealed types allowed in this source level?
 229      */
 230     boolean allowSealedTypes;
 231 
 232     /** The type of the method receiver, as specified by a first "this" parameter.
 233      */
 234     JCVariableDecl receiverParam;
 235 
 236     /** When terms are parsed, the mode determines which is expected:
 237      *     mode = EXPR        : an expression
 238      *     mode = TYPE        : a type
 239      *     mode = NOPARAMS    : no parameters allowed for type
 240      *     mode = TYPEARG     : type argument
 241      *     mode |= NOLAMBDA   : lambdas are not allowed
 242      */
 243     protected static final int EXPR = 0x1;
 244     protected static final int TYPE = 0x2;
 245     protected static final int NOPARAMS = 0x4;
 246     protected static final int TYPEARG = 0x8;
 247     protected static final int DIAMOND = 0x10;

 286 
 287     protected boolean peekToken(Predicate<TokenKind> tk1, Predicate<TokenKind> tk2) {
 288         return peekToken(0, tk1, tk2);
 289     }
 290 
 291     protected boolean peekToken(int lookahead, Predicate<TokenKind> tk1, Predicate<TokenKind> tk2) {
 292         return tk1.test(S.token(lookahead + 1).kind) &&
 293                 tk2.test(S.token(lookahead + 2).kind);
 294     }
 295 
 296     protected boolean peekToken(Predicate<TokenKind> tk1, Predicate<TokenKind> tk2, Predicate<TokenKind> tk3) {
 297         return peekToken(0, tk1, tk2, tk3);
 298     }
 299 
 300     protected boolean peekToken(int lookahead, Predicate<TokenKind> tk1, Predicate<TokenKind> tk2, Predicate<TokenKind> tk3) {
 301         return tk1.test(S.token(lookahead + 1).kind) &&
 302                 tk2.test(S.token(lookahead + 2).kind) &&
 303                 tk3.test(S.token(lookahead + 3).kind);
 304     }
 305 







 306     @SuppressWarnings("unchecked")
 307     protected boolean peekToken(Predicate<TokenKind>... kinds) {
 308         return peekToken(0, kinds);
 309     }
 310 
 311     @SuppressWarnings("unchecked")
 312     protected boolean peekToken(int lookahead, Predicate<TokenKind>... kinds) {
 313         for (Predicate<TokenKind> kind : kinds) {
 314             if (!kind.test(S.token(++lookahead).kind)) {
 315                 return false;
 316             }
 317         }
 318         return true;
 319     }
 320 
 321     /* ---------- error recovery -------------- */
 322 
 323     private JCErroneous errorTree;
 324 
 325     /** Skip forward until a suitable stop token is found.

 455 
 456     /** If next input token matches given token, skip it, otherwise report
 457      *  an error.
 458      */
 459     public void accept(TokenKind tk) {
 460         accept(tk, Errors::Expected);
 461     }
 462 
 463     /** If next input token matches given token, skip it, otherwise report
 464      *  an error.
 465      */
 466     public void accept(TokenKind tk, Function<TokenKind, Error> errorProvider) {
 467         if (token.kind == tk) {
 468             nextToken();
 469         } else {
 470             setErrorEndPos(token.pos);
 471             reportSyntaxError(S.prevToken().endPos, errorProvider.apply(tk));
 472         }
 473     }
 474 
















 475     /** Report an illegal start of expression/type error at given position.
 476      */
 477     JCExpression illegal(int pos) {
 478         setErrorEndPos(pos);
 479         if ((mode & EXPR) != 0)
 480             return syntaxError(pos, Errors.IllegalStartOfExpr);
 481         else
 482             return syntaxError(pos, Errors.IllegalStartOfType);
 483 
 484     }
 485 
 486     /** Report an illegal start of expression/type error at current position.
 487      */
 488     JCExpression illegal() {
 489         return illegal(token.pos);
 490     }
 491 
 492     /** Diagnose a modifier flag from the set, if any. */
 493     protected void checkNoMods(long mods) {
 494         checkNoMods(token.pos, mods);

1155                 selectTypeMode();
1156                 return typeArgument();
1157             } else
1158                 return illegal();
1159         case PLUSPLUS: case SUBSUB: case BANG: case TILDE: case PLUS: case SUB:
1160             if (typeArgs == null && (mode & EXPR) != 0) {
1161                 TokenKind tk = token.kind;
1162                 nextToken();
1163                 selectExprMode();
1164                 if (tk == SUB &&
1165                     (token.kind == INTLITERAL || token.kind == LONGLITERAL) &&
1166                     token.radix() == 10) {
1167                     selectExprMode();
1168                     t = literal(names.hyphen, pos);
1169                 } else {
1170                     t = term3();
1171                     return F.at(pos).Unary(unoptag(tk), t);
1172                 }
1173             } else return illegal();
1174             break;















1175         case LPAREN:
1176             if (typeArgs == null && (mode & EXPR) != 0) {
1177                 ParensResult pres = analyzeParens();
1178                 switch (pres) {
1179                     case CAST:
1180                        accept(LPAREN);
1181                        selectTypeMode();
1182                        int pos1 = pos;
1183                        List<JCExpression> targets = List.of(t = parseType());
1184                        while (token.kind == AMP) {
1185                            checkSourceLevel(Feature.INTERSECTION_TYPES_IN_CAST);
1186                            accept(AMP);
1187                            targets = targets.prepend(parseType());
1188                        }
1189                        if (targets.length() > 1) {
1190                            t = toP(F.at(pos1).TypeIntersection(targets.reverse()));
1191                        }
1192                        accept(RPAREN);
1193                        selectExprMode();
1194                        JCExpression t1 = term3();

1323                         break loop;
1324                     case LPAREN:
1325                         if ((mode & EXPR) != 0) {
1326                             selectExprMode();
1327                             t = arguments(typeArgs, t);
1328                             if (!annos.isEmpty()) t = illegal(annos.head.pos);
1329                             typeArgs = null;
1330                         }
1331                         break loop;
1332                     case DOT:
1333                         nextToken();
1334                         if (token.kind == TokenKind.IDENTIFIER && typeArgs != null) {
1335                             return illegal();
1336                         }
1337                         int oldmode = mode;
1338                         mode &= ~NOPARAMS;
1339                         typeArgs = typeArgumentsOpt(EXPR);
1340                         mode = oldmode;
1341                         if ((mode & EXPR) != 0) {
1342                             switch (token.kind) {






1343                             case CLASS:
1344                                 if (typeArgs != null) return illegal();
1345                                 selectExprMode();
1346                                 t = to(F.at(pos).Select(t, names._class));
1347                                 nextToken();
1348                                 break loop;
1349                             case THIS:
1350                                 if (typeArgs != null) return illegal();
1351                                 selectExprMode();
1352                                 t = to(F.at(pos).Select(t, names._this));
1353                                 nextToken();
1354                                 break loop;
1355                             case SUPER:
1356                                 selectExprMode();
1357                                 t = to(F.at(pos).Select(t, names._super));
1358                                 t = superSuffix(typeArgs, t);
1359                                 typeArgs = null;
1360                                 break loop;
1361                             case NEW:
1362                                 if (typeArgs != null) return illegal();

1380                             token.kind == MONKEYS_AT) {
1381                             //error recovery, case like:
1382                             //int i = expr.<missing-ident>
1383                             //@Deprecated
1384                             if (typeArgs != null) illegal();
1385                             return toP(t);
1386                         }
1387                         if (tyannos != null && tyannos.nonEmpty()) {
1388                             t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
1389                         }
1390                         break;
1391                     case ELLIPSIS:
1392                         if (this.permitTypeAnnotationsPushBack) {
1393                             this.typeAnnotationsPushedBack = annos;
1394                         } else if (annos.nonEmpty()) {
1395                             // Don't return here -- error recovery attempt
1396                             illegal(annos.head.pos);
1397                         }
1398                         break loop;
1399                     case LT:
1400                         if ((mode & TYPE) == 0 && isUnboundMemberRef()) {
1401                             //this is an unbound method reference whose qualifier
1402                             //is a generic type i.e. A<S>::m

1403                             int pos1 = token.pos;
1404                             accept(LT);
1405                             ListBuffer<JCExpression> args = new ListBuffer<>();
1406                             args.append(typeArgument());
1407                             while (token.kind == COMMA) {
1408                                 nextToken();
1409                                 args.append(typeArgument());
1410                             }
1411                             accept(GT);
1412                             t = toP(F.at(pos1).TypeApply(t, args.toList()));
1413                             while (token.kind == DOT) {
1414                                 nextToken();






1415                                 selectTypeMode();
1416                                 t = toP(F.at(token.pos).Select(t, ident()));
1417                                 t = typeArgumentsOpt(t);
1418                             }
1419                             t = bracketsOpt(t);
1420                             if (token.kind != COLCOL) {
1421                                 //method reference expected here
1422                                 t = illegal();
1423                             }
1424                             selectExprMode();
1425                             return term3Rest(t, typeArgs);
1426                         }
1427                         break loop;
1428                     default:
1429                         break loop;
1430                     }
1431                 }
1432             }
1433             if (typeArgs != null) illegal();
1434             t = typeArgumentsOpt(t);

1561                         }
1562                         return t;
1563                     }
1564                     mode = oldmode;
1565                 }
1566                 if ((mode & EXPR) != 0) {
1567                     selectExprMode();
1568                     JCExpression t1 = term();
1569                     t = to(F.at(pos1).Indexed(t, t1));
1570                 }
1571                 accept(RBRACKET);
1572             } else if (token.kind == DOT) {
1573                 nextToken();
1574                 typeArgs = typeArgumentsOpt(EXPR);
1575                 if (token.kind == SUPER && (mode & EXPR) != 0) {
1576                     selectExprMode();
1577                     t = to(F.at(pos1).Select(t, names._super));
1578                     nextToken();
1579                     t = arguments(typeArgs, t);
1580                     typeArgs = null;
1581                 } else if (token.kind == NEW && (mode & EXPR) != 0) {
1582                     if (typeArgs != null) return illegal();
1583                     selectExprMode();
1584                     int pos2 = token.pos;
1585                     nextToken();
1586                     if (token.kind == LT) typeArgs = typeArguments(false);
1587                     t = innerCreator(pos2, typeArgs, t);
1588                     typeArgs = null;
1589                 } else {
1590                     List<JCAnnotation> tyannos = null;
1591                     if ((mode & TYPE) != 0 && token.kind == MONKEYS_AT) {
1592                         // is the mode check needed?
1593                         tyannos = typeAnnotationsOpt();
1594                     }
1595                     t = toP(F.at(pos1).Select(t, ident(true)));
1596                     if (token.pos <= endPosTable.errorEndPos &&
1597                         token.kind == MONKEYS_AT) {
1598                         //error recovery, case like:
1599                         //int i = expr.<missing-ident>
1600                         //@Deprecated
1601                         break;

1615                 if (!annos.isEmpty()) {
1616                     if (permitTypeAnnotationsPushBack)
1617                         typeAnnotationsPushedBack = annos;
1618                     else
1619                         return illegal(annos.head.pos);
1620                 }
1621                 break;
1622             }
1623         }
1624         while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && (mode & EXPR) != 0) {
1625             selectExprMode();
1626             t = to(F.at(token.pos).Unary(
1627                   token.kind == PLUSPLUS ? POSTINC : POSTDEC, t));
1628             nextToken();
1629         }
1630         return toP(t);
1631     }
1632 
1633     /**
1634      * If we see an identifier followed by a '&lt;' it could be an unbound
1635      * method reference or a binary expression. To disambiguate, look for a

1636      * matching '&gt;' and see if the subsequent terminal is either '.' or '::'.
1637      */
1638     @SuppressWarnings("fallthrough")
1639     boolean isUnboundMemberRef() {
1640         int pos = 0, depth = 0;
1641         outer: for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
1642             switch (t.kind) {
1643                 case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
1644                 case DOT: case RBRACKET: case LBRACKET: case COMMA:
1645                 case BYTE: case SHORT: case INT: case LONG: case FLOAT:
1646                 case DOUBLE: case BOOLEAN: case CHAR:
1647                 case MONKEYS_AT:
1648                     break;
1649 
1650                 case LPAREN:
1651                     // skip annotation values
1652                     int nesting = 0;
1653                     for (; ; pos++) {
1654                         TokenKind tk2 = S.token(pos).kind;
1655                         switch (tk2) {
1656                             case EOF:
1657                                 return false;
1658                             case LPAREN:
1659                                 nesting++;

1741                     // based on subsequent token.
1742                     switch (S.token(lookahead + 1).kind) {
1743                         /*case PLUSPLUS: case SUBSUB: */
1744                         case BANG: case TILDE:
1745                         case LPAREN: case THIS: case SUPER:
1746                         case INTLITERAL: case LONGLITERAL: case FLOATLITERAL:
1747                         case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL:
1748                         case TRUE: case FALSE: case NULL:
1749                         case NEW: case IDENTIFIER: case ASSERT: case ENUM: case UNDERSCORE:
1750                         case SWITCH:
1751                         case BYTE: case SHORT: case CHAR: case INT:
1752                         case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
1753                             return ParensResult.CAST;
1754                         default:
1755                             return defaultResult;
1756                     }
1757                 case UNDERSCORE:
1758                 case ASSERT:
1759                 case ENUM:
1760                 case IDENTIFIER:
1761                     if (peekToken(lookahead, LAX_IDENTIFIER)) {
1762                         // Identifier, Identifier/'_'/'assert'/'enum' -> explicit lambda
1763                         return ParensResult.EXPLICIT_LAMBDA;
1764                     } else if (peekToken(lookahead, RPAREN, ARROW)) {
1765                         // Identifier, ')' '->' -> implicit lambda
1766                         return (mode & NOLAMBDA) == 0 ? ParensResult.IMPLICIT_LAMBDA
1767                                                       : ParensResult.PARENS;
1768                     } else if (depth == 0 && peekToken(lookahead, COMMA)) {
1769                         defaultResult = ParensResult.IMPLICIT_LAMBDA;
1770                     }
1771                     type = false;
1772                     break;
1773                 case FINAL:
1774                 case ELLIPSIS:
1775                     //those can only appear in explicit lambdas
1776                     return ParensResult.EXPLICIT_LAMBDA;
1777                 case MONKEYS_AT:
1778                     type = true;
1779                     lookahead = skipAnnotation(lookahead);
1780                     break;
1781                 case LBRACKET:
1782                     if (peekToken(lookahead, RBRACKET, LAX_IDENTIFIER)) {

1794                         break;
1795                     } else {
1796                         return ParensResult.PARENS;
1797                     }
1798                 case LT:
1799                     depth++; break;
1800                 case GTGTGT:
1801                     depth--;
1802                 case GTGT:
1803                     depth--;
1804                 case GT:
1805                     depth--;
1806                     if (depth == 0) {
1807                         if (peekToken(lookahead, RPAREN) ||
1808                                 peekToken(lookahead, AMP)) {
1809                             // '>', ')' -> cast
1810                             // '>', '&' -> cast
1811                             return ParensResult.CAST;
1812                         } else if (peekToken(lookahead, LAX_IDENTIFIER, COMMA) ||
1813                                 peekToken(lookahead, LAX_IDENTIFIER, RPAREN, ARROW) ||


1814                                 peekToken(lookahead, ELLIPSIS)) {
1815                             // '>', Identifier/'_'/'assert'/'enum', ',' -> explicit lambda
1816                             // '>', Identifier/'_'/'assert'/'enum', ')', '->' -> explicit lambda
1817                             // '>', '...' -> explicit lambda
1818                             return ParensResult.EXPLICIT_LAMBDA;
1819                         }
1820                         //it looks a type, but could still be (i) a cast to generic type,
1821                         //(ii) an unbound method reference or (iii) an explicit lambda
1822                         type = true;
1823                         break;
1824                     } else if (depth < 0) {
1825                         //unbalanced '<', '>' - not a generic type
1826                         return ParensResult.PARENS;
1827                     }
1828                     break;
1829                 default:
1830                     //this includes EOF
1831                     return defaultResult;
1832             }
1833         }

2219 
2220     private JCExpression bracketsOptCont(JCExpression t, int pos,
2221             List<JCAnnotation> annotations) {
2222         accept(RBRACKET);
2223         t = bracketsOpt(t);
2224         t = toP(F.at(pos).TypeArray(t));
2225         if (annotations.nonEmpty()) {
2226             t = toP(F.at(pos).AnnotatedType(annotations, t));
2227         }
2228         return t;
2229     }
2230 
2231     /** BracketsSuffixExpr = "." CLASS
2232      *  BracketsSuffixType =
2233      */
2234     JCExpression bracketsSuffix(JCExpression t) {
2235         if ((mode & EXPR) != 0 && token.kind == DOT) {
2236             selectExprMode();
2237             int pos = token.pos;
2238             nextToken();
2239             accept(CLASS);
2240             if (token.pos == endPosTable.errorEndPos) {
2241                 // error recovery
2242                 Name name;
2243                 if (LAX_IDENTIFIER.test(token.kind)) {
2244                     name = token.name();
2245                     nextToken();
2246                 } else {
2247                     name = names.error;
2248                 }
2249                 t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name))));
2250             } else {
2251                 Tag tag = t.getTag();
2252                 // Type annotations are illegal on class literals. Annotated non array class literals
2253                 // are complained about directly in term3(), Here check for type annotations on dimensions
2254                 // taking care to handle some interior dimension(s) being annotated.
2255                 if ((tag == TYPEARRAY && TreeInfo.containsTypeAnnotation(t)) || tag == ANNOTATED_TYPE)
2256                     syntaxError(token.pos, Errors.NoAnnotationsOnDotClass);
2257                 t = toP(F.at(pos).Select(t, names._class));




2258             }
2259         } else if ((mode & TYPE) != 0) {
2260             if (token.kind != COLCOL) {
2261                 selectTypeMode();
2262             }
2263         } else if (token.kind != COLCOL) {
2264             syntaxError(token.pos, Errors.DotClassExpected);
2265         }
2266         return t;
2267     }
2268 
2269     /**
2270      * MemberReferenceSuffix = "::" [TypeArguments] Ident
2271      *                       | "::" [TypeArguments] "new"
2272      */
2273     JCExpression memberReferenceSuffix(JCExpression t) {
2274         int pos1 = token.pos;
2275         accept(COLCOL);
2276         return memberReferenceSuffix(pos1, t);
2277     }

2282         List<JCExpression> typeArgs = null;
2283         if (token.kind == LT) {
2284             typeArgs = typeArguments(false);
2285         }
2286         Name refName;
2287         ReferenceMode refMode;
2288         if (token.kind == NEW) {
2289             refMode = ReferenceMode.NEW;
2290             refName = names.init;
2291             nextToken();
2292         } else {
2293             refMode = ReferenceMode.INVOKE;
2294             refName = ident();
2295         }
2296         return toP(F.at(t.getStartPosition()).Reference(refMode, refName, t, typeArgs));
2297     }
2298 
2299     /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
2300      */
2301     JCExpression creator(int newpos, List<JCExpression> typeArgs) {
2302         List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
2303 



2304         switch (token.kind) {
2305         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
2306         case DOUBLE: case BOOLEAN:




2307             if (typeArgs == null) {
2308                 if (newAnnotations.isEmpty()) {
2309                     return arrayCreatorRest(newpos, basicType());
2310                 } else {
2311                     return arrayCreatorRest(newpos, toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, basicType())));
2312                 }
2313             }
2314             break;
2315         default:
2316         }
2317         JCExpression t = qualident(true);
2318 
2319         int oldmode = mode;
2320         selectTypeMode();
2321         boolean diamondFound = false;
2322         int lastTypeargsPos = -1;
2323         if (token.kind == LT) {
2324             lastTypeargsPos = token.pos;
2325             t = typeArguments(t, true);
2326             diamondFound = (mode & DIAMOND) != 0;

2355             JCExpression e = arrayCreatorRest(newpos, t);
2356             if (diamondFound) {
2357                 reportSyntaxError(lastTypeargsPos, Errors.CannotCreateArrayWithDiamond);
2358                 return toP(F.at(newpos).Erroneous(List.of(e)));
2359             }
2360             else if (typeArgs != null) {
2361                 int pos = newpos;
2362                 if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) {
2363                     // note: this should always happen but we should
2364                     // not rely on this as the parser is continuously
2365                     // modified to improve error recovery.
2366                     pos = typeArgs.head.pos;
2367                 }
2368                 setErrorEndPos(S.prevToken().endPos);
2369                 JCErroneous err = F.at(pos).Erroneous(typeArgs.prepend(e));
2370                 reportSyntaxError(err, Errors.CannotCreateArrayWithTypeArguments);
2371                 return toP(err);
2372             }
2373             return e;
2374         } else if (token.kind == LPAREN) {



2375             // handle type annotations for instantiations and anonymous classes
2376             if (newAnnotations.nonEmpty()) {
2377                 t = insertAnnotationsToMostInner(t, newAnnotations, false);
2378             }
2379             return classCreatorRest(newpos, null, typeArgs, t);





2380         } else {
2381             setErrorEndPos(token.pos);
2382             reportSyntaxError(token.pos, Errors.Expected2(LPAREN, LBRACKET));
2383             t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.nil(), null));
2384             return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
2385         }
2386     }
2387 
2388     /** InnerCreator = [Annotations] Ident [TypeArguments] ClassCreatorRest
2389      */
2390     JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
2391         List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
2392 
2393         JCExpression t = toP(F.at(token.pos).Ident(ident()));
2394 
2395         if (newAnnotations.nonEmpty()) {
2396             t = toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, t));
2397         }
2398 
2399         if (token.kind == LT) {
2400             int oldmode = mode;
2401             t = typeArguments(t, true);
2402             mode = oldmode;
2403         }
2404         return classCreatorRest(newpos, encl, typeArgs, t);
2405     }
2406 
2407     /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
2408      *                         | Expression "]" {[Annotations]  "[" Expression "]"} BracketsOpt )
2409      */
2410     JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
2411         List<JCAnnotation> annos = typeAnnotationsOpt();
2412 
2413         accept(LBRACKET);
2414         if (token.kind == RBRACKET) {
2415             accept(RBRACKET);
2416             elemtype = bracketsOpt(elemtype, annos);
2417             if (token.kind == LBRACE) {
2418                 JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
2419                 if (annos.nonEmpty()) {
2420                     // when an array initializer is present then
2421                     // the parsed annotations should target the
2422                     // new array tree
2423                     // bracketsOpt inserts the annotation in
2424                     // elemtype, and it needs to be corrected

2462             if (token.kind == LBRACE) {
2463                 elems = arrayInitializerElements(newpos, elemtype);
2464             }
2465 
2466             JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), elems));
2467             na.dimAnnotations = dimAnnotations.toList();
2468 
2469             if (elems != null) {
2470                 return syntaxError(errpos, List.of(na), Errors.IllegalArrayCreationBothDimensionAndInitialization);
2471             }
2472 
2473             return na;
2474         }
2475     }
2476 
2477     /** ClassCreatorRest = Arguments [ClassBody]
2478      */
2479     JCNewClass classCreatorRest(int newpos,
2480                                   JCExpression encl,
2481                                   List<JCExpression> typeArgs,
2482                                   JCExpression t)

2483     {
2484         List<JCExpression> args = arguments();
2485         JCClassDecl body = null;
2486         if (token.kind == LBRACE) {
2487             int pos = token.pos;
2488             List<JCTree> defs = classInterfaceOrRecordBody(names.empty, false, false);
2489             JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2490             body = toP(F.at(pos).AnonymousClassDef(mods, defs));
2491         }
2492         return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));

2493     }
2494 
2495     /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
2496      */
2497     JCExpression arrayInitializer(int newpos, JCExpression t) {
2498         List<JCExpression> elems = arrayInitializerElements(newpos, t);
2499         return toP(F.at(newpos).NewArray(t, List.nil(), elems));
2500     }
2501 
2502     List<JCExpression> arrayInitializerElements(int newpos, JCExpression t) {
2503         accept(LBRACE);
2504         ListBuffer<JCExpression> elems = new ListBuffer<>();
2505         if (token.kind == COMMA) {
2506             nextToken();
2507         } else if (token.kind != RBRACE) {
2508             elems.append(variableInitializer());
2509             while (token.kind == COMMA) {
2510                 nextToken();
2511                 if (token.kind == RBRACE) break;
2512                 elems.append(variableInitializer());

2705                     accept(SEMI);
2706                     return List.of(toP(F.at(pos).Yield(t)));
2707                 }
2708 
2709                 //else intentional fall-through
2710             } else {
2711                 if (isNonSealedClassStart(true)) {
2712                     log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2713                     nextToken();
2714                     nextToken();
2715                     nextToken();
2716                     return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.comment(CommentStyle.JAVADOC)));
2717                 } else if (isSealedClassStart(true)) {
2718                     checkSourceLevel(Feature.SEALED_CLASSES);
2719                     log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2720                     nextToken();
2721                     return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.comment(CommentStyle.JAVADOC)));
2722                 }
2723             }
2724         }




2725         if (isRecordStart() && allowRecords) {
2726             dc = token.comment(CommentStyle.JAVADOC);
2727             return List.of(recordDeclaration(F.at(pos).Modifiers(0), dc));
2728         } else {
2729             Token prevToken = token;
2730             JCExpression t = term(EXPR | TYPE);
2731             if (token.kind == COLON && t.hasTag(IDENT)) {
2732                 nextToken();
2733                 JCStatement stat = parseStatementAsBlock();
2734                 return List.of(F.at(pos).Labelled(prevToken.name(), stat));
2735             } else if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.test(token.kind)) {
2736                 pos = token.pos;
2737                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2738                 F.at(pos);
2739                 return localVariableDeclarations(mods, t);
2740             } else {
2741                 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
2742                 t = checkExprStat(t);
2743                 accept(SEMI);
2744                 JCExpressionStatement expr = toP(F.at(pos).Exec(t));

3142             nextToken();
3143             pos = token.pos;
3144             JCExpression t = parseExpression();
3145             // This Exec is a "StatementExpression"; it subsumes no terminating token
3146             stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
3147         }
3148         return stats;
3149     }
3150 
3151     /** ForInit = StatementExpression MoreStatementExpressions
3152      *           |  { FINAL | '@' Annotation } Type VariableDeclarators
3153      */
3154     List<JCStatement> forInit() {
3155         ListBuffer<JCStatement> stats = new ListBuffer<>();
3156         int pos = token.pos;
3157         if (token.kind == FINAL || token.kind == MONKEYS_AT) {
3158             return variableDeclarators(optFinal(0), parseType(true), stats, true).toList();
3159         } else {
3160             JCExpression t = term(EXPR | TYPE);
3161             if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.test(token.kind)) {
3162                 return variableDeclarators(modifiersOpt(), t, stats, true).toList();



3163             } else if ((lastmode & TYPE) != 0 && token.kind == COLON) {
3164                 log.error(DiagnosticFlag.SYNTAX, pos, Errors.BadInitializer("for-loop"));
3165                 return List.of((JCStatement)F.at(pos).VarDef(modifiersOpt(), names.error, t, null));
3166             } else {
3167                 return moreStatementExpressions(pos, t, stats).toList();
3168             }
3169         }
3170     }
3171 
3172     /** ForUpdate = StatementExpression MoreStatementExpressions
3173      */
3174     List<JCExpressionStatement> forUpdate() {
3175         return moreStatementExpressions(token.pos,
3176                                         parseExpression(),
3177                                         new ListBuffer<JCExpressionStatement>()).toList();
3178     }
3179 
3180     /** AnnotationsOpt = { '@' Annotation }
3181      *
3182      * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION

3239             case ABSTRACT    : flag = Flags.ABSTRACT; break;
3240             case NATIVE      : flag = Flags.NATIVE; break;
3241             case VOLATILE    : flag = Flags.VOLATILE; break;
3242             case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
3243             case STRICTFP    : flag = Flags.STRICTFP; break;
3244             case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
3245             case DEFAULT     : checkSourceLevel(Feature.DEFAULT_METHODS); flag = Flags.DEFAULT; break;
3246             case ERROR       : flag = 0; nextToken(); break;
3247             case IDENTIFIER  : {
3248                 if (isNonSealedClassStart(false)) {
3249                     flag = Flags.NON_SEALED;
3250                     nextToken();
3251                     nextToken();
3252                     break;
3253                 }
3254                 if (isSealedClassStart(false)) {
3255                     checkSourceLevel(Feature.SEALED_CLASSES);
3256                     flag = Flags.SEALED;
3257                     break;
3258                 }




3259                 break loop;
3260             }
3261             default: break loop;
3262             }
3263             if ((flags & flag) != 0) log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.RepeatedModifier);
3264             lastPos = token.pos;
3265             nextToken();
3266             if (flag == Flags.ANNOTATION) {
3267                 if (token.kind != INTERFACE) {
3268                     JCAnnotation ann = annotation(lastPos, Tag.ANNOTATION);
3269                     // if first modifier is an annotation, set pos to annotation's.
3270                     if (flags == 0 && annotations.isEmpty())
3271                         pos = ann.pos;
3272                     annotations.append(ann);
3273                     flag = 0;





3274                 }
3275             }
3276             flags |= flag;
3277         }
3278         switch (token.kind) {
3279         case ENUM: flags |= Flags.ENUM; break;
3280         case INTERFACE: flags |= Flags.INTERFACE; break;
3281         default: break;
3282         }
3283 
3284         /* A modifiers tree with no modifier tokens or annotations
3285          * has no text position. */
3286         if ((flags & (Flags.ModifierFlags | Flags.ANNOTATION)) == 0 && annotations.isEmpty())
3287             pos = Position.NOPOS;
3288 





3289         JCModifiers mods = F.at(pos).Modifiers(flags, annotations.toList());
3290         if (pos != Position.NOPOS)
3291             storeEnd(mods, S.prevToken().endPos);
3292         return mods;
3293     }
3294 
3295     /** Annotation              = "@" Qualident [ "(" AnnotationFieldValues ")" ]
3296      *
3297      * @param pos position of "@" token
3298      * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION
3299      */
3300     JCAnnotation annotation(int pos, Tag kind) {
3301         // accept(AT); // AT consumed by caller
3302         if (kind == Tag.TYPE_ANNOTATION) {
3303             checkSourceLevel(Feature.TYPE_ANNOTATIONS);
3304         }
3305         JCTree ident = qualident(false);
3306         List<JCExpression> fieldValues = annotationFieldValuesOpt();
3307         JCAnnotation ann;
3308         if (kind == Tag.ANNOTATION) {

3493             if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) {
3494                 return Source.JDK10;
3495             } else if (shouldWarn) {
3496                 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK10));
3497             }
3498         }
3499         if (name == names.yield) {
3500             if (allowYieldStatement) {
3501                 return Source.JDK14;
3502             } else if (shouldWarn) {
3503                 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK14));
3504             }
3505         }
3506         if (name == names.record) {
3507             if (allowRecords) {
3508                 return Source.JDK14;
3509             } else if (shouldWarn) {
3510                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK14));
3511             }
3512         }







3513         if (name == names.sealed) {
3514             if (allowSealedTypes) {
3515                 return Source.JDK15;
3516             } else if (shouldWarn) {
3517                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3518             }
3519         }
3520         if (name == names.permits) {
3521             if (allowSealedTypes) {
3522                 return Source.JDK15;
3523             } else if (shouldWarn) {
3524                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3525             }
3526         }
3527         return null;
3528     }
3529 
3530     /** VariableDeclaratorId = Ident BracketsOpt
3531      */
3532     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {

3893                         erroneousTree = syntaxError(pos, errs, Errors.Expected4(CLASS, INTERFACE, ENUM, "record"));
3894                     } else {
3895                         erroneousTree = syntaxError(pos, errs, Errors.Expected3(CLASS, INTERFACE, ENUM));
3896                     }
3897                 }
3898                 return toP(F.Exec(erroneousTree));
3899             }
3900         }
3901     }
3902 
3903     /** ClassDeclaration = CLASS Ident TypeParametersOpt [EXTENDS Type]
3904      *                     [IMPLEMENTS TypeList] ClassBody
3905      *  @param mods    The modifiers starting the class declaration
3906      *  @param dc       The documentation comment for the class, or null.
3907      */
3908     protected JCClassDecl classDeclaration(JCModifiers mods, Comment dc) {
3909         int pos = token.pos;
3910         accept(CLASS);
3911         Name name = typeName();
3912 










3913         List<JCTypeParameter> typarams = typeParametersOpt();
3914 
3915         JCExpression extending = null;
3916         if (token.kind == EXTENDS) {
3917             nextToken();
3918             extending = parseType();
3919         }
3920         List<JCExpression> implementing = List.nil();
3921         if (token.kind == IMPLEMENTS) {
3922             nextToken();
3923             implementing = typeList();
3924         }
3925         List<JCExpression> permitting = permitsClause(mods, "class");
3926         List<JCTree> defs = classInterfaceOrRecordBody(name, false, false);
3927         JCClassDecl result = toP(F.at(pos).ClassDef(
3928             mods, name, typarams, extending, implementing, permitting, defs));
3929         attach(result, dc);
3930         return result;
3931     }
3932 
3933     protected JCClassDecl recordDeclaration(JCModifiers mods, Comment dc) {
3934         int pos = token.pos;
3935         nextToken();
3936         mods.flags |= Flags.RECORD;
3937         Name name = typeName();









3938 
3939         List<JCTypeParameter> typarams = typeParametersOpt();
3940 
3941         List<JCVariableDecl> headerFields = formalParameters(false, true);
3942 
3943         List<JCExpression> implementing = List.nil();
3944         if (token.kind == IMPLEMENTS) {
3945             nextToken();
3946             implementing = typeList();
3947         }
3948         List<JCTree> defs = classInterfaceOrRecordBody(name, false, true);
3949         java.util.List<JCVariableDecl> fields = new ArrayList<>();
3950         for (JCVariableDecl field : headerFields) {
3951             fields.add(field);
3952         }
3953         for (JCTree def : defs) {
3954             if (def.hasTag(METHODDEF)) {
3955                 JCMethodDecl methDef = (JCMethodDecl) def;
3956                 if (methDef.name == names.init && methDef.params.isEmpty() && (methDef.mods.flags & Flags.COMPACT_RECORD_CONSTRUCTOR) != 0) {
3957                     ListBuffer<JCVariableDecl> tmpParams = new ListBuffer<>();

4353                         if (isVoid || typarams.nonEmpty()) {
4354                             JCMethodDecl m =
4355                                     toP(F.at(pos).MethodDef(mods, name, type, typarams,
4356                                                             List.nil(), List.nil(), null, null));
4357                             attach(m, dc);
4358                             err = List.of(m);
4359                         } else {
4360                             err = List.nil();
4361                         }
4362                         return List.of(syntaxError(token.pos, err, Errors.Expected(LPAREN)));
4363                     }
4364                 }
4365             }
4366         }
4367     }
4368 
4369     protected boolean isRecordStart() {
4370         if (token.kind == IDENTIFIER && token.name() == names.record &&
4371             (peekToken(TokenKind.IDENTIFIER, TokenKind.LPAREN) ||
4372              peekToken(TokenKind.IDENTIFIER, TokenKind.EOF) ||

4373              peekToken(TokenKind.IDENTIFIER, TokenKind.LT))) {
4374             checkSourceLevel(Feature.RECORDS);
4375             return true;
4376         } else {
4377             return false;
4378         }
4379     }
4380 
4381     protected boolean isNonSealedClassStart(boolean local) {
4382         if (isNonSealedIdentifier(token, 0)) {
4383             Token next = S.token(3);
4384             return allowedAfterSealedOrNonSealed(next, local, true);
4385         }
4386         return false;
4387     }
4388 
4389     protected boolean isNonSealedIdentifier(Token someToken, int lookAheadOffset) {
4390         if (someToken.name() == names.non && peekToken(lookAheadOffset, TokenKind.SUB, TokenKind.IDENTIFIER)) {
4391             Token tokenSub = S.token(lookAheadOffset + 1);
4392             Token tokenSealed = S.token(lookAheadOffset + 2);
4393             if (someToken.endPos == tokenSub.pos &&
4394                     tokenSub.endPos == tokenSealed.pos &&
4395                     tokenSealed.name() == names.sealed) {
4396                 checkSourceLevel(Feature.SEALED_CLASSES);
4397                 return true;
4398             }
4399         }
4400         return false;
4401     }
4402 
















4403     protected boolean isSealedClassStart(boolean local) {
4404         if (token.name() == names.sealed) {
4405             Token next = S.token(1);
4406             if (allowedAfterSealedOrNonSealed(next, local, false)) {
4407                 checkSourceLevel(Feature.SEALED_CLASSES);
4408                 return true;
4409             }
4410         }
4411         return false;
4412     }
4413 
4414     private boolean allowedAfterSealedOrNonSealed(Token next, boolean local, boolean currentIsNonSealed) {
4415         return local ?
4416             switch (next.kind) {
4417                 case MONKEYS_AT -> {
4418                     Token afterNext = S.token(2);
4419                     yield afterNext.kind != INTERFACE || currentIsNonSealed;
4420                 }
4421                 case ABSTRACT, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4422                 default -> false;

  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.parser;
  27 
  28 import java.util.*;
  29 import java.util.function.Function;
  30 import java.util.function.Predicate;
  31 import java.util.stream.Collectors;
  32 
  33 import com.sun.source.tree.CaseTree;
  34 import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
  35 import com.sun.source.tree.ModuleTree.ModuleKind;
  36 
  37 import com.sun.tools.javac.code.*;
  38 import com.sun.tools.javac.code.Flags.Flag;
  39 import com.sun.tools.javac.code.Source.Feature;
  40 import com.sun.tools.javac.parser.Tokens.*;
  41 import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
  42 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  43 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  44 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
  45 import com.sun.tools.javac.tree.*;
  46 import com.sun.tools.javac.tree.JCTree.*;
  47 import com.sun.tools.javac.util.*;
  48 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
  49 import com.sun.tools.javac.util.JCDiagnostic.Error;
  50 import com.sun.tools.javac.util.JCDiagnostic.Fragment;
  51 import com.sun.tools.javac.util.List;
  52 
  53 import static com.sun.tools.javac.code.Flags.asFlagSet;
  54 import static com.sun.tools.javac.parser.Tokens.TokenKind.*;
  55 import static com.sun.tools.javac.parser.Tokens.TokenKind.ASSERT;
  56 import static com.sun.tools.javac.parser.Tokens.TokenKind.CASE;
  57 import static com.sun.tools.javac.parser.Tokens.TokenKind.CATCH;
  58 import static com.sun.tools.javac.parser.Tokens.TokenKind.EQ;
  59 import static com.sun.tools.javac.parser.Tokens.TokenKind.GT;
  60 import static com.sun.tools.javac.parser.Tokens.TokenKind.IMPORT;
  61 import static com.sun.tools.javac.parser.Tokens.TokenKind.LT;
  62 import static com.sun.tools.javac.parser.Tokens.TokenKind.SYNCHRONIZED;
  63 import static com.sun.tools.javac.tree.JCTree.Tag.*;
  64 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.ImplicitAndExplicitNotAllowed;
  65 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.VarAndExplicitNotAllowed;
  66 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.VarAndImplicitNotAllowed;
  67 import java.util.function.BiFunction;
  68 
  69 /**
  70  * The parser maps a token sequence into an abstract syntax tree.
  71  * The parser is a hand-written recursive-descent parser that
  72  * implements the grammar described in the Java Language Specification.
  73  * For efficiency reasons, an operator precedence scheme is used
  74  * for parsing binary operation expressions.
  75  *
  76  *  <p><b>This is NOT part of any supported API.
  77  *  If you write code that depends on this, you do so at your own risk.
  78  *  This code and its internal interfaces are subject to change or
  79  *  deletion without notice.</b>
  80  */
  81 public class JavacParser implements Parser {
  82 

 171     protected JavacParser(ParserFactory fac,
 172                      Lexer S,
 173                      boolean keepDocComments,
 174                      boolean keepLineMap,
 175                      boolean keepEndPositions,
 176                      boolean parseModuleInfo) {
 177         this.S = S;
 178         nextToken(); // prime the pump
 179         this.F = fac.F;
 180         this.log = fac.log;
 181         this.names = fac.names;
 182         this.source = fac.source;
 183         this.preview = fac.preview;
 184         this.allowStringFolding = fac.options.getBoolean("allowStringFolding", true);
 185         this.keepDocComments = keepDocComments;
 186         this.parseModuleInfo = parseModuleInfo;
 187         docComments = newDocCommentTable(keepDocComments, fac);
 188         this.keepLineMap = keepLineMap;
 189         this.errorTree = F.Erroneous();
 190         endPosTable = newEndPosTable(keepEndPositions);
 191         this.allowWithFieldOperator = fac.options.isSet("allowWithFieldOperator");
 192         this.allowYieldStatement = Feature.SWITCH_EXPRESSION.allowedInSource(source);
 193         this.allowRecords = Feature.RECORDS.allowedInSource(source);
 194         this.allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);
 195         this.allowPrimitiveClasses = (!preview.isPreview(Feature.PRIMITIVE_CLASSES) || preview.isEnabled()) &&
 196                 Feature.PRIMITIVE_CLASSES.allowedInSource(source);
 197     }
 198 
 199     protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) {
 200         return  keepEndPositions
 201                 ? new SimpleEndPosTable(this)
 202                 : new EmptyEndPosTable(this);
 203     }
 204 
 205     protected DocCommentTable newDocCommentTable(boolean keepDocComments, ParserFactory fac) {
 206         return keepDocComments ? new LazyDocCommentTable(fac) : null;
 207     }
 208 
 209     /** Switch: should we fold strings?
 210      */
 211     boolean allowStringFolding;
 212 
 213     /** Switch: should we allow withField operator at source level ?
 214     */
 215     boolean allowWithFieldOperator;
 216 
 217     /** Switch: should we keep docComments?
 218      */
 219     boolean keepDocComments;
 220 
 221     /** Switch: should we keep line table?
 222      */
 223     boolean keepLineMap;
 224 
 225     /** Switch: is "this" allowed as an identifier?
 226      * This is needed to parse receiver types.
 227      */
 228     boolean allowThisIdent;
 229 
 230     /** Switch: is yield statement allowed in this source level?
 231      */
 232     boolean allowYieldStatement;
 233 
 234     /** Switch: are records allowed in this source level?
 235      */
 236     boolean allowRecords;
 237 
 238     /** Switch: are primitive classes allowed in this source level?
 239      */
 240      boolean allowPrimitiveClasses;
 241 
 242     /** Switch: are sealed types allowed in this source level?
 243      */
 244     boolean allowSealedTypes;
 245 
 246     /** The type of the method receiver, as specified by a first "this" parameter.
 247      */
 248     JCVariableDecl receiverParam;
 249 
 250     /** When terms are parsed, the mode determines which is expected:
 251      *     mode = EXPR        : an expression
 252      *     mode = TYPE        : a type
 253      *     mode = NOPARAMS    : no parameters allowed for type
 254      *     mode = TYPEARG     : type argument
 255      *     mode |= NOLAMBDA   : lambdas are not allowed
 256      */
 257     protected static final int EXPR = 0x1;
 258     protected static final int TYPE = 0x2;
 259     protected static final int NOPARAMS = 0x4;
 260     protected static final int TYPEARG = 0x8;
 261     protected static final int DIAMOND = 0x10;

 300 
 301     protected boolean peekToken(Predicate<TokenKind> tk1, Predicate<TokenKind> tk2) {
 302         return peekToken(0, tk1, tk2);
 303     }
 304 
 305     protected boolean peekToken(int lookahead, Predicate<TokenKind> tk1, Predicate<TokenKind> tk2) {
 306         return tk1.test(S.token(lookahead + 1).kind) &&
 307                 tk2.test(S.token(lookahead + 2).kind);
 308     }
 309 
 310     protected boolean peekToken(Predicate<TokenKind> tk1, Predicate<TokenKind> tk2, Predicate<TokenKind> tk3) {
 311         return peekToken(0, tk1, tk2, tk3);
 312     }
 313 
 314     protected boolean peekToken(int lookahead, Predicate<TokenKind> tk1, Predicate<TokenKind> tk2, Predicate<TokenKind> tk3) {
 315         return tk1.test(S.token(lookahead + 1).kind) &&
 316                 tk2.test(S.token(lookahead + 2).kind) &&
 317                 tk3.test(S.token(lookahead + 3).kind);
 318     }
 319 
 320     protected boolean peekToken(int lookahead, Predicate<TokenKind> tk1, Predicate<TokenKind> tk2, Predicate<TokenKind> tk3, Predicate<TokenKind> tk4) {
 321         return tk1.test(S.token(lookahead + 1).kind) &&
 322                 tk2.test(S.token(lookahead + 2).kind) &&
 323                 tk3.test(S.token(lookahead + 3).kind) &&
 324                 tk4.test(S.token(lookahead + 4).kind);
 325     }
 326 
 327     @SuppressWarnings("unchecked")
 328     protected boolean peekToken(Predicate<TokenKind>... kinds) {
 329         return peekToken(0, kinds);
 330     }
 331 
 332     @SuppressWarnings("unchecked")
 333     protected boolean peekToken(int lookahead, Predicate<TokenKind>... kinds) {
 334         for (Predicate<TokenKind> kind : kinds) {
 335             if (!kind.test(S.token(++lookahead).kind)) {
 336                 return false;
 337             }
 338         }
 339         return true;
 340     }
 341 
 342     /* ---------- error recovery -------------- */
 343 
 344     private JCErroneous errorTree;
 345 
 346     /** Skip forward until a suitable stop token is found.

 476 
 477     /** If next input token matches given token, skip it, otherwise report
 478      *  an error.
 479      */
 480     public void accept(TokenKind tk) {
 481         accept(tk, Errors::Expected);
 482     }
 483 
 484     /** If next input token matches given token, skip it, otherwise report
 485      *  an error.
 486      */
 487     public void accept(TokenKind tk, Function<TokenKind, Error> errorProvider) {
 488         if (token.kind == tk) {
 489             nextToken();
 490         } else {
 491             setErrorEndPos(token.pos);
 492             reportSyntaxError(S.prevToken().endPos, errorProvider.apply(tk));
 493         }
 494     }
 495 
 496     /** If next input token matches one of the two given tokens, skip it, otherwise report
 497      *  an error.
 498      *
 499      * @return The actual token kind.
 500      */
 501     public TokenKind accept2(TokenKind tk1, TokenKind tk2) {
 502         TokenKind returnValue = token.kind;
 503         if (token.kind == tk1 || token.kind == tk2) {
 504             nextToken();
 505         } else {
 506             setErrorEndPos(token.pos);
 507             reportSyntaxError(S.prevToken().endPos, Errors.Expected2(tk1, tk2));
 508         }
 509         return returnValue;
 510     }
 511 
 512     /** Report an illegal start of expression/type error at given position.
 513      */
 514     JCExpression illegal(int pos) {
 515         setErrorEndPos(pos);
 516         if ((mode & EXPR) != 0)
 517             return syntaxError(pos, Errors.IllegalStartOfExpr);
 518         else
 519             return syntaxError(pos, Errors.IllegalStartOfType);
 520 
 521     }
 522 
 523     /** Report an illegal start of expression/type error at current position.
 524      */
 525     JCExpression illegal() {
 526         return illegal(token.pos);
 527     }
 528 
 529     /** Diagnose a modifier flag from the set, if any. */
 530     protected void checkNoMods(long mods) {
 531         checkNoMods(token.pos, mods);

1192                 selectTypeMode();
1193                 return typeArgument();
1194             } else
1195                 return illegal();
1196         case PLUSPLUS: case SUBSUB: case BANG: case TILDE: case PLUS: case SUB:
1197             if (typeArgs == null && (mode & EXPR) != 0) {
1198                 TokenKind tk = token.kind;
1199                 nextToken();
1200                 selectExprMode();
1201                 if (tk == SUB &&
1202                     (token.kind == INTLITERAL || token.kind == LONGLITERAL) &&
1203                     token.radix() == 10) {
1204                     selectExprMode();
1205                     t = literal(names.hyphen, pos);
1206                 } else {
1207                     t = term3();
1208                     return F.at(pos).Unary(unoptag(tk), t);
1209                 }
1210             } else return illegal();
1211             break;
1212         case WITHFIELD:
1213             if (!allowWithFieldOperator) {
1214                 log.error(pos, Errors.WithFieldOperatorDisallowed);
1215             }
1216             if (typeArgs == null && (mode & EXPR) != 0) {
1217                 nextToken();
1218                 accept(LPAREN);
1219                 mode = EXPR;
1220                 t = term();
1221                 accept(COMMA);
1222                 mode = EXPR;
1223                 JCExpression v = term();
1224                 accept(RPAREN);
1225                 return F.at(pos).WithField(t, v);
1226             } else return illegal();
1227         case LPAREN:
1228             if (typeArgs == null && (mode & EXPR) != 0) {
1229                 ParensResult pres = analyzeParens();
1230                 switch (pres) {
1231                     case CAST:
1232                        accept(LPAREN);
1233                        selectTypeMode();
1234                        int pos1 = pos;
1235                        List<JCExpression> targets = List.of(t = parseType());
1236                        while (token.kind == AMP) {
1237                            checkSourceLevel(Feature.INTERSECTION_TYPES_IN_CAST);
1238                            accept(AMP);
1239                            targets = targets.prepend(parseType());
1240                        }
1241                        if (targets.length() > 1) {
1242                            t = toP(F.at(pos1).TypeIntersection(targets.reverse()));
1243                        }
1244                        accept(RPAREN);
1245                        selectExprMode();
1246                        JCExpression t1 = term3();

1375                         break loop;
1376                     case LPAREN:
1377                         if ((mode & EXPR) != 0) {
1378                             selectExprMode();
1379                             t = arguments(typeArgs, t);
1380                             if (!annos.isEmpty()) t = illegal(annos.head.pos);
1381                             typeArgs = null;
1382                         }
1383                         break loop;
1384                     case DOT:
1385                         nextToken();
1386                         if (token.kind == TokenKind.IDENTIFIER && typeArgs != null) {
1387                             return illegal();
1388                         }
1389                         int oldmode = mode;
1390                         mode &= ~NOPARAMS;
1391                         typeArgs = typeArgumentsOpt(EXPR);
1392                         mode = oldmode;
1393                         if ((mode & EXPR) != 0) {
1394                             switch (token.kind) {
1395                             case DEFAULT:
1396                                 if (typeArgs != null) return illegal();
1397                                 selectExprMode();
1398                                 t = to(F.at(pos).DefaultValue(t));
1399                                 nextToken();
1400                                 break loop;
1401                             case CLASS:
1402                                 if (typeArgs != null) return illegal();
1403                                 selectExprMode();
1404                                 t = to(F.at(pos).Select(t, names._class));
1405                                 nextToken();
1406                                 break loop;
1407                             case THIS:
1408                                 if (typeArgs != null) return illegal();
1409                                 selectExprMode();
1410                                 t = to(F.at(pos).Select(t, names._this));
1411                                 nextToken();
1412                                 break loop;
1413                             case SUPER:
1414                                 selectExprMode();
1415                                 t = to(F.at(pos).Select(t, names._super));
1416                                 t = superSuffix(typeArgs, t);
1417                                 typeArgs = null;
1418                                 break loop;
1419                             case NEW:
1420                                 if (typeArgs != null) return illegal();

1438                             token.kind == MONKEYS_AT) {
1439                             //error recovery, case like:
1440                             //int i = expr.<missing-ident>
1441                             //@Deprecated
1442                             if (typeArgs != null) illegal();
1443                             return toP(t);
1444                         }
1445                         if (tyannos != null && tyannos.nonEmpty()) {
1446                             t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
1447                         }
1448                         break;
1449                     case ELLIPSIS:
1450                         if (this.permitTypeAnnotationsPushBack) {
1451                             this.typeAnnotationsPushedBack = annos;
1452                         } else if (annos.nonEmpty()) {
1453                             // Don't return here -- error recovery attempt
1454                             illegal(annos.head.pos);
1455                         }
1456                         break loop;
1457                     case LT:
1458                         if ((mode & TYPE) == 0 && isParameterizedTypePrefix()) {
1459                             //this is either an unbound method reference whose qualifier
1460                             //is a generic type i.e. A<S>::m or a default value creation of
1461                             //the form ValueType<S>.default
1462                             int pos1 = token.pos;
1463                             accept(LT);
1464                             ListBuffer<JCExpression> args = new ListBuffer<>();
1465                             args.append(typeArgument());
1466                             while (token.kind == COMMA) {
1467                                 nextToken();
1468                                 args.append(typeArgument());
1469                             }
1470                             accept(GT);
1471                             t = toP(F.at(pos1).TypeApply(t, args.toList()));
1472                             while (token.kind == DOT) {
1473                                 nextToken();
1474                                 if (token.kind == DEFAULT) {
1475                                     t =  toP(F.at(token.pos).DefaultValue(t));
1476                                     nextToken();
1477                                     selectExprMode();
1478                                     return term3Rest(t, typeArgs);
1479                                 }
1480                                 selectTypeMode();
1481                                 t = toP(F.at(token.pos).Select(t, ident()));
1482                                 t = typeArgumentsOpt(t);
1483                             }
1484                             t = bracketsOpt(t);
1485                             if (token.kind != COLCOL) {
1486                                 //method reference expected here
1487                                 t = illegal();
1488                             }
1489                             selectExprMode();
1490                             return term3Rest(t, typeArgs);
1491                         }
1492                         break loop;
1493                     default:
1494                         break loop;
1495                     }
1496                 }
1497             }
1498             if (typeArgs != null) illegal();
1499             t = typeArgumentsOpt(t);

1626                         }
1627                         return t;
1628                     }
1629                     mode = oldmode;
1630                 }
1631                 if ((mode & EXPR) != 0) {
1632                     selectExprMode();
1633                     JCExpression t1 = term();
1634                     t = to(F.at(pos1).Indexed(t, t1));
1635                 }
1636                 accept(RBRACKET);
1637             } else if (token.kind == DOT) {
1638                 nextToken();
1639                 typeArgs = typeArgumentsOpt(EXPR);
1640                 if (token.kind == SUPER && (mode & EXPR) != 0) {
1641                     selectExprMode();
1642                     t = to(F.at(pos1).Select(t, names._super));
1643                     nextToken();
1644                     t = arguments(typeArgs, t);
1645                     typeArgs = null;
1646                 } else if ((token.kind == NEW) && (mode & EXPR) != 0) {
1647                     if (typeArgs != null) return illegal();
1648                     selectExprMode();
1649                     int pos2 = token.pos;
1650                     nextToken();
1651                     if (token.kind == LT) typeArgs = typeArguments(false);
1652                     t = innerCreator(pos2, typeArgs, t);
1653                     typeArgs = null;
1654                 } else {
1655                     List<JCAnnotation> tyannos = null;
1656                     if ((mode & TYPE) != 0 && token.kind == MONKEYS_AT) {
1657                         // is the mode check needed?
1658                         tyannos = typeAnnotationsOpt();
1659                     }
1660                     t = toP(F.at(pos1).Select(t, ident(true)));
1661                     if (token.pos <= endPosTable.errorEndPos &&
1662                         token.kind == MONKEYS_AT) {
1663                         //error recovery, case like:
1664                         //int i = expr.<missing-ident>
1665                         //@Deprecated
1666                         break;

1680                 if (!annos.isEmpty()) {
1681                     if (permitTypeAnnotationsPushBack)
1682                         typeAnnotationsPushedBack = annos;
1683                     else
1684                         return illegal(annos.head.pos);
1685                 }
1686                 break;
1687             }
1688         }
1689         while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && (mode & EXPR) != 0) {
1690             selectExprMode();
1691             t = to(F.at(token.pos).Unary(
1692                   token.kind == PLUSPLUS ? POSTINC : POSTDEC, t));
1693             nextToken();
1694         }
1695         return toP(t);
1696     }
1697 
1698     /**
1699      * If we see an identifier followed by a '&lt;' it could be an unbound
1700      * method reference or a default value creation that uses a parameterized type
1701      * or a binary expression. To disambiguate, look for a
1702      * matching '&gt;' and see if the subsequent terminal is either '.' or '::'.
1703      */
1704     @SuppressWarnings("fallthrough")
1705     boolean isParameterizedTypePrefix() {
1706         int pos = 0, depth = 0;
1707         outer: for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
1708             switch (t.kind) {
1709                 case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
1710                 case DOT: case RBRACKET: case LBRACKET: case COMMA:
1711                 case BYTE: case SHORT: case INT: case LONG: case FLOAT:
1712                 case DOUBLE: case BOOLEAN: case CHAR:
1713                 case MONKEYS_AT:
1714                     break;
1715 
1716                 case LPAREN:
1717                     // skip annotation values
1718                     int nesting = 0;
1719                     for (; ; pos++) {
1720                         TokenKind tk2 = S.token(pos).kind;
1721                         switch (tk2) {
1722                             case EOF:
1723                                 return false;
1724                             case LPAREN:
1725                                 nesting++;

1807                     // based on subsequent token.
1808                     switch (S.token(lookahead + 1).kind) {
1809                         /*case PLUSPLUS: case SUBSUB: */
1810                         case BANG: case TILDE:
1811                         case LPAREN: case THIS: case SUPER:
1812                         case INTLITERAL: case LONGLITERAL: case FLOATLITERAL:
1813                         case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL:
1814                         case TRUE: case FALSE: case NULL:
1815                         case NEW: case IDENTIFIER: case ASSERT: case ENUM: case UNDERSCORE:
1816                         case SWITCH:
1817                         case BYTE: case SHORT: case CHAR: case INT:
1818                         case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
1819                             return ParensResult.CAST;
1820                         default:
1821                             return defaultResult;
1822                     }
1823                 case UNDERSCORE:
1824                 case ASSERT:
1825                 case ENUM:
1826                 case IDENTIFIER:
1827                     if (peekToken(lookahead, LAX_IDENTIFIER) || (peekToken(lookahead, QUES, LAX_IDENTIFIER) && (peekToken(lookahead + 2, RPAREN) || peekToken(lookahead + 2, COMMA)))) {
1828                         // Identifier[?], Identifier/'_'/'assert'/'enum' -> explicit lambda
1829                         return ParensResult.EXPLICIT_LAMBDA;
1830                     } else if (peekToken(lookahead, RPAREN, ARROW)) {
1831                         // Identifier, ')' '->' -> implicit lambda
1832                         return (mode & NOLAMBDA) == 0 ? ParensResult.IMPLICIT_LAMBDA
1833                                                       : ParensResult.PARENS;
1834                     } else if (depth == 0 && peekToken(lookahead, COMMA)) {
1835                         defaultResult = ParensResult.IMPLICIT_LAMBDA;
1836                     }
1837                     type = false;
1838                     break;
1839                 case FINAL:
1840                 case ELLIPSIS:
1841                     //those can only appear in explicit lambdas
1842                     return ParensResult.EXPLICIT_LAMBDA;
1843                 case MONKEYS_AT:
1844                     type = true;
1845                     lookahead = skipAnnotation(lookahead);
1846                     break;
1847                 case LBRACKET:
1848                     if (peekToken(lookahead, RBRACKET, LAX_IDENTIFIER)) {

1860                         break;
1861                     } else {
1862                         return ParensResult.PARENS;
1863                     }
1864                 case LT:
1865                     depth++; break;
1866                 case GTGTGT:
1867                     depth--;
1868                 case GTGT:
1869                     depth--;
1870                 case GT:
1871                     depth--;
1872                     if (depth == 0) {
1873                         if (peekToken(lookahead, RPAREN) ||
1874                                 peekToken(lookahead, AMP)) {
1875                             // '>', ')' -> cast
1876                             // '>', '&' -> cast
1877                             return ParensResult.CAST;
1878                         } else if (peekToken(lookahead, LAX_IDENTIFIER, COMMA) ||
1879                                 peekToken(lookahead, LAX_IDENTIFIER, RPAREN, ARROW) ||
1880                                 peekToken(lookahead, QUES, LAX_IDENTIFIER, COMMA) ||
1881                                 peekToken(lookahead, QUES, LAX_IDENTIFIER, RPAREN, ARROW) ||
1882                                 peekToken(lookahead, ELLIPSIS)) {
1883                             // '>', Identifier/'_'/'assert'/'enum', ',' -> explicit lambda
1884                             // '>', Identifier/'_'/'assert'/'enum', ')', '->' -> explicit lambda
1885                             // '>', '...' -> explicit lambda
1886                             return ParensResult.EXPLICIT_LAMBDA;
1887                         }
1888                         //it looks a type, but could still be (i) a cast to generic type,
1889                         //(ii) an unbound method reference or (iii) an explicit lambda
1890                         type = true;
1891                         break;
1892                     } else if (depth < 0) {
1893                         //unbalanced '<', '>' - not a generic type
1894                         return ParensResult.PARENS;
1895                     }
1896                     break;
1897                 default:
1898                     //this includes EOF
1899                     return defaultResult;
1900             }
1901         }

2287 
2288     private JCExpression bracketsOptCont(JCExpression t, int pos,
2289             List<JCAnnotation> annotations) {
2290         accept(RBRACKET);
2291         t = bracketsOpt(t);
2292         t = toP(F.at(pos).TypeArray(t));
2293         if (annotations.nonEmpty()) {
2294             t = toP(F.at(pos).AnnotatedType(annotations, t));
2295         }
2296         return t;
2297     }
2298 
2299     /** BracketsSuffixExpr = "." CLASS
2300      *  BracketsSuffixType =
2301      */
2302     JCExpression bracketsSuffix(JCExpression t) {
2303         if ((mode & EXPR) != 0 && token.kind == DOT) {
2304             selectExprMode();
2305             int pos = token.pos;
2306             nextToken();
2307             TokenKind selector = accept2(CLASS, DEFAULT);
2308             if (token.pos == endPosTable.errorEndPos) {
2309                 // error recovery
2310                 Name name;
2311                 if (LAX_IDENTIFIER.test(token.kind)) {
2312                     name = token.name();
2313                     nextToken();
2314                 } else {
2315                     name = names.error;
2316                 }
2317                 t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name))));
2318             } else {
2319                 Tag tag = t.getTag();
2320                 // Type annotations are illegal on class literals. Annotated non array class literals
2321                 // are complained about directly in term3(), Here check for type annotations on dimensions
2322                 // taking care to handle some interior dimension(s) being annotated.
2323                 if ((tag == TYPEARRAY && TreeInfo.containsTypeAnnotation(t)) || tag == ANNOTATED_TYPE)
2324                     syntaxError(token.pos, Errors.NoAnnotationsOnDotClass);
2325                 if (selector == CLASS) {
2326                     t = toP(F.at(pos).Select(t, names._class));
2327                 } else {
2328                     t = toP(F.at(pos).DefaultValue(t));
2329                 }
2330             }
2331         } else if ((mode & TYPE) != 0) {
2332             if (token.kind != COLCOL) {
2333                 selectTypeMode();
2334             }
2335         } else if (token.kind != COLCOL) {
2336             syntaxError(token.pos, Errors.DotClassExpected);
2337         }
2338         return t;
2339     }
2340 
2341     /**
2342      * MemberReferenceSuffix = "::" [TypeArguments] Ident
2343      *                       | "::" [TypeArguments] "new"
2344      */
2345     JCExpression memberReferenceSuffix(JCExpression t) {
2346         int pos1 = token.pos;
2347         accept(COLCOL);
2348         return memberReferenceSuffix(pos1, t);
2349     }

2354         List<JCExpression> typeArgs = null;
2355         if (token.kind == LT) {
2356             typeArgs = typeArguments(false);
2357         }
2358         Name refName;
2359         ReferenceMode refMode;
2360         if (token.kind == NEW) {
2361             refMode = ReferenceMode.NEW;
2362             refName = names.init;
2363             nextToken();
2364         } else {
2365             refMode = ReferenceMode.INVOKE;
2366             refName = ident();
2367         }
2368         return toP(F.at(t.getStartPosition()).Reference(refMode, refName, t, typeArgs));
2369     }
2370 
2371     /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
2372      */
2373     JCExpression creator(int newpos, List<JCExpression> typeArgs) {
2374         final JCModifiers mods = modifiersOpt();
2375         List<JCAnnotation> newAnnotations = mods.annotations;
2376         if (!newAnnotations.isEmpty()) {
2377             checkSourceLevel(newAnnotations.head.pos, Feature.TYPE_ANNOTATIONS);
2378         }
2379         switch (token.kind) {
2380         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
2381         case DOUBLE: case BOOLEAN:
2382             if (mods.flags != 0) {
2383                 long badModifiers = (mods.flags & Flags.PRIMITIVE_CLASS) != 0 ? mods.flags & ~(Flags.FINAL | Flags.REFERENCE_FAVORING) : mods.flags;
2384                 log.error(token.pos, Errors.ModNotAllowedHere(asFlagSet(badModifiers)));
2385             }
2386             if (typeArgs == null) {
2387                 if (newAnnotations.isEmpty()) {
2388                     return arrayCreatorRest(newpos, basicType());
2389                 } else {
2390                     return arrayCreatorRest(newpos, toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, basicType())));
2391                 }
2392             }
2393             break;
2394         default:
2395         }
2396         JCExpression t = qualident(true);
2397 
2398         int oldmode = mode;
2399         selectTypeMode();
2400         boolean diamondFound = false;
2401         int lastTypeargsPos = -1;
2402         if (token.kind == LT) {
2403             lastTypeargsPos = token.pos;
2404             t = typeArguments(t, true);
2405             diamondFound = (mode & DIAMOND) != 0;

2434             JCExpression e = arrayCreatorRest(newpos, t);
2435             if (diamondFound) {
2436                 reportSyntaxError(lastTypeargsPos, Errors.CannotCreateArrayWithDiamond);
2437                 return toP(F.at(newpos).Erroneous(List.of(e)));
2438             }
2439             else if (typeArgs != null) {
2440                 int pos = newpos;
2441                 if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) {
2442                     // note: this should always happen but we should
2443                     // not rely on this as the parser is continuously
2444                     // modified to improve error recovery.
2445                     pos = typeArgs.head.pos;
2446                 }
2447                 setErrorEndPos(S.prevToken().endPos);
2448                 JCErroneous err = F.at(pos).Erroneous(typeArgs.prepend(e));
2449                 reportSyntaxError(err, Errors.CannotCreateArrayWithTypeArguments);
2450                 return toP(err);
2451             }
2452             return e;
2453         } else if (token.kind == LPAREN) {
2454             long badModifiers = mods.flags & ~(Flags.PRIMITIVE_CLASS | Flags.FINAL | Flags.REFERENCE_FAVORING);
2455             if (badModifiers != 0)
2456                 log.error(token.pos, Errors.ModNotAllowedHere(asFlagSet(badModifiers)));
2457             // handle type annotations for instantiations and anonymous classes
2458             if (newAnnotations.nonEmpty()) {
2459                 t = insertAnnotationsToMostInner(t, newAnnotations, false);
2460             }
2461             JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t, mods.flags);
2462             if ((newClass.def == null) && (mods.flags != 0)) {
2463                 badModifiers = (mods.flags & Flags.PRIMITIVE_CLASS) != 0 ? mods.flags & ~(Flags.FINAL | Flags.REFERENCE_FAVORING) : mods.flags;
2464                 log.error(newClass.pos, Errors.ModNotAllowedHere(asFlagSet(badModifiers)));
2465             }
2466             return newClass;
2467         } else {
2468             setErrorEndPos(token.pos);
2469             reportSyntaxError(token.pos, Errors.Expected2(LPAREN, LBRACKET));
2470             t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.nil(), null));
2471             return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
2472         }
2473     }
2474 
2475     /** InnerCreator = [Annotations] Ident [TypeArguments] ClassCreatorRest
2476      */
2477     JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
2478         List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
2479 
2480         JCExpression t = toP(F.at(token.pos).Ident(ident()));
2481 
2482         if (newAnnotations.nonEmpty()) {
2483             t = toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, t));
2484         }
2485 
2486         if (token.kind == LT) {
2487             int oldmode = mode;
2488             t = typeArguments(t, true);
2489             mode = oldmode;
2490         }
2491         return classCreatorRest(newpos, encl, typeArgs, t, 0);
2492     }
2493 
2494     /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
2495      *                         | Expression "]" {[Annotations]  "[" Expression "]"} BracketsOpt )
2496      */
2497     JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
2498         List<JCAnnotation> annos = typeAnnotationsOpt();
2499 
2500         accept(LBRACKET);
2501         if (token.kind == RBRACKET) {
2502             accept(RBRACKET);
2503             elemtype = bracketsOpt(elemtype, annos);
2504             if (token.kind == LBRACE) {
2505                 JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
2506                 if (annos.nonEmpty()) {
2507                     // when an array initializer is present then
2508                     // the parsed annotations should target the
2509                     // new array tree
2510                     // bracketsOpt inserts the annotation in
2511                     // elemtype, and it needs to be corrected

2549             if (token.kind == LBRACE) {
2550                 elems = arrayInitializerElements(newpos, elemtype);
2551             }
2552 
2553             JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), elems));
2554             na.dimAnnotations = dimAnnotations.toList();
2555 
2556             if (elems != null) {
2557                 return syntaxError(errpos, List.of(na), Errors.IllegalArrayCreationBothDimensionAndInitialization);
2558             }
2559 
2560             return na;
2561         }
2562     }
2563 
2564     /** ClassCreatorRest = Arguments [ClassBody]
2565      */
2566     JCNewClass classCreatorRest(int newpos,
2567                                   JCExpression encl,
2568                                   List<JCExpression> typeArgs,
2569                                   JCExpression t,
2570                                   long flags)
2571     {
2572         List<JCExpression> args = arguments();
2573         JCClassDecl body = null;
2574         if (token.kind == LBRACE) {
2575             int pos = token.pos;
2576             List<JCTree> defs = classInterfaceOrRecordBody(names.empty, false, false);
2577             JCModifiers mods = F.at(Position.NOPOS).Modifiers(flags);
2578             body = toP(F.at(pos).AnonymousClassDef(mods, defs));
2579         }
2580         JCNewClass newClass = toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
2581         return newClass;
2582     }
2583 
2584     /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
2585      */
2586     JCExpression arrayInitializer(int newpos, JCExpression t) {
2587         List<JCExpression> elems = arrayInitializerElements(newpos, t);
2588         return toP(F.at(newpos).NewArray(t, List.nil(), elems));
2589     }
2590 
2591     List<JCExpression> arrayInitializerElements(int newpos, JCExpression t) {
2592         accept(LBRACE);
2593         ListBuffer<JCExpression> elems = new ListBuffer<>();
2594         if (token.kind == COMMA) {
2595             nextToken();
2596         } else if (token.kind != RBRACE) {
2597             elems.append(variableInitializer());
2598             while (token.kind == COMMA) {
2599                 nextToken();
2600                 if (token.kind == RBRACE) break;
2601                 elems.append(variableInitializer());

2794                     accept(SEMI);
2795                     return List.of(toP(F.at(pos).Yield(t)));
2796                 }
2797 
2798                 //else intentional fall-through
2799             } else {
2800                 if (isNonSealedClassStart(true)) {
2801                     log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2802                     nextToken();
2803                     nextToken();
2804                     nextToken();
2805                     return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.comment(CommentStyle.JAVADOC)));
2806                 } else if (isSealedClassStart(true)) {
2807                     checkSourceLevel(Feature.SEALED_CLASSES);
2808                     log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2809                     nextToken();
2810                     return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.comment(CommentStyle.JAVADOC)));
2811                 }
2812             }
2813         }
2814         if (isPrimitiveModifier()) {
2815             dc = token.comment(CommentStyle.JAVADOC);
2816             return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
2817         }
2818         if (isRecordStart() && allowRecords) {
2819             dc = token.comment(CommentStyle.JAVADOC);
2820             return List.of(recordDeclaration(F.at(pos).Modifiers(0), dc));
2821         } else {
2822             Token prevToken = token;
2823             JCExpression t = term(EXPR | TYPE);
2824             if (token.kind == COLON && t.hasTag(IDENT)) {
2825                 nextToken();
2826                 JCStatement stat = parseStatementAsBlock();
2827                 return List.of(F.at(pos).Labelled(prevToken.name(), stat));
2828             } else if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.test(token.kind)) {
2829                 pos = token.pos;
2830                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2831                 F.at(pos);
2832                 return localVariableDeclarations(mods, t);
2833             } else {
2834                 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
2835                 t = checkExprStat(t);
2836                 accept(SEMI);
2837                 JCExpressionStatement expr = toP(F.at(pos).Exec(t));

3235             nextToken();
3236             pos = token.pos;
3237             JCExpression t = parseExpression();
3238             // This Exec is a "StatementExpression"; it subsumes no terminating token
3239             stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
3240         }
3241         return stats;
3242     }
3243 
3244     /** ForInit = StatementExpression MoreStatementExpressions
3245      *           |  { FINAL | '@' Annotation } Type VariableDeclarators
3246      */
3247     List<JCStatement> forInit() {
3248         ListBuffer<JCStatement> stats = new ListBuffer<>();
3249         int pos = token.pos;
3250         if (token.kind == FINAL || token.kind == MONKEYS_AT) {
3251             return variableDeclarators(optFinal(0), parseType(true), stats, true).toList();
3252         } else {
3253             JCExpression t = term(EXPR | TYPE);
3254             if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.test(token.kind)) {
3255                 pos = token.pos;
3256                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
3257                 F.at(pos);
3258                 return variableDeclarators(mods, t, stats, true).toList();
3259             } else if ((lastmode & TYPE) != 0 && token.kind == COLON) {
3260                 log.error(DiagnosticFlag.SYNTAX, pos, Errors.BadInitializer("for-loop"));
3261                 return List.of((JCStatement)F.at(pos).VarDef(modifiersOpt(), names.error, t, null));
3262             } else {
3263                 return moreStatementExpressions(pos, t, stats).toList();
3264             }
3265         }
3266     }
3267 
3268     /** ForUpdate = StatementExpression MoreStatementExpressions
3269      */
3270     List<JCExpressionStatement> forUpdate() {
3271         return moreStatementExpressions(token.pos,
3272                                         parseExpression(),
3273                                         new ListBuffer<JCExpressionStatement>()).toList();
3274     }
3275 
3276     /** AnnotationsOpt = { '@' Annotation }
3277      *
3278      * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION

3335             case ABSTRACT    : flag = Flags.ABSTRACT; break;
3336             case NATIVE      : flag = Flags.NATIVE; break;
3337             case VOLATILE    : flag = Flags.VOLATILE; break;
3338             case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
3339             case STRICTFP    : flag = Flags.STRICTFP; break;
3340             case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
3341             case DEFAULT     : checkSourceLevel(Feature.DEFAULT_METHODS); flag = Flags.DEFAULT; break;
3342             case ERROR       : flag = 0; nextToken(); break;
3343             case IDENTIFIER  : {
3344                 if (isNonSealedClassStart(false)) {
3345                     flag = Flags.NON_SEALED;
3346                     nextToken();
3347                     nextToken();
3348                     break;
3349                 }
3350                 if (isSealedClassStart(false)) {
3351                     checkSourceLevel(Feature.SEALED_CLASSES);
3352                     flag = Flags.SEALED;
3353                     break;
3354                 }
3355                 if (isPrimitiveModifier()) {
3356                     flag = Flags.PRIMITIVE_CLASS;
3357                     break;
3358                 }
3359                 break loop;
3360             }
3361             default: break loop;
3362             }
3363             if ((flags & flag) != 0) log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.RepeatedModifier);
3364             lastPos = token.pos;
3365             nextToken();
3366             if (flag == Flags.ANNOTATION) {
3367                 if (token.kind != INTERFACE) {
3368                     JCAnnotation ann = annotation(lastPos, Tag.ANNOTATION);
3369                     // if first modifier is an annotation, set pos to annotation's.
3370                     if (flags == 0 && annotations.isEmpty())
3371                         pos = ann.pos;
3372                     final Name name = TreeInfo.name(ann.annotationType);
3373                     if (name == names.__primitive__ || name == names.java_lang___primitive__) {
3374                         flag = Flags.PRIMITIVE_CLASS;
3375                     } else {
3376                         annotations.append(ann);
3377                         flag = 0;
3378                     }
3379                 }
3380             }
3381             flags |= flag;
3382         }
3383         switch (token.kind) {
3384         case ENUM: flags |= Flags.ENUM; break;
3385         case INTERFACE: flags |= Flags.INTERFACE; break;
3386         default: break;
3387         }
3388 
3389         /* A modifiers tree with no modifier tokens or annotations
3390          * has no text position. */
3391         if ((flags & (Flags.ModifierFlags | Flags.ANNOTATION)) == 0 && annotations.isEmpty())
3392             pos = Position.NOPOS;
3393 
3394         // Force primitive classes to be automatically final.
3395         if ((flags & (Flags.PRIMITIVE_CLASS | Flags.ABSTRACT | Flags.INTERFACE | Flags.ENUM)) == Flags.PRIMITIVE_CLASS) {
3396             flags |= Flags.FINAL;
3397         }
3398 
3399         JCModifiers mods = F.at(pos).Modifiers(flags, annotations.toList());
3400         if (pos != Position.NOPOS)
3401             storeEnd(mods, S.prevToken().endPos);
3402         return mods;
3403     }
3404 
3405     /** Annotation              = "@" Qualident [ "(" AnnotationFieldValues ")" ]
3406      *
3407      * @param pos position of "@" token
3408      * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION
3409      */
3410     JCAnnotation annotation(int pos, Tag kind) {
3411         // accept(AT); // AT consumed by caller
3412         if (kind == Tag.TYPE_ANNOTATION) {
3413             checkSourceLevel(Feature.TYPE_ANNOTATIONS);
3414         }
3415         JCTree ident = qualident(false);
3416         List<JCExpression> fieldValues = annotationFieldValuesOpt();
3417         JCAnnotation ann;
3418         if (kind == Tag.ANNOTATION) {

3603             if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) {
3604                 return Source.JDK10;
3605             } else if (shouldWarn) {
3606                 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK10));
3607             }
3608         }
3609         if (name == names.yield) {
3610             if (allowYieldStatement) {
3611                 return Source.JDK14;
3612             } else if (shouldWarn) {
3613                 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK14));
3614             }
3615         }
3616         if (name == names.record) {
3617             if (allowRecords) {
3618                 return Source.JDK14;
3619             } else if (shouldWarn) {
3620                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK14));
3621             }
3622         }
3623         if (name == names.primitive) {
3624             if (allowPrimitiveClasses) {
3625                 return Source.JDK17;
3626             } else if (shouldWarn) {
3627                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK17));
3628             }
3629         }
3630         if (name == names.sealed) {
3631             if (allowSealedTypes) {
3632                 return Source.JDK15;
3633             } else if (shouldWarn) {
3634                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3635             }
3636         }
3637         if (name == names.permits) {
3638             if (allowSealedTypes) {
3639                 return Source.JDK15;
3640             } else if (shouldWarn) {
3641                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3642             }
3643         }
3644         return null;
3645     }
3646 
3647     /** VariableDeclaratorId = Ident BracketsOpt
3648      */
3649     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {

4010                         erroneousTree = syntaxError(pos, errs, Errors.Expected4(CLASS, INTERFACE, ENUM, "record"));
4011                     } else {
4012                         erroneousTree = syntaxError(pos, errs, Errors.Expected3(CLASS, INTERFACE, ENUM));
4013                     }
4014                 }
4015                 return toP(F.Exec(erroneousTree));
4016             }
4017         }
4018     }
4019 
4020     /** ClassDeclaration = CLASS Ident TypeParametersOpt [EXTENDS Type]
4021      *                     [IMPLEMENTS TypeList] ClassBody
4022      *  @param mods    The modifiers starting the class declaration
4023      *  @param dc       The documentation comment for the class, or null.
4024      */
4025     protected JCClassDecl classDeclaration(JCModifiers mods, Comment dc) {
4026         int pos = token.pos;
4027         accept(CLASS);
4028         Name name = typeName();
4029 
4030         if ((mods.flags & Flags.PRIMITIVE_CLASS) != 0) {
4031             if (token.kind == DOT) {
4032                 final Token pastDot = S.token(1);
4033                 if (pastDot.kind == IDENTIFIER && pastDot.name() == names.val) {
4034                     nextToken(); nextToken(); // discard .val
4035                     mods.flags |= Flags.REFERENCE_FAVORING;
4036                 }
4037             }
4038         }
4039 
4040         List<JCTypeParameter> typarams = typeParametersOpt();
4041 
4042         JCExpression extending = null;
4043         if (token.kind == EXTENDS) {
4044             nextToken();
4045             extending = parseType();
4046         }
4047         List<JCExpression> implementing = List.nil();
4048         if (token.kind == IMPLEMENTS) {
4049             nextToken();
4050             implementing = typeList();
4051         }
4052         List<JCExpression> permitting = permitsClause(mods, "class");
4053         List<JCTree> defs = classInterfaceOrRecordBody(name, false, false);
4054         JCClassDecl result = toP(F.at(pos).ClassDef(
4055             mods, name, typarams, extending, implementing, permitting, defs));
4056         attach(result, dc);
4057         return result;
4058     }
4059 
4060     protected JCClassDecl recordDeclaration(JCModifiers mods, Comment dc) {
4061         int pos = token.pos;
4062         nextToken();
4063         mods.flags |= Flags.RECORD;
4064         Name name = typeName();
4065         if ((mods.flags & Flags.PRIMITIVE_CLASS) != 0) {
4066             if (token.kind == DOT) {
4067                 final Token pastDot = S.token(1);
4068                 if (pastDot.kind == IDENTIFIER && pastDot.name() == names.val) {
4069                     nextToken(); nextToken(); // discard .val
4070                     mods.flags |= Flags.REFERENCE_FAVORING;
4071                 }
4072             }
4073         }
4074 
4075         List<JCTypeParameter> typarams = typeParametersOpt();
4076 
4077         List<JCVariableDecl> headerFields = formalParameters(false, true);
4078 
4079         List<JCExpression> implementing = List.nil();
4080         if (token.kind == IMPLEMENTS) {
4081             nextToken();
4082             implementing = typeList();
4083         }
4084         List<JCTree> defs = classInterfaceOrRecordBody(name, false, true);
4085         java.util.List<JCVariableDecl> fields = new ArrayList<>();
4086         for (JCVariableDecl field : headerFields) {
4087             fields.add(field);
4088         }
4089         for (JCTree def : defs) {
4090             if (def.hasTag(METHODDEF)) {
4091                 JCMethodDecl methDef = (JCMethodDecl) def;
4092                 if (methDef.name == names.init && methDef.params.isEmpty() && (methDef.mods.flags & Flags.COMPACT_RECORD_CONSTRUCTOR) != 0) {
4093                     ListBuffer<JCVariableDecl> tmpParams = new ListBuffer<>();

4489                         if (isVoid || typarams.nonEmpty()) {
4490                             JCMethodDecl m =
4491                                     toP(F.at(pos).MethodDef(mods, name, type, typarams,
4492                                                             List.nil(), List.nil(), null, null));
4493                             attach(m, dc);
4494                             err = List.of(m);
4495                         } else {
4496                             err = List.nil();
4497                         }
4498                         return List.of(syntaxError(token.pos, err, Errors.Expected(LPAREN)));
4499                     }
4500                 }
4501             }
4502         }
4503     }
4504 
4505     protected boolean isRecordStart() {
4506         if (token.kind == IDENTIFIER && token.name() == names.record &&
4507             (peekToken(TokenKind.IDENTIFIER, TokenKind.LPAREN) ||
4508              peekToken(TokenKind.IDENTIFIER, TokenKind.EOF) ||
4509              peekToken(TokenKind.IDENTIFIER, TokenKind.DOT) ||
4510              peekToken(TokenKind.IDENTIFIER, TokenKind.LT))) {
4511             checkSourceLevel(Feature.RECORDS);
4512             return true;
4513         } else {
4514             return false;
4515         }
4516     }
4517 
4518     protected boolean isNonSealedClassStart(boolean local) {
4519         if (isNonSealedIdentifier(token, 0)) {
4520             Token next = S.token(3);
4521             return allowedAfterSealedOrNonSealed(next, local, true);
4522         }
4523         return false;
4524     }
4525 
4526     protected boolean isNonSealedIdentifier(Token someToken, int lookAheadOffset) {
4527         if (someToken.name() == names.non && peekToken(lookAheadOffset, TokenKind.SUB, TokenKind.IDENTIFIER)) {
4528             Token tokenSub = S.token(lookAheadOffset + 1);
4529             Token tokenSealed = S.token(lookAheadOffset + 2);
4530             if (someToken.endPos == tokenSub.pos &&
4531                     tokenSub.endPos == tokenSealed.pos &&
4532                     tokenSealed.name() == names.sealed) {
4533                 checkSourceLevel(Feature.SEALED_CLASSES);
4534                 return true;
4535             }
4536         }
4537         return false;
4538     }
4539 
4540     protected boolean isPrimitiveModifier() {
4541         if (allowPrimitiveClasses && token.kind == IDENTIFIER && token.name() == names.primitive) {
4542             Token next = S.token(1);
4543             switch (next.kind) {
4544                 case PRIVATE: case PROTECTED: case PUBLIC: case STATIC: case TRANSIENT:
4545                 case FINAL: case ABSTRACT: case NATIVE: case VOLATILE: case SYNCHRONIZED:
4546                 case STRICTFP: case MONKEYS_AT: case DEFAULT: case BYTE: case SHORT:
4547                 case CHAR: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
4548                 case CLASS: case INTERFACE: case ENUM: case IDENTIFIER: // new primitive Comparable() {}
4549                     checkSourceLevel(Feature.PRIMITIVE_CLASSES);
4550                     return true;
4551             }
4552         }
4553         return false;
4554     }
4555 
4556     protected boolean isSealedClassStart(boolean local) {
4557         if (token.name() == names.sealed) {
4558             Token next = S.token(1);
4559             if (allowedAfterSealedOrNonSealed(next, local, false)) {
4560                 checkSourceLevel(Feature.SEALED_CLASSES);
4561                 return true;
4562             }
4563         }
4564         return false;
4565     }
4566 
4567     private boolean allowedAfterSealedOrNonSealed(Token next, boolean local, boolean currentIsNonSealed) {
4568         return local ?
4569             switch (next.kind) {
4570                 case MONKEYS_AT -> {
4571                     Token afterNext = S.token(2);
4572                     yield afterNext.kind != INTERFACE || currentIsNonSealed;
4573                 }
4574                 case ABSTRACT, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4575                 default -> false;
< prev index next >