< 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 

 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;

 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);

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++;

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));

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



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

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












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







3273                 }
3274             }
3275             flags |= flag;
3276         }
3277         switch (token.kind) {
3278         case ENUM: flags |= Flags.ENUM; break;
3279         case INTERFACE: flags |= Flags.INTERFACE; break;
3280         default: break;
3281         }
3282 
3283         /* A modifiers tree with no modifier tokens or annotations
3284          * has no text position. */
3285         if ((flags & (Flags.ModifierFlags | Flags.ANNOTATION)) == 0 && annotations.isEmpty())
3286             pos = Position.NOPOS;
3287 
3288         JCModifiers mods = F.at(pos).Modifiers(flags, annotations.toList());
3289         if (pos != Position.NOPOS)
3290             storeEnd(mods, S.prevToken().endPos);
3291         return mods;
3292     }

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





















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

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














































































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

 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.allowYieldStatement = Feature.SWITCH_EXPRESSION.allowedInSource(source);
 192         this.allowRecords = Feature.RECORDS.allowedInSource(source);
 193         this.allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);
 194         this.allowPrimitiveClasses = (!preview.isPreview(Feature.PRIMITIVE_CLASSES) || preview.isEnabled()) &&
 195                 Feature.PRIMITIVE_CLASSES.allowedInSource(source);
 196         this.allowValueClasses = (!preview.isPreview(Feature.VALUE_CLASSES) || preview.isEnabled()) &&
 197                 Feature.VALUE_CLASSES.allowedInSource(source);
 198     }
 199 
 200     protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) {
 201         return  keepEndPositions
 202                 ? new SimpleEndPosTable(this)
 203                 : new EmptyEndPosTable(this);
 204     }
 205 
 206     protected DocCommentTable newDocCommentTable(boolean keepDocComments, ParserFactory fac) {
 207         return keepDocComments ? new LazyDocCommentTable(fac) : null;
 208     }
 209 
 210     /** Switch: should we fold strings?
 211      */
 212     boolean allowStringFolding;
 213 
 214     /** Switch: should we keep docComments?
 215      */
 216     boolean keepDocComments;
 217 
 218     /** Switch: should we keep line table?
 219      */
 220     boolean keepLineMap;
 221 
 222     /** Switch: is "this" allowed as an identifier?
 223      * This is needed to parse receiver types.
 224      */
 225     boolean allowThisIdent;
 226 
 227     /** Switch: is yield statement allowed in this source level?
 228      */
 229     boolean allowYieldStatement;
 230 
 231     /** Switch: are records allowed in this source level?
 232      */
 233     boolean allowRecords;
 234 
 235     /** Switch: are primitive classes allowed in this source level?
 236      */
 237      boolean allowPrimitiveClasses;
 238 
 239     /** Switch: are value classes allowed in this source level?
 240      */
 241     boolean allowValueClasses;
 242 
 243     /** Switch: are sealed types allowed in this source level?
 244      */
 245     boolean allowSealedTypes;
 246 
 247     /** The type of the method receiver, as specified by a first "this" parameter.
 248      */
 249     JCVariableDecl receiverParam;
 250 
 251     /** When terms are parsed, the mode determines which is expected:
 252      *     mode = EXPR        : an expression
 253      *     mode = TYPE        : a type
 254      *     mode = NOPARAMS    : no parameters allowed for type
 255      *     mode = TYPEARG     : type argument
 256      *     mode |= NOLAMBDA   : lambdas are not allowed
 257      */
 258     protected static final int EXPR = 0x1;
 259     protected static final int TYPE = 0x2;
 260     protected static final int NOPARAMS = 0x4;
 261     protected static final int TYPEARG = 0x8;
 262     protected static final int DIAMOND = 0x10;

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

