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

1359                         break loop;
1360                     case LPAREN:
1361                         if ((mode & EXPR) != 0) {
1362                             selectExprMode();
1363                             t = arguments(typeArgs, t);
1364                             if (!annos.isEmpty()) t = illegal(annos.head.pos);
1365                             typeArgs = null;
1366                         }
1367                         break loop;
1368                     case DOT:
1369                         nextToken();
1370                         if (token.kind == TokenKind.IDENTIFIER && typeArgs != null) {
1371                             return illegal();
1372                         }
1373                         int oldmode = mode;
1374                         mode &= ~NOPARAMS;
1375                         typeArgs = typeArgumentsOpt(EXPR);
1376                         mode = oldmode;
1377                         if ((mode & EXPR) != 0) {
1378                             switch (token.kind) {






1379                             case CLASS:
1380                                 if (typeArgs != null) return illegal();
1381                                 selectExprMode();
1382                                 t = to(F.at(pos).Select(t, names._class));
1383                                 nextToken();
1384                                 break loop;
1385                             case THIS:
1386                                 if (typeArgs != null) return illegal();
1387                                 selectExprMode();
1388                                 t = to(F.at(pos).Select(t, names._this));
1389                                 nextToken();
1390                                 break loop;
1391                             case SUPER:
1392                                 selectExprMode();
1393                                 t = to(F.at(pos).Select(t, names._super));
1394                                 t = superSuffix(typeArgs, t);
1395                                 typeArgs = null;
1396                                 break loop;
1397                             case NEW:
1398                                 if (typeArgs != null) return illegal();

1416                             token.kind == MONKEYS_AT) {
1417                             //error recovery, case like:
1418                             //int i = expr.<missing-ident>
1419                             //@Deprecated
1420                             if (typeArgs != null) illegal();
1421                             return toP(t);
1422                         }
1423                         if (tyannos != null && tyannos.nonEmpty()) {
1424                             t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
1425                         }
1426                         break;
1427                     case ELLIPSIS:
1428                         if (this.permitTypeAnnotationsPushBack) {
1429                             this.typeAnnotationsPushedBack = annos;
1430                         } else if (annos.nonEmpty()) {
1431                             // Don't return here -- error recovery attempt
1432                             illegal(annos.head.pos);
1433                         }
1434                         break loop;
1435                     case LT:
1436                         if ((mode & TYPE) == 0 && isUnboundMemberRef()) {
1437                             //this is an unbound method reference whose qualifier
1438                             //is a generic type i.e. A<S>::m

1439                             int pos1 = token.pos;
1440                             accept(LT);
1441                             ListBuffer<JCExpression> args = new ListBuffer<>();
1442                             args.append(typeArgument());
1443                             while (token.kind == COMMA) {
1444                                 nextToken();
1445                                 args.append(typeArgument());
1446                             }
1447                             accept(GT);
1448                             t = toP(F.at(pos1).TypeApply(t, args.toList()));
1449                             while (token.kind == DOT) {
1450                                 nextToken();






1451                                 selectTypeMode();
1452                                 t = toP(F.at(token.pos).Select(t, ident()));
1453                                 t = typeArgumentsOpt(t);
1454                             }
1455                             t = bracketsOpt(t);
1456                             if (token.kind != COLCOL) {
1457                                 //method reference expected here
1458                                 t = illegal();
1459                             }
1460                             selectExprMode();
1461                             return term3Rest(t, typeArgs);
1462                         }
1463                         break loop;
1464                     default:
1465                         break loop;
1466                     }
1467                 }
1468             }
1469             if (typeArgs != null) illegal();
1470             t = typeArgumentsOpt(t);

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