1354                         break loop;
1355                     case LPAREN:
1356                         if ((mode & EXPR) != 0) {
1357                             selectExprMode();
1358                             t = arguments(typeArgs, t);
1359                             if (!annos.isEmpty()) t = illegal(annos.head.pos);
1360                             typeArgs = null;
1361                         }
1362                         break loop;
1363                     case DOT:
1364                         nextToken();
1365                         if (token.kind == TokenKind.IDENTIFIER && typeArgs != null) {
1366                             return illegal();
1367                         }
1368                         int oldmode = mode;
1369                         mode &= ~NOPARAMS;
1370                         typeArgs = typeArgumentsOpt(EXPR);
1371                         mode = oldmode;
1372                         if ((mode & EXPR) != 0) {
1373                             switch (token.kind) {
1374                             case DEFAULT:
1375                                 if (typeArgs != null) return illegal();
1376                                 selectExprMode();
1377                                 t = to(F.at(pos).DefaultValue(t));
1378                                 nextToken();
1379                                 break loop;
1380                             case CLASS:
1381                                 if (typeArgs != null) return illegal();
1382                                 selectExprMode();
1383                                 t = to(F.at(pos).Select(t, names._class));
1384                                 nextToken();
1385                                 break loop;
1386                             case THIS:
1387                                 if (typeArgs != null) return illegal();
1388                                 selectExprMode();
1389                                 t = to(F.at(pos).Select(t, names._this));
1390                                 nextToken();
1391                                 break loop;
1392                             case SUPER:
1393                                 selectExprMode();
1394                                 t = to(F.at(pos).Select(t, names._super));
1395                                 t = superSuffix(typeArgs, t);
1396                                 typeArgs = null;
1397                                 break loop;
1398                             case NEW:
1399                                 if (typeArgs != null) return illegal();

1417                             token.kind == MONKEYS_AT) {
1418                             //error recovery, case like:
1419                             //int i = expr.<missing-ident>
1420                             //@Deprecated
1421                             if (typeArgs != null) illegal();
1422                             return toP(t);
1423                         }
1424                         if (tyannos != null && tyannos.nonEmpty()) {
1425                             t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
1426                         }
1427                         break;
1428                     case ELLIPSIS:
1429                         if (this.permitTypeAnnotationsPushBack) {
1430                             this.typeAnnotationsPushedBack = annos;
1431                         } else if (annos.nonEmpty()) {
1432                             // Don't return here -- error recovery attempt
1433                             illegal(annos.head.pos);
1434                         }
1435                         break loop;
1436                     case LT:
1437                         if ((mode & TYPE) == 0 && isParameterizedTypePrefix()) {
1438                             //this is either an unbound method reference whose qualifier
1439                             //is a generic type i.e. A<S>::m or a default value creation of
1440                             //the form ValueType<S>.default
1441                             int pos1 = token.pos;
1442                             accept(LT);
1443                             ListBuffer<JCExpression> args = new ListBuffer<>();
1444                             args.append(typeArgument());
1445                             while (token.kind == COMMA) {
1446                                 nextToken();
1447                                 args.append(typeArgument());
1448                             }
1449                             accept(GT);
1450                             t = toP(F.at(pos1).TypeApply(t, args.toList()));
1451                             while (token.kind == DOT) {
1452                                 nextToken();
1453                                 if (token.kind == DEFAULT) {
1454                                     t =  toP(F.at(token.pos).DefaultValue(t));
1455                                     nextToken();
1456                                     selectExprMode();
1457                                     return term3Rest(t, typeArgs);
1458                                 }
1459                                 selectTypeMode();
1460                                 t = toP(F.at(token.pos).Select(t, ident()));
1461                                 t = typeArgumentsOpt(t);
1462                             }
1463                             t = bracketsOpt(t);
1464                             if (token.kind != COLCOL) {
1465                                 //method reference expected here
1466                                 t = illegal();
1467                             }
1468                             selectExprMode();
1469                             return term3Rest(t, typeArgs);
1470                         }
1471                         break loop;
1472                     default:
1473                         break loop;
1474                     }
1475                 }
1476             }
1477             if (typeArgs != null) illegal();
1478             t = typeArgumentsOpt(t);

1605                         }
1606                         return t;
1607                     }
1608                     mode = oldmode;
1609                 }
1610                 if ((mode & EXPR) != 0) {
1611                     selectExprMode();
1612                     JCExpression t1 = term();
1613                     t = to(F.at(pos1).Indexed(t, t1));
1614                 }
1615                 accept(RBRACKET);
1616             } else if (token.kind == DOT) {
1617                 nextToken();
1618                 typeArgs = typeArgumentsOpt(EXPR);
1619                 if (token.kind == SUPER && (mode & EXPR) != 0) {
1620                     selectExprMode();
1621                     t = to(F.at(pos1).Select(t, names._super));
1622                     nextToken();
1623                     t = arguments(typeArgs, t);
1624                     typeArgs = null;
1625                 } else if ((token.kind == NEW) && (mode & EXPR) != 0) {
1626                     if (typeArgs != null) return illegal();
1627                     selectExprMode();
1628                     int pos2 = token.pos;
1629                     nextToken();
1630                     if (token.kind == LT) typeArgs = typeArguments(false);
1631                     t = innerCreator(pos2, typeArgs, t);
1632                     typeArgs = null;
1633                 } else {
1634                     List<JCAnnotation> tyannos = null;
1635                     if ((mode & TYPE) != 0 && token.kind == MONKEYS_AT) {
1636                         // is the mode check needed?
1637                         tyannos = typeAnnotationsOpt();
1638                     }
1639                     t = toP(F.at(pos1).Select(t, ident(true)));
1640                     if (token.pos <= endPosTable.errorEndPos &&
1641                         token.kind == MONKEYS_AT) {
1642                         //error recovery, case like:
1643                         //int i = expr.<missing-ident>
1644                         //@Deprecated
1645                         break;

1659                 if (!annos.isEmpty()) {
1660                     if (permitTypeAnnotationsPushBack)
1661                         typeAnnotationsPushedBack = annos;
1662                     else
1663                         return illegal(annos.head.pos);
1664                 }
1665                 break;
1666             }
1667         }
1668         while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && (mode & EXPR) != 0) {
1669             selectExprMode();
1670             t = to(F.at(token.pos).Unary(
1671                   token.kind == PLUSPLUS ? POSTINC : POSTDEC, t));
1672             nextToken();
1673         }
1674         return toP(t);
1675     }
1676 
1677     /**
1678      * If we see an identifier followed by a '&lt;' it could be an unbound
1679      * method reference or a default value creation that uses a parameterized type
1680      * or a binary expression. To disambiguate, look for a
1681      * matching '&gt;' and see if the subsequent terminal is either '.' or '::'.
1682      */
1683     @SuppressWarnings("fallthrough")
1684     boolean isParameterizedTypePrefix() {
1685         int pos = 0, depth = 0;
1686         outer: for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
1687             switch (t.kind) {
1688                 case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
1689                 case DOT: case RBRACKET: case LBRACKET: case COMMA:
1690                 case BYTE: case SHORT: case INT: case LONG: case FLOAT:
1691                 case DOUBLE: case BOOLEAN: case CHAR:
1692                 case MONKEYS_AT:
1693                     break;
1694 
1695                 case LPAREN:
1696                     // skip annotation values
1697                     int nesting = 0;
1698                     for (; ; pos++) {
1699                         TokenKind tk2 = S.token(pos).kind;
1700                         switch (tk2) {
1701                             case EOF:
1702                                 return false;
1703                             case LPAREN:
1704                                 nesting++;

2264 
2265     private JCExpression bracketsOptCont(JCExpression t, int pos,
2266             List<JCAnnotation> annotations) {
2267         accept(RBRACKET);
2268         t = bracketsOpt(t);
2269         t = toP(F.at(pos).TypeArray(t));
2270         if (annotations.nonEmpty()) {
2271             t = toP(F.at(pos).AnnotatedType(annotations, t));
2272         }
2273         return t;
2274     }
2275 
2276     /** BracketsSuffixExpr = "." CLASS
2277      *  BracketsSuffixType =
2278      */
2279     JCExpression bracketsSuffix(JCExpression t) {
2280         if ((mode & EXPR) != 0 && token.kind == DOT) {
2281             selectExprMode();
2282             int pos = token.pos;
2283             nextToken();
2284             TokenKind selector = accept2(CLASS, DEFAULT);
2285             if (token.pos == endPosTable.errorEndPos) {
2286                 // error recovery
2287                 Name name;
2288                 if (LAX_IDENTIFIER.test(token.kind)) {
2289                     name = token.name();
2290                     nextToken();
2291                 } else {
2292                     name = names.error;
2293                 }
2294                 t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name))));
2295             } else {
2296                 Tag tag = t.getTag();
2297                 // Type annotations are illegal on class literals. Annotated non array class literals
2298                 // are complained about directly in term3(), Here check for type annotations on dimensions
2299                 // taking care to handle some interior dimension(s) being annotated.
2300                 if ((tag == TYPEARRAY && TreeInfo.containsTypeAnnotation(t)) || tag == ANNOTATED_TYPE)
2301                     syntaxError(token.pos, Errors.NoAnnotationsOnDotClass);
2302                 if (selector == CLASS) {
2303                     t = toP(F.at(pos).Select(t, names._class));
2304                 } else {
2305                     t = toP(F.at(pos).DefaultValue(t));
2306                 }
2307             }
2308         } else if ((mode & TYPE) != 0) {
2309             if (token.kind != COLCOL) {
2310                 selectTypeMode();
2311             }
2312         } else if (token.kind != COLCOL) {
2313             syntaxError(token.pos, Errors.DotClassExpected);
2314         }
2315         return t;
2316     }
2317 
2318     /**
2319      * MemberReferenceSuffix = "::" [TypeArguments] Ident
2320      *                       | "::" [TypeArguments] "new"
2321      */
2322     JCExpression memberReferenceSuffix(JCExpression t) {
2323         int pos1 = token.pos;
2324         accept(COLCOL);
2325         return memberReferenceSuffix(pos1, t);
2326     }