1651                 if (!annos.isEmpty()) {
1652                     if (permitTypeAnnotationsPushBack)
1653                         typeAnnotationsPushedBack = annos;
1654                     else
1655                         return illegal(annos.head.pos);
1656                 }
1657                 break;
1658             }
1659         }
1660         while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && (mode & EXPR) != 0) {
1661             selectExprMode();
1662             t = to(F.at(token.pos).Unary(
1663                   token.kind == PLUSPLUS ? POSTINC : POSTDEC, t));
1664             nextToken();
1665         }
1666         return toP(t);
1667     }
1668 
1669     /**
1670      * If we see an identifier followed by a '&lt;' it could be an unbound
1671      * method reference or a binary expression. To disambiguate, look for a

1672      * matching '&gt;' and see if the subsequent terminal is either '.' or '::'.
1673      */
1674     @SuppressWarnings("fallthrough")
1675     boolean isUnboundMemberRef() {
1676         int pos = 0, depth = 0;
1677         outer: for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
1678             switch (t.kind) {
1679                 case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
1680                 case DOT: case RBRACKET: case LBRACKET: case COMMA:
1681                 case BYTE: case SHORT: case INT: case LONG: case FLOAT:
1682                 case DOUBLE: case BOOLEAN: case CHAR:
1683                 case MONKEYS_AT:
1684                     break;
1685 
1686                 case LPAREN:
1687                     // skip annotation values
1688                     int nesting = 0;
1689                     for (; ; pos++) {
1690                         TokenKind tk2 = S.token(pos).kind;
1691                         switch (tk2) {
1692                             case EOF:
1693                                 return false;
1694                             case LPAREN:
1695                                 nesting++;

2253 
2254     private JCExpression bracketsOptCont(JCExpression t, int pos,
2255             List<JCAnnotation> annotations) {
2256         accept(RBRACKET);
2257         t = bracketsOpt(t);
2258         t = toP(F.at(pos).TypeArray(t));
2259         if (annotations.nonEmpty()) {
2260             t = toP(F.at(pos).AnnotatedType(annotations, t));
2261         }
2262         return t;
2263     }
2264 
2265     /** BracketsSuffixExpr = "." CLASS
2266      *  BracketsSuffixType =
2267      */
2268     JCExpression bracketsSuffix(JCExpression t) {
2269         if ((mode & EXPR) != 0 && token.kind == DOT) {
2270             selectExprMode();
2271             int pos = token.pos;
2272             nextToken();
2273             accept(CLASS);
2274             if (token.pos == endPosTable.errorEndPos) {
2275                 // error recovery
2276                 Name name;
2277                 if (LAX_IDENTIFIER.test(token.kind)) {
2278                     name = token.name();
2279                     nextToken();
2280                 } else {
2281                     name = names.error;
2282                 }
2283                 t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name))));
2284             } else {
2285                 Tag tag = t.getTag();
2286                 // Type annotations are illegal on class literals. Annotated non array class literals
2287                 // are complained about directly in term3(), Here check for type annotations on dimensions
2288                 // taking care to handle some interior dimension(s) being annotated.
2289                 if ((tag == TYPEARRAY && TreeInfo.containsTypeAnnotation(t)) || tag == ANNOTATED_TYPE)
2290                     syntaxError(token.pos, Errors.NoAnnotationsOnDotClass);
2291                 t = toP(F.at(pos).Select(t, names._class));




2292             }
2293         } else if ((mode & TYPE) != 0) {
2294             if (token.kind != COLCOL) {
2295                 selectTypeMode();
2296             }
2297         } else if (token.kind != COLCOL) {
2298             syntaxError(token.pos, Errors.DotClassExpected);
2299         }
2300         return t;
2301     }
2302 
2303     /**
2304      * MemberReferenceSuffix = "::" [TypeArguments] Ident
2305      *                       | "::" [TypeArguments] "new"
2306      */
2307     JCExpression memberReferenceSuffix(JCExpression t) {
2308         int pos1 = token.pos;
2309         accept(COLCOL);
2310         return memberReferenceSuffix(pos1, t);
2311     }

2315         List<JCExpression> typeArgs = null;
2316         if (token.kind == LT) {
2317             typeArgs = typeArguments(false);
2318         }
2319         Name refName;
2320         ReferenceMode refMode;
2321         if (token.kind == NEW) {
2322             refMode = ReferenceMode.NEW;
2323             refName = names.init;
2324             nextToken();
2325         } else {
2326             refMode = ReferenceMode.INVOKE;
2327             refName = ident();
2328         }
2329         return toP(F.at(t.getStartPosition()).Reference(refMode, refName, t, typeArgs));
2330     }
2331 
2332     /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
2333      */
2334     JCExpression creator(int newpos, List<JCExpression> typeArgs) {
2335         List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
2336 
2337         switch (token.kind) {
2338         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
2339         case DOUBLE: case BOOLEAN:



2340             if (typeArgs == null) {
2341                 if (newAnnotations.isEmpty()) {
2342                     return arrayCreatorRest(newpos, basicType());
2343                 } else {
2344                     return arrayCreatorRest(newpos, toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, basicType())));
2345                 }
2346             }
2347             break;
2348         default:
2349         }
2350         JCExpression t = qualident(true);
2351 
2352         int oldmode = mode;
2353         selectTypeMode();
2354         boolean diamondFound = false;
2355         int lastTypeargsPos = -1;
2356         if (token.kind == LT) {
2357             lastTypeargsPos = token.pos;
2358             t = typeArguments(t, true);
2359             diamondFound = (mode & DIAMOND) != 0;

2388             JCExpression e = arrayCreatorRest(newpos, t);
2389             if (diamondFound) {
2390                 reportSyntaxError(lastTypeargsPos, Errors.CannotCreateArrayWithDiamond);
2391                 return toP(F.at(newpos).Erroneous(List.of(e)));
2392             }
2393             else if (typeArgs != null) {
2394                 int pos = newpos;
2395                 if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) {
2396                     // note: this should always happen but we should
2397                     // not rely on this as the parser is continuously
2398                     // modified to improve error recovery.
2399                     pos = typeArgs.head.pos;
2400                 }
2401                 setErrorEndPos(S.prevToken().endPos);
2402                 JCErroneous err = F.at(pos).Erroneous(typeArgs.prepend(e));
2403                 reportSyntaxError(err, Errors.CannotCreateArrayWithTypeArguments);
2404                 return toP(err);
2405             }
2406             return e;
2407         } else if (token.kind == LPAREN) {



2408             // handle type annotations for instantiations and anonymous classes
2409             if (newAnnotations.nonEmpty()) {
2410                 t = insertAnnotationsToMostInner(t, newAnnotations, false);
2411             }
2412             return classCreatorRest(newpos, null, typeArgs, t);




2413         } else {
2414             setErrorEndPos(token.pos);
2415             reportSyntaxError(token.pos, Errors.Expected2(LPAREN, LBRACKET));
2416             t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.nil(), null));
2417             return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
2418         }
2419     }
2420 
2421     /** InnerCreator = [Annotations] Ident [TypeArguments] ClassCreatorRest
2422      */
2423     JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
2424         List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
2425 
2426         JCExpression t = toP(F.at(token.pos).Ident(ident()));
2427 
2428         if (newAnnotations.nonEmpty()) {
2429             t = toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, t));
2430         }
2431 
2432         if (token.kind == LT) {
2433             int oldmode = mode;
2434             t = typeArguments(t, true);
2435             mode = oldmode;
2436         }
2437         return classCreatorRest(newpos, encl, typeArgs, t);
2438     }
2439 
2440     /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
2441      *                         | Expression "]" {[Annotations]  "[" Expression "]"} BracketsOpt )
2442      */
2443     JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
2444         List<JCAnnotation> annos = typeAnnotationsOpt();
2445 
2446         accept(LBRACKET);
2447         if (token.kind == RBRACKET) {
2448             accept(RBRACKET);
2449             elemtype = bracketsOpt(elemtype, annos);
2450             if (token.kind == LBRACE) {
2451                 JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
2452                 if (annos.nonEmpty()) {
2453                     // when an array initializer is present then
2454                     // the parsed annotations should target the
2455                     // new array tree
2456                     // bracketsOpt inserts the annotation in
2457                     // elemtype, and it needs to be corrected

2495             if (token.kind == LBRACE) {
2496                 elems = arrayInitializerElements(newpos, elemtype);
2497             }
2498 
2499             JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), elems));
2500             na.dimAnnotations = dimAnnotations.toList();
2501 
2502             if (elems != null) {
2503                 return syntaxError(errpos, List.of(na), Errors.IllegalArrayCreationBothDimensionAndInitialization);
2504             }
2505 
2506             return na;
2507         }
2508     }
2509 
2510     /** ClassCreatorRest = Arguments [ClassBody]
2511      */
2512     JCNewClass classCreatorRest(int newpos,
2513                                   JCExpression encl,
2514                                   List<JCExpression> typeArgs,
2515                                   JCExpression t)

2516     {
2517         List<JCExpression> args = arguments();
2518         JCClassDecl body = null;
2519         if (token.kind == LBRACE) {
2520             int pos = token.pos;
2521             List<JCTree> defs = classInterfaceOrRecordBody(names.empty, false, false);
2522             JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2523             body = toP(F.at(pos).AnonymousClassDef(mods, defs));
2524         }
2525         return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));

2526     }
2527 
2528     /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
2529      */
2530     JCExpression arrayInitializer(int newpos, JCExpression t) {
2531         List<JCExpression> elems = arrayInitializerElements(newpos, t);
2532         return toP(F.at(newpos).NewArray(t, List.nil(), elems));
2533     }
2534 
2535     List<JCExpression> arrayInitializerElements(int newpos, JCExpression t) {
2536         accept(LBRACE);
2537         ListBuffer<JCExpression> elems = new ListBuffer<>();
2538         if (token.kind == COMMA) {
2539             nextToken();
2540         } else if (token.kind != RBRACE) {
2541             elems.append(variableInitializer());
2542             while (token.kind == COMMA) {
2543                 nextToken();
2544                 if (token.kind == RBRACE) break;
2545                 elems.append(variableInitializer());

2738                     accept(SEMI);
2739                     return List.of(toP(F.at(pos).Yield(t)));
2740                 }
2741 
2742                 //else intentional fall-through
2743             } else {
2744                 if (isNonSealedClassStart(true)) {
2745                     log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2746                     nextToken();
2747                     nextToken();
2748                     nextToken();
2749                     return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.comment(CommentStyle.JAVADOC)));
2750                 } else if (isSealedClassStart(true)) {
2751                     checkSourceLevel(Feature.SEALED_CLASSES);
2752                     log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2753                     nextToken();
2754                     return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.comment(CommentStyle.JAVADOC)));
2755                 }
2756             }
2757         }