2331         List<JCExpression> typeArgs = null;
2332         if (token.kind == LT) {
2333             typeArgs = typeArguments(false);
2334         }
2335         Name refName;
2336         ReferenceMode refMode;
2337         if (token.kind == NEW) {
2338             refMode = ReferenceMode.NEW;
2339             refName = names.init;
2340             nextToken();
2341         } else {
2342             refMode = ReferenceMode.INVOKE;
2343             refName = ident();
2344         }
2345         return toP(F.at(t.getStartPosition()).Reference(refMode, refName, t, typeArgs));
2346     }
2347 
2348     /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
2349      */
2350     JCExpression creator(int newpos, List<JCExpression> typeArgs) {
2351         final JCModifiers mods = modifiersOpt();
2352         List<JCAnnotation> newAnnotations = mods.annotations;
2353         if (!newAnnotations.isEmpty()) {
2354             checkSourceLevel(newAnnotations.head.pos, Feature.TYPE_ANNOTATIONS);
2355         }
2356         switch (token.kind) {
2357         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
2358         case DOUBLE: case BOOLEAN:
2359             if (mods.flags != 0) {
2360                 log.error(token.pos, Errors.ModNotAllowedHere(asFlagSet(mods.flags)));
2361             }
2362             if (typeArgs == null) {
2363                 if (newAnnotations.isEmpty()) {
2364                     return arrayCreatorRest(newpos, basicType());
2365                 } else {
2366                     return arrayCreatorRest(newpos, toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, basicType())));
2367                 }
2368             }
2369             break;
2370         default:
2371         }
2372         JCExpression t = qualident(true);
2373 
2374         int oldmode = mode;
2375         selectTypeMode();
2376         boolean diamondFound = false;
2377         int lastTypeargsPos = -1;
2378         if (token.kind == LT) {
2379             lastTypeargsPos = token.pos;
2380             t = typeArguments(t, true);
2381             diamondFound = (mode & DIAMOND) != 0;

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

2524             if (token.kind == LBRACE) {
2525                 elems = arrayInitializerElements(newpos, elemtype);
2526             }
2527 
2528             JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), elems));
2529             na.dimAnnotations = dimAnnotations.toList();
2530 
2531             if (elems != null) {
2532                 return syntaxError(errpos, List.of(na), Errors.IllegalArrayCreationBothDimensionAndInitialization);
2533             }
2534 
2535             return na;
2536         }
2537     }
2538 
2539     /** ClassCreatorRest = Arguments [ClassBody]
2540      */
2541     JCNewClass classCreatorRest(int newpos,
2542                                   JCExpression encl,
2543                                   List<JCExpression> typeArgs,
2544                                   JCExpression t,
2545                                   long flags)
2546     {
2547         List<JCExpression> args = arguments();
2548         JCClassDecl body = null;
2549         if (token.kind == LBRACE) {
2550             int pos = token.pos;
2551             List<JCTree> defs = classInterfaceOrRecordBody(names.empty, false, false);
2552             JCModifiers mods = F.at(Position.NOPOS).Modifiers(flags);
2553             body = toP(F.at(pos).AnonymousClassDef(mods, defs));
2554         }
2555         JCNewClass newClass = toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
2556         return newClass;
2557     }
2558 
2559     /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
2560      */
2561     JCExpression arrayInitializer(int newpos, JCExpression t) {
2562         List<JCExpression> elems = arrayInitializerElements(newpos, t);
2563         return toP(F.at(newpos).NewArray(t, List.nil(), elems));
2564     }
2565 
2566     List<JCExpression> arrayInitializerElements(int newpos, JCExpression t) {
2567         accept(LBRACE);
2568         ListBuffer<JCExpression> elems = new ListBuffer<>();
2569         if (token.kind == COMMA) {
2570             nextToken();
2571         } else if (token.kind != RBRACE) {
2572             elems.append(variableInitializer());
2573             while (token.kind == COMMA) {
2574                 nextToken();
2575                 if (token.kind == RBRACE) break;
2576                 elems.append(variableInitializer());

2769                     accept(SEMI);
2770                     return List.of(toP(F.at(pos).Yield(t)));
2771                 }
2772 
2773                 //else intentional fall-through
2774             } else {
2775                 if (isNonSealedClassStart(true)) {
2776                     log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2777                     nextToken();
2778                     nextToken();
2779                     nextToken();
2780                     return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.comment(CommentStyle.JAVADOC)));
2781                 } else if (isSealedClassStart(true)) {
2782                     checkSourceLevel(Feature.SEALED_CLASSES);
2783                     log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2784                     nextToken();
2785                     return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.comment(CommentStyle.JAVADOC)));
2786                 }
2787             }
2788         }
2789         if ((isPrimitiveModifier() && allowPrimitiveClasses) || (isValueModifier() || isIdentityModifier()) && allowValueClasses) {
2790             dc = token.comment(CommentStyle.JAVADOC);
2791             return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
2792         }
2793         if (isRecordStart() && allowRecords) {
2794             dc = token.comment(CommentStyle.JAVADOC);
2795             return List.of(recordDeclaration(F.at(pos).Modifiers(0), dc));
2796         } else {
2797             Token prevToken = token;
2798             JCExpression t = term(EXPR | TYPE);
2799             if (token.kind == COLON && t.hasTag(IDENT)) {
2800                 nextToken();
2801                 JCStatement stat = parseStatementAsBlock();
2802                 return List.of(F.at(pos).Labelled(prevToken.name(), stat));
2803             } else if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.test(token.kind)) {
2804                 pos = token.pos;
2805                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2806                 F.at(pos);
2807                 return localVariableDeclarations(mods, t);
2808             } else {
2809                 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
2810                 t = checkExprStat(t);
2811                 accept(SEMI);
2812                 JCExpressionStatement expr = toP(F.at(pos).Exec(t));

3209             nextToken();
3210             pos = token.pos;
3211             JCExpression t = parseExpression();
3212             // This Exec is a "StatementExpression"; it subsumes no terminating token
3213             stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
3214         }
3215         return stats;
3216     }
3217 
3218     /** ForInit = StatementExpression MoreStatementExpressions
3219      *           |  { FINAL | '@' Annotation } Type VariableDeclarators
3220      */
3221     List<JCStatement> forInit() {
3222         ListBuffer<JCStatement> stats = new ListBuffer<>();
3223         int pos = token.pos;
3224         if (token.kind == FINAL || token.kind == MONKEYS_AT) {
3225             return variableDeclarators(optFinal(0), parseType(true), stats, true).toList();
3226         } else {
3227             JCExpression t = term(EXPR | TYPE);
3228             if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.test(token.kind)) {
3229                 pos = token.pos;
3230                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
3231                 F.at(pos);
3232                 return variableDeclarators(mods, t, stats, true).toList();
3233             } else if ((lastmode & TYPE) != 0 && token.kind == COLON) {
3234                 log.error(DiagnosticFlag.SYNTAX, pos, Errors.BadInitializer("for-loop"));
3235                 return List.of((JCStatement)F.at(pos).VarDef(modifiersOpt(), names.error, t, null));
3236             } else {
3237                 return moreStatementExpressions(pos, t, stats).toList();
3238             }
3239         }
3240     }
3241 
3242     /** ForUpdate = StatementExpression MoreStatementExpressions
3243      */
3244     List<JCExpressionStatement> forUpdate() {
3245         return moreStatementExpressions(token.pos,
3246                                         parseExpression(),
3247                                         new ListBuffer<JCExpressionStatement>()).toList();
3248     }
3249 
3250     /** AnnotationsOpt = { '@' Annotation }
3251      *
3252      * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION

3309             case ABSTRACT    : flag = Flags.ABSTRACT; break;
3310             case NATIVE      : flag = Flags.NATIVE; break;
3311             case VOLATILE    : flag = Flags.VOLATILE; break;
3312             case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
3313             case STRICTFP    : flag = Flags.STRICTFP; break;
3314             case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
3315             case DEFAULT     : checkSourceLevel(Feature.DEFAULT_METHODS); flag = Flags.DEFAULT; break;
3316             case ERROR       : flag = 0; nextToken(); break;
3317             case IDENTIFIER  : {
3318                 if (isNonSealedClassStart(false)) {
3319                     flag = Flags.NON_SEALED;
3320                     nextToken();
3321                     nextToken();
3322                     break;
3323                 }
3324                 if (isSealedClassStart(false)) {
3325                     checkSourceLevel(Feature.SEALED_CLASSES);
3326                     flag = Flags.SEALED;
3327                     break;
3328                 }
3329                 if (isPrimitiveModifier()) {
3330                     flag = Flags.PRIMITIVE_CLASS;
3331                     break;
3332                 }
3333                 if (isValueModifier()) {
3334                     flag = Flags.VALUE_CLASS;
3335                     break;
3336                 }
3337                 if (isIdentityModifier()) {
3338                     flag = Flags.IDENTITY_TYPE;
3339                     break;
3340                 }
3341                 break loop;
3342             }
3343             default: break loop;
3344             }
3345             if ((flags & flag) != 0) log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.RepeatedModifier);
3346             lastPos = token.pos;
3347             nextToken();
3348             if (flag == Flags.ANNOTATION) {
3349                 if (token.kind != INTERFACE) {
3350                     JCAnnotation ann = annotation(lastPos, Tag.ANNOTATION);
3351                     // if first modifier is an annotation, set pos to annotation's.
3352                     if (flags == 0 && annotations.isEmpty())
3353                         pos = ann.pos;
3354                     final Name name = TreeInfo.name(ann.annotationType);
3355                     if (name == names.__primitive__ || name == names.java_lang___primitive__) {
3356                         flag = Flags.PRIMITIVE_CLASS;
3357                     } else if (name == names.__value__ || name == names.java_lang___value__) {
3358                         flag = Flags.VALUE_CLASS;
3359                     } else {
3360                         annotations.append(ann);
3361                         flag = 0;
3362                     }
3363                 }
3364             }
3365             flags |= flag;
3366         }
3367         switch (token.kind) {
3368         case ENUM: flags |= Flags.ENUM; break;
3369         case INTERFACE: flags |= Flags.INTERFACE; break;
3370         default: break;
3371         }
3372 
3373         /* A modifiers tree with no modifier tokens or annotations
3374          * has no text position. */
3375         if ((flags & (Flags.ModifierFlags | Flags.ANNOTATION)) == 0 && annotations.isEmpty())
3376             pos = Position.NOPOS;
3377 
3378         JCModifiers mods = F.at(pos).Modifiers(flags, annotations.toList());
3379         if (pos != Position.NOPOS)
3380             storeEnd(mods, S.prevToken().endPos);
3381         return mods;
3382     }