2758         if (isRecordStart() && allowRecords) {
2759             dc = token.comment(CommentStyle.JAVADOC);
2760             return List.of(recordDeclaration(F.at(pos).Modifiers(0), dc));
2761         } else {
2762             Token prevToken = token;
2763             JCExpression t = term(EXPR | TYPE);
2764             if (token.kind == COLON && t.hasTag(IDENT)) {
2765                 nextToken();
2766                 JCStatement stat = parseStatementAsBlock();
2767                 return List.of(F.at(pos).Labelled(prevToken.name(), stat));
2768             } else if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.test(token.kind)) {
2769                 pos = token.pos;
2770                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2771                 F.at(pos);
2772                 return localVariableDeclarations(mods, t);
2773             } else {
2774                 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
2775                 t = checkExprStat(t);
2776                 accept(SEMI);
2777                 JCExpressionStatement expr = toP(F.at(pos).Exec(t));

3197             nextToken();
3198             pos = token.pos;
3199             JCExpression t = parseExpression();
3200             // This Exec is a "StatementExpression"; it subsumes no terminating token
3201             stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
3202         }
3203         return stats;
3204     }
3205 
3206     /** ForInit = StatementExpression MoreStatementExpressions
3207      *           |  { FINAL | '@' Annotation } Type VariableDeclarators
3208      */
3209     List<JCStatement> forInit() {
3210         ListBuffer<JCStatement> stats = new ListBuffer<>();
3211         int pos = token.pos;
3212         if (token.kind == FINAL || token.kind == MONKEYS_AT) {
3213             return variableDeclarators(optFinal(0), parseType(true), stats, true).toList();
3214         } else {
3215             JCExpression t = term(EXPR | TYPE);
3216             if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.test(token.kind)) {
3217                 return variableDeclarators(modifiersOpt(), t, stats, true).toList();



3218             } else if ((lastmode & TYPE) != 0 && token.kind == COLON) {
3219                 log.error(DiagnosticFlag.SYNTAX, pos, Errors.BadInitializer("for-loop"));
3220                 return List.of((JCStatement)F.at(pos).VarDef(modifiersOpt(), names.error, t, null));
3221             } else {
3222                 return moreStatementExpressions(pos, t, stats).toList();
3223             }
3224         }
3225     }
3226 
3227     /** ForUpdate = StatementExpression MoreStatementExpressions
3228      */
3229     List<JCExpressionStatement> forUpdate() {
3230         return moreStatementExpressions(token.pos,
3231                                         parseExpression(),
3232                                         new ListBuffer<JCExpressionStatement>()).toList();
3233     }
3234 
3235     /** AnnotationsOpt = { '@' Annotation }
3236      *
3237      * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION

3294             case ABSTRACT    : flag = Flags.ABSTRACT; break;
3295             case NATIVE      : flag = Flags.NATIVE; break;
3296             case VOLATILE    : flag = Flags.VOLATILE; break;
3297             case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
3298             case STRICTFP    : flag = Flags.STRICTFP; break;
3299             case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
3300             case DEFAULT     : flag = Flags.DEFAULT; break;
3301             case ERROR       : flag = 0; nextToken(); break;
3302             case IDENTIFIER  : {
3303                 if (isNonSealedClassStart(false)) {
3304                     flag = Flags.NON_SEALED;
3305                     nextToken();
3306                     nextToken();
3307                     break;
3308                 }
3309                 if (isSealedClassStart(false)) {
3310                     checkSourceLevel(Feature.SEALED_CLASSES);
3311                     flag = Flags.SEALED;
3312                     break;
3313                 }












3314                 break loop;
3315             }
3316             default: break loop;
3317             }
3318             if ((flags & flag) != 0) log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.RepeatedModifier);
3319             lastPos = token.pos;
3320             nextToken();
3321             if (flag == Flags.ANNOTATION) {
3322                 if (token.kind != INTERFACE) {
3323                     JCAnnotation ann = annotation(lastPos, Tag.ANNOTATION);
3324                     // if first modifier is an annotation, set pos to annotation's.
3325                     if (flags == 0 && annotations.isEmpty())
3326                         pos = ann.pos;
3327                     annotations.append(ann);
3328                     flag = 0;
3329                 }
3330             }
3331             flags |= flag;
3332         }
3333         switch (token.kind) {

3545             if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) {
3546                 return Source.JDK10;
3547             } else if (shouldWarn) {
3548                 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK10));
3549             }
3550         }
3551         if (name == names.yield) {
3552             if (allowYieldStatement) {
3553                 return Source.JDK14;
3554             } else if (shouldWarn) {
3555                 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK14));
3556             }
3557         }
3558         if (name == names.record) {
3559             if (allowRecords) {
3560                 return Source.JDK14;
3561             } else if (shouldWarn) {
3562                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK14));
3563             }
3564         }



















3565         if (name == names.sealed) {
3566             if (allowSealedTypes) {
3567                 return Source.JDK15;
3568             } else if (shouldWarn) {
3569                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3570             }
3571         }
3572         if (name == names.permits) {
3573             if (allowSealedTypes) {
3574                 return Source.JDK15;
3575             } else if (shouldWarn) {
3576                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3577             }
3578         }
3579         return null;
3580     }
3581 
3582     /** VariableDeclaratorId = Ident BracketsOpt
3583      */
3584     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {

4442             Token next = S.token(3);
4443             return allowedAfterSealedOrNonSealed(next, local, true);
4444         }
4445         return false;
4446     }
4447 
4448     protected boolean isNonSealedIdentifier(Token someToken, int lookAheadOffset) {
4449         if (someToken.name() == names.non && peekToken(lookAheadOffset, TokenKind.SUB, TokenKind.IDENTIFIER)) {
4450             Token tokenSub = S.token(lookAheadOffset + 1);
4451             Token tokenSealed = S.token(lookAheadOffset + 2);
4452             if (someToken.endPos == tokenSub.pos &&
4453                     tokenSub.endPos == tokenSealed.pos &&
4454                     tokenSealed.name() == names.sealed) {
4455                 checkSourceLevel(Feature.SEALED_CLASSES);
4456                 return true;
4457             }
4458         }
4459         return false;
4460     }
4461 














































