3582             if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) {
3583                 return Source.JDK10;
3584             } else if (shouldWarn) {
3585                 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK10));
3586             }
3587         }
3588         if (name == names.yield) {
3589             if (allowYieldStatement) {
3590                 return Source.JDK14;
3591             } else if (shouldWarn) {
3592                 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK14));
3593             }
3594         }
3595         if (name == names.record) {
3596             if (allowRecords) {
3597                 return Source.JDK14;
3598             } else if (shouldWarn) {
3599                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK14));
3600             }
3601         }
3602         if (name == names.primitive) {
3603             if (allowPrimitiveClasses) {
3604                 return Source.JDK18;
3605             } else if (shouldWarn) {
3606                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK18));
3607             }
3608         }
3609         if (name == names.value) {
3610             if (allowValueClasses) {
3611                 return Source.JDK18;
3612             } else if (shouldWarn) {
3613                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK18));
3614             }
3615         }
3616         if (name == names.identity) {
3617             if (allowPrimitiveClasses) {
3618                 return Source.JDK18;
3619             } else if (shouldWarn) {
3620                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK18));
3621             }
3622         }
3623         if (name == names.sealed) {
3624             if (allowSealedTypes) {
3625                 return Source.JDK15;
3626             } else if (shouldWarn) {
3627                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3628             }
3629         }
3630         if (name == names.permits) {
3631             if (allowSealedTypes) {
3632                 return Source.JDK15;
3633             } else if (shouldWarn) {
3634                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3635             }
3636         }
3637         return null;
3638     }
3639 
3640     /** VariableDeclaratorId = Ident BracketsOpt
3641      */
3642     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {

4493             Token next = S.token(3);
4494             return allowedAfterSealedOrNonSealed(next, local, true);
4495         }
4496         return false;
4497     }
4498 
4499     protected boolean isNonSealedIdentifier(Token someToken, int lookAheadOffset) {
4500         if (someToken.name() == names.non && peekToken(lookAheadOffset, TokenKind.SUB, TokenKind.IDENTIFIER)) {
4501             Token tokenSub = S.token(lookAheadOffset + 1);
4502             Token tokenSealed = S.token(lookAheadOffset + 2);
4503             if (someToken.endPos == tokenSub.pos &&
4504                     tokenSub.endPos == tokenSealed.pos &&
4505                     tokenSealed.name() == names.sealed) {
4506                 checkSourceLevel(Feature.SEALED_CLASSES);
4507                 return true;
4508             }
4509         }
4510         return false;
4511     }
4512 
4513     protected boolean isPrimitiveModifier() {
4514         if (token.kind == IDENTIFIER && token.name() == names.primitive) {
4515             boolean isPrimitiveModifier = false;
4516             Token next = S.token(1);
4517             switch (next.kind) {
4518                 case PRIVATE: case PROTECTED: case PUBLIC: case STATIC: case TRANSIENT:
4519                 case FINAL: case ABSTRACT: case NATIVE: case VOLATILE: case SYNCHRONIZED:
4520                 case STRICTFP: case MONKEYS_AT: case DEFAULT: case BYTE: case SHORT:
4521                 case CHAR: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
4522                 case CLASS: case INTERFACE: case ENUM:
4523                     isPrimitiveModifier = true;
4524                     break;
4525                 case IDENTIFIER: // primitive record R || primitive primitive || primitive identity || primitive value || new primitive Comparable() {}
4526                     if (next.name() == names.record || next.name() == names.primitive || next.name() == names.identity
4527                             || next.name() == names.value || (mode & EXPR) != 0)
4528                         isPrimitiveModifier = true;
4529                     break;
4530             }
4531             if (isPrimitiveModifier) {
4532                 checkSourceLevel(Feature.PRIMITIVE_CLASSES);
4533                 return true;
4534             }
4535         }
4536         return false;
4537     }
4538 
4539     protected boolean isValueModifier() {
4540         if (token.kind == IDENTIFIER && token.name() == names.value) {
4541             boolean isValueModifier = false;
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:
4549                     isValueModifier = true;
4550                     break;
4551                 case IDENTIFIER: // value record R || value value || value identity || value primitive || new value Comparable() {} ??
4552                     if (next.name() == names.record || next.name() == names.value || next.name() == names.identity
4553                             || next.name() == names.primitive || (mode & EXPR) != 0)
4554                         isValueModifier = true;
4555                     break;
4556             }
4557             if (isValueModifier) {
4558                 checkSourceLevel(Feature.VALUE_CLASSES);
4559                 return true;
4560             }
4561         }
4562         return false;
4563     }
4564 
4565     protected boolean isIdentityModifier() {
4566         if (token.kind == IDENTIFIER && token.name() == names.identity) {
4567             boolean isIdentityModifier = false;
4568             Token next = S.token(1);
4569             switch (next.kind) {
4570                 case PRIVATE: case PROTECTED: case PUBLIC: case STATIC: case TRANSIENT:
4571                 case FINAL: case ABSTRACT: case NATIVE: case VOLATILE: case SYNCHRONIZED:
4572                 case STRICTFP: case MONKEYS_AT: case DEFAULT: case BYTE: case SHORT:
4573                 case CHAR: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
4574                 case CLASS: case INTERFACE: case ENUM:
4575                     isIdentityModifier = true;
4576                     break;
4577                 case IDENTIFIER: // identity record R || identity primitive || || identity identity || identity value || new identity Comparable() {}
4578                     if (next.name() == names.record || next.name() == names.primitive || next.name() == names.identity
4579                             || next.name() == names.value || (mode & EXPR) != 0)
4580                         isIdentityModifier = true;
4581                     break;
4582             }
4583             if (isIdentityModifier) {
4584                 checkSourceLevel(Feature.PRIMITIVE_CLASSES);
4585                 return true;
4586             }
4587         }
4588         return false;
4589     }
4590 
4591     protected boolean isSealedClassStart(boolean local) {
4592         if (token.name() == names.sealed) {
4593             Token next = S.token(1);
4594             if (allowedAfterSealedOrNonSealed(next, local, false)) {
4595                 checkSourceLevel(Feature.SEALED_CLASSES);
4596                 return true;
4597             }
4598         }
4599         return false;
4600     }
4601 
4602     private boolean allowedAfterSealedOrNonSealed(Token next, boolean local, boolean currentIsNonSealed) {
4603         return local ?
4604             switch (next.kind) {
4605                 case MONKEYS_AT -> {
4606                     Token afterNext = S.token(2);
4607                     yield afterNext.kind != INTERFACE || currentIsNonSealed;
4608                 }
4609                 case ABSTRACT, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4610                 default -> false;
< prev index next >