4462     protected boolean isSealedClassStart(boolean local) {
4463         if (token.name() == names.sealed) {
4464             Token next = S.token(1);
4465             if (allowedAfterSealedOrNonSealed(next, local, false)) {
4466                 checkSourceLevel(Feature.SEALED_CLASSES);
4467                 return true;
4468             }
4469         }
4470         return false;
4471     }
4472 
4473     private boolean allowedAfterSealedOrNonSealed(Token next, boolean local, boolean currentIsNonSealed) {
4474         return local ?
4475             switch (next.kind) {
4476                 case MONKEYS_AT -> {
4477                     Token afterNext = S.token(2);
4478                     yield afterNext.kind != INTERFACE || currentIsNonSealed;
4479                 }
4480                 case ABSTRACT, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4481                 default -> false;
4482             } :
4483             switch (next.kind) {
4484                 case MONKEYS_AT -> {
4485                     Token afterNext = S.token(2);
4486                     yield afterNext.kind != INTERFACE || currentIsNonSealed;
4487                 }
4488                 case PUBLIC, PROTECTED, PRIVATE, ABSTRACT, STATIC, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4489                 case IDENTIFIER -> isNonSealedIdentifier(next, currentIsNonSealed ? 3 : 1) || next.name() == names.sealed;



4490                 default -> false;
4491             };
4492     }
4493 
4494     /** MethodDeclaratorRest =
4495      *      FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
4496      *  VoidMethodDeclaratorRest =
4497      *      FormalParameters [THROWS TypeList] ( MethodBody | ";")
4498      *  ConstructorDeclaratorRest =
4499      *      "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
4500      */
4501     protected JCTree methodDeclaratorRest(int pos,
4502                               JCModifiers mods,
4503                               JCExpression type,
4504                               Name name,
4505                               List<JCTypeParameter> typarams,
4506                               boolean isInterface, boolean isVoid,
4507                               boolean isRecord,
4508                               Comment dc) {
4509         if (isInterface) {

4956         case INT:
4957             return TypeTag.INT;
4958         case LONG:
4959             return TypeTag.LONG;
4960         case FLOAT:
4961             return TypeTag.FLOAT;
4962         case DOUBLE:
4963             return TypeTag.DOUBLE;
4964         case BOOLEAN:
4965             return TypeTag.BOOLEAN;
4966         default:
4967             return TypeTag.NONE;
4968         }
4969     }
4970 
4971     void checkSourceLevel(Feature feature) {
4972         checkSourceLevel(token.pos, feature);
4973     }
4974 
4975     protected void checkSourceLevel(int pos, Feature feature) {
4976         if (preview.isPreview(feature) && !preview.isEnabled()) {



4977             //preview feature without --preview flag, error
4978             log.error(DiagnosticFlag.SOURCE_LEVEL, pos, preview.disabledError(feature));
4979         } else if (!feature.allowedInSource(source)) {
4980             //incompatible source level, error
4981             log.error(DiagnosticFlag.SOURCE_LEVEL, pos, feature.error(source.name));
4982         } else if (preview.isPreview(feature)) {
4983             //use of preview feature, warn
4984             preview.warnPreview(pos, feature);
4985         }
4986     }
4987 
4988     /*
4989      * a functional source tree and end position mappings
4990      */
4991     protected static class SimpleEndPosTable extends AbstractEndPosTable {
4992 
4993         private final IntHashTable endPosMap;
4994 
4995         SimpleEndPosTable(JavacParser parser) {
4996             super(parser);

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

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

1388                         break loop;
1389                     case LPAREN:
1390                         if ((mode & EXPR) != 0) {
1391                             selectExprMode();
1392                             t = arguments(typeArgs, t);
1393                             if (!annos.isEmpty()) t = illegal(annos.head.pos);
1394                             typeArgs = null;
1395                         }
1396                         break loop;
1397                     case DOT:
1398                         nextToken();
1399                         if (token.kind == TokenKind.IDENTIFIER && typeArgs != null) {
1400                             return illegal();
1401                         }
1402                         int oldmode = mode;
1403                         mode &= ~NOPARAMS;
1404                         typeArgs = typeArgumentsOpt(EXPR);
1405                         mode = oldmode;
1406                         if ((mode & EXPR) != 0) {
1407                             switch (token.kind) {
1408                             case DEFAULT:
1409                                 if (typeArgs != null) return illegal();
1410                                 selectExprMode();
1411                                 t = to(F.at(pos).DefaultValue(t));
1412                                 nextToken();
1413                                 break loop;
1414                             case CLASS:
1415                                 if (typeArgs != null) return illegal();
1416                                 selectExprMode();
1417                                 t = to(F.at(pos).Select(t, names._class));
1418                                 nextToken();
1419                                 break loop;
1420                             case THIS:
1421                                 if (typeArgs != null) return illegal();
1422                                 selectExprMode();
1423                                 t = to(F.at(pos).Select(t, names._this));
1424                                 nextToken();
1425                                 break loop;
1426                             case SUPER:
1427                                 selectExprMode();
1428                                 t = to(F.at(pos).Select(t, names._super));
1429                                 t = superSuffix(typeArgs, t);
1430                                 typeArgs = null;
1431                                 break loop;
1432                             case NEW:
1433                                 if (typeArgs != null) return illegal();

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

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

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

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

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

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

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

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

3260             nextToken();
3261             pos = token.pos;
3262             JCExpression t = parseExpression();
3263             // This Exec is a "StatementExpression"; it subsumes no terminating token
3264             stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
3265         }
3266         return stats;
3267     }
3268 
3269     /** ForInit = StatementExpression MoreStatementExpressions
3270      *           |  { FINAL | '@' Annotation } Type VariableDeclarators
3271      */
3272     List<JCStatement> forInit() {
3273         ListBuffer<JCStatement> stats = new ListBuffer<>();
3274         int pos = token.pos;
3275         if (token.kind == FINAL || token.kind == MONKEYS_AT) {
3276             return variableDeclarators(optFinal(0), parseType(true), stats, true).toList();
3277         } else {
3278             JCExpression t = term(EXPR | TYPE);
3279             if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.test(token.kind)) {
3280                 pos = token.pos;
3281                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
3282                 F.at(pos);
3283                 return variableDeclarators(mods, t, stats, true).toList();
3284             } else if ((lastmode & TYPE) != 0 && token.kind == COLON) {
3285                 log.error(DiagnosticFlag.SYNTAX, pos, Errors.BadInitializer("for-loop"));
3286                 return List.of((JCStatement)F.at(pos).VarDef(modifiersOpt(), names.error, t, null));
3287             } else {
3288                 return moreStatementExpressions(pos, t, stats).toList();
3289             }
3290         }
3291     }
3292 
3293     /** ForUpdate = StatementExpression MoreStatementExpressions
3294      */
3295     List<JCExpressionStatement> forUpdate() {
3296         return moreStatementExpressions(token.pos,
3297                                         parseExpression(),
3298                                         new ListBuffer<JCExpressionStatement>()).toList();
3299     }
3300 
3301     /** AnnotationsOpt = { '@' Annotation }
3302      *
3303      * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION

3360             case ABSTRACT    : flag = Flags.ABSTRACT; break;
3361             case NATIVE      : flag = Flags.NATIVE; break;
3362             case VOLATILE    : flag = Flags.VOLATILE; break;
3363             case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
3364             case STRICTFP    : flag = Flags.STRICTFP; break;
3365             case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
3366             case DEFAULT     : flag = Flags.DEFAULT; break;
3367             case ERROR       : flag = 0; nextToken(); break;
3368             case IDENTIFIER  : {
3369                 if (isNonSealedClassStart(false)) {
3370                     flag = Flags.NON_SEALED;
3371                     nextToken();
3372                     nextToken();
3373                     break;
3374                 }
3375                 if (isSealedClassStart(false)) {
3376                     checkSourceLevel(Feature.SEALED_CLASSES);
3377                     flag = Flags.SEALED;
3378                     break;
3379                 }
3380                 if (isPrimitiveModifier()) {
3381                     flag = Flags.PRIMITIVE_CLASS;
3382                     break;
3383                 }
3384                 if (isValueModifier()) {
3385                     flag = Flags.VALUE_CLASS;
3386                     break;
3387                 }
3388                 if (isIdentityModifier()) {
3389                     flag = Flags.IDENTITY_TYPE;
3390                     break;
3391                 }
3392                 break loop;
3393             }
3394             default: break loop;
3395             }
3396             if ((flags & flag) != 0) log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.RepeatedModifier);
3397             lastPos = token.pos;
3398             nextToken();
3399             if (flag == Flags.ANNOTATION) {
3400                 if (token.kind != INTERFACE) {
3401                     JCAnnotation ann = annotation(lastPos, Tag.ANNOTATION);
3402                     // if first modifier is an annotation, set pos to annotation's.
3403                     if (flags == 0 && annotations.isEmpty())
3404                         pos = ann.pos;
3405                     annotations.append(ann);
3406                     flag = 0;
3407                 }
3408             }
3409             flags |= flag;
3410         }
3411         switch (token.kind) {

3623             if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) {
3624                 return Source.JDK10;
3625             } else if (shouldWarn) {
3626                 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK10));
3627             }
3628         }
3629         if (name == names.yield) {
3630             if (allowYieldStatement) {
3631                 return Source.JDK14;
3632             } else if (shouldWarn) {
3633                 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK14));
3634             }
3635         }
3636         if (name == names.record) {
3637             if (allowRecords) {
3638                 return Source.JDK14;
3639             } else if (shouldWarn) {
3640                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK14));
3641             }
3642         }
3643         if (name == names.primitive) {
3644             if (allowPrimitiveClasses) {
3645                 return Source.JDK18;
3646             }
3647         }
3648         if (name == names.value) {
3649             if (allowValueClasses) {
3650                 return Source.JDK18;
3651             } else if (shouldWarn) {
3652                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK18));
3653             }
3654         }
3655         if (name == names.identity) {
3656             if (allowPrimitiveClasses) {
3657                 return Source.JDK18;
3658             } else if (shouldWarn) {
3659                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK18));
3660             }
3661         }
3662         if (name == names.sealed) {
3663             if (allowSealedTypes) {
3664                 return Source.JDK15;
3665             } else if (shouldWarn) {
3666                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3667             }
3668         }
3669         if (name == names.permits) {
3670             if (allowSealedTypes) {
3671                 return Source.JDK15;
3672             } else if (shouldWarn) {
3673                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3674             }
3675         }
3676         return null;
3677     }
3678 
3679     /** VariableDeclaratorId = Ident BracketsOpt
3680      */
3681     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {

4539             Token next = S.token(3);
4540             return allowedAfterSealedOrNonSealed(next, local, true);
4541         }
4542         return false;
4543     }
4544 
4545     protected boolean isNonSealedIdentifier(Token someToken, int lookAheadOffset) {
4546         if (someToken.name() == names.non && peekToken(lookAheadOffset, TokenKind.SUB, TokenKind.IDENTIFIER)) {
4547             Token tokenSub = S.token(lookAheadOffset + 1);
4548             Token tokenSealed = S.token(lookAheadOffset + 2);
4549             if (someToken.endPos == tokenSub.pos &&
4550                     tokenSub.endPos == tokenSealed.pos &&
4551                     tokenSealed.name() == names.sealed) {
4552                 checkSourceLevel(Feature.SEALED_CLASSES);
4553                 return true;
4554             }
4555         }
4556         return false;
4557     }
4558 
4559     protected boolean isPrimitiveModifier() {
4560         if (token.kind == IDENTIFIER && token.name() == names.primitive) {
4561             boolean isPrimitiveModifier = false;
4562             Token next = S.token(1);
4563             switch (next.kind) {
4564                 case PRIVATE: case PROTECTED: case PUBLIC: case STATIC: case TRANSIENT:
4565                 case FINAL: case ABSTRACT: case NATIVE: case VOLATILE: case SYNCHRONIZED:
4566                 case STRICTFP: case MONKEYS_AT: case DEFAULT: case BYTE: case SHORT:
4567                 case CHAR: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
4568                 case CLASS: case INTERFACE: case ENUM:
4569                     isPrimitiveModifier = true;
4570                     break;
4571                 case IDENTIFIER: // primitive record R || primitive primitive || primitive identity || primitive value || new primitive Comparable() {}
4572                     if (next.name() == names.record || next.name() == names.primitive || next.name() == names.identity
4573                             || next.name() == names.value || (mode & EXPR) != 0)
4574                         isPrimitiveModifier = true;
4575                     break;
4576             }
4577             if (isPrimitiveModifier) {
4578                 checkSourceLevel(Feature.PRIMITIVE_CLASSES);
4579                 return true;
4580             }
4581         }
4582         return false;
4583     }
4584 
4585     protected boolean isValueModifier() {
4586         if (token.kind == IDENTIFIER && token.name() == names.value) {
4587             boolean isValueModifier = false;
4588             Token next = S.token(1);
4589             switch (next.kind) {
4590                 case PRIVATE: case PROTECTED: case PUBLIC: case STATIC: case TRANSIENT:
4591                 case FINAL: case ABSTRACT: case NATIVE: case VOLATILE: case SYNCHRONIZED:
4592                 case STRICTFP: case MONKEYS_AT: case DEFAULT: case BYTE: case SHORT:
4593                 case CHAR: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
4594                 case CLASS: case INTERFACE: case ENUM:
4595                     isValueModifier = true;
4596                     break;
4597                 case IDENTIFIER: // value record R || value value || value identity || value primitive || new value Comparable() {} ??
4598                     if (next.name() == names.record || next.name() == names.value || next.name() == names.identity
4599                             || next.name() == names.primitive || (mode & EXPR) != 0)
4600                         isValueModifier = true;
4601                     break;
4602             }
4603             if (isValueModifier) {
4604                 checkSourceLevel(Feature.VALUE_CLASSES);
4605                 return true;
4606             }
4607         }
4608         return false;
4609     }
4610 
4611     protected boolean isIdentityModifier() {
4612         if (token.kind == IDENTIFIER && token.name() == names.identity) {
4613             boolean isIdentityModifier = false;
4614             Token next = S.token(1);
4615             switch (next.kind) {
4616                 case PRIVATE: case PROTECTED: case PUBLIC: case STATIC: case TRANSIENT:
4617                 case FINAL: case ABSTRACT: case NATIVE: case VOLATILE: case SYNCHRONIZED:
4618                 case STRICTFP: case MONKEYS_AT: case DEFAULT: case BYTE: case SHORT:
4619                 case CHAR: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
4620                 case CLASS: case INTERFACE: case ENUM:
4621                     isIdentityModifier = true;
4622                     break;
4623                 case IDENTIFIER: // identity record R || identity primitive || || identity identity || identity value || new identity Comparable() {}
4624                     if (next.name() == names.record || next.name() == names.primitive || next.name() == names.identity
4625                             || next.name() == names.value || (mode & EXPR) != 0)
4626                         isIdentityModifier = true;
4627                     break;
4628             }
4629             if (isIdentityModifier) {
4630                 checkSourceLevel(Feature.VALUE_CLASSES);
4631                 return true;
4632             }
4633         }
4634         return false;
4635     }
4636 
4637     protected boolean isSealedClassStart(boolean local) {
4638         if (token.name() == names.sealed) {
4639             Token next = S.token(1);
4640             if (allowedAfterSealedOrNonSealed(next, local, false)) {
4641                 checkSourceLevel(Feature.SEALED_CLASSES);
4642                 return true;
4643             }
4644         }
4645         return false;
4646     }
4647 
4648     private boolean allowedAfterSealedOrNonSealed(Token next, boolean local, boolean currentIsNonSealed) {
4649         return local ?
4650             switch (next.kind) {
4651                 case MONKEYS_AT -> {
4652                     Token afterNext = S.token(2);
4653                     yield afterNext.kind != INTERFACE || currentIsNonSealed;
4654                 }
4655                 case ABSTRACT, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4656                 default -> false;
4657             } :
4658             switch (next.kind) {
4659                 case MONKEYS_AT -> {
4660                     Token afterNext = S.token(2);
4661                     yield afterNext.kind != INTERFACE || currentIsNonSealed;
4662                 }
4663                 case PUBLIC, PROTECTED, PRIVATE, ABSTRACT, STATIC, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4664                 case IDENTIFIER -> isNonSealedIdentifier(next, currentIsNonSealed ? 3 : 1) ||
4665                         next.name() == names.sealed ||
4666                         next.name() == names.value ||
4667                         next.name() == names.identity;
4668                 default -> false;
4669             };
4670     }
4671 
4672     /** MethodDeclaratorRest =
4673      *      FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
4674      *  VoidMethodDeclaratorRest =
4675      *      FormalParameters [THROWS TypeList] ( MethodBody | ";")
4676      *  ConstructorDeclaratorRest =
4677      *      "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
4678      */
4679     protected JCTree methodDeclaratorRest(int pos,
4680                               JCModifiers mods,
4681                               JCExpression type,
4682                               Name name,
4683                               List<JCTypeParameter> typarams,
4684                               boolean isInterface, boolean isVoid,
4685                               boolean isRecord,
4686                               Comment dc) {
4687         if (isInterface) {

5134         case INT:
5135             return TypeTag.INT;
5136         case LONG:
5137             return TypeTag.LONG;
5138         case FLOAT:
5139             return TypeTag.FLOAT;
5140         case DOUBLE:
5141             return TypeTag.DOUBLE;
5142         case BOOLEAN:
5143             return TypeTag.BOOLEAN;
5144         default:
5145             return TypeTag.NONE;
5146         }
5147     }
5148 
5149     void checkSourceLevel(Feature feature) {
5150         checkSourceLevel(token.pos, feature);
5151     }
5152 
5153     protected void checkSourceLevel(int pos, Feature feature) {
5154         if (feature == Feature.PRIMITIVE_CLASSES && !allowPrimitiveClasses) {
5155             // primitive classes are special
5156             log.error(DiagnosticFlag.SOURCE_LEVEL, pos, feature.error(source.name));
5157         } else if (preview.isPreview(feature) && !preview.isEnabled()) {
5158             //preview feature without --preview flag, error
5159             log.error(DiagnosticFlag.SOURCE_LEVEL, pos, preview.disabledError(feature));
5160         } else if (!feature.allowedInSource(source)) {
5161             //incompatible source level, error
5162             log.error(DiagnosticFlag.SOURCE_LEVEL, pos, feature.error(source.name));
5163         } else if (preview.isPreview(feature)) {
5164             //use of preview feature, warn
5165             preview.warnPreview(pos, feature);
5166         }
5167     }
5168 
5169     /*
5170      * a functional source tree and end position mappings
5171      */
5172     protected static class SimpleEndPosTable extends AbstractEndPosTable {
5173 
5174         private final IntHashTable endPosMap;
5175 
5176         SimpleEndPosTable(JavacParser parser) {
5177             super(parser);
< prev index next >