< prev index next >

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

Print this page

  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 javax.lang.model.SourceVersion;
  34 
  35 import com.sun.source.tree.CaseTree;
  36 import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
  37 import com.sun.source.tree.ModuleTree.ModuleKind;
  38 
  39 import com.sun.tools.javac.code.*;

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

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

  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 com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
  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 

 175                      boolean keepLineMap,
 176                      boolean keepEndPositions,
 177                      boolean parseModuleInfo) {
 178         this.S = S;
 179         nextToken(); // prime the pump
 180         this.F = fac.F;
 181         this.log = fac.log;
 182         this.names = fac.names;
 183         this.source = fac.source;
 184         this.preview = fac.preview;
 185         this.allowStringFolding = fac.options.getBoolean("allowStringFolding", true);
 186         this.keepDocComments = keepDocComments;
 187         this.parseModuleInfo = parseModuleInfo;
 188         this.docComments = newDocCommentTable(keepDocComments, fac);
 189         this.keepLineMap = keepLineMap;
 190         this.errorTree = F.Erroneous();
 191         this.endPosTable = newEndPosTable(keepEndPositions);
 192         this.allowYieldStatement = Feature.SWITCH_EXPRESSION.allowedInSource(source);
 193         this.allowRecords = Feature.RECORDS.allowedInSource(source);
 194         this.allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);


 195     }
 196 
 197     /** Construct a parser from an existing parser, with minimal overhead.
 198      */
 199     @SuppressWarnings("this-escape")
 200     protected JavacParser(JavacParser parser,
 201                           Lexer S) {
 202         this.S = S;
 203         this.token = parser.token;
 204         this.F = parser.F;
 205         this.log = parser.log;
 206         this.names = parser.names;
 207         this.source = parser.source;
 208         this.preview = parser.preview;
 209         this.allowStringFolding = parser.allowStringFolding;
 210         this.keepDocComments = false;
 211         this.parseModuleInfo = false;
 212         this.docComments = null;
 213         this.errorTree = F.Erroneous();
 214         this.endPosTable = newEndPosTable(false);
 215         this.allowYieldStatement = Feature.SWITCH_EXPRESSION.allowedInSource(source);
 216         this.allowRecords = Feature.RECORDS.allowedInSource(source);
 217         this.allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);


 218     }
 219 
 220     protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) {
 221         return  keepEndPositions
 222                 ? new SimpleEndPosTable(this)
 223                 : new EmptyEndPosTable(this);
 224     }
 225 
 226     protected DocCommentTable newDocCommentTable(boolean keepDocComments, ParserFactory fac) {
 227         return keepDocComments ? new LazyDocCommentTable(fac) : null;
 228     }
 229 
 230     /** Switch: should we fold strings?
 231      */
 232     boolean allowStringFolding;
 233 
 234     /** Switch: should we keep docComments?
 235      */
 236     boolean keepDocComments;
 237 
 238     /** Switch: should we keep line table?
 239      */
 240     boolean keepLineMap;
 241 
 242     /** Switch: is "this" allowed as an identifier?
 243      * This is needed to parse receiver types.
 244      */
 245     boolean allowThisIdent;
 246 
 247     /** Switch: is yield statement allowed in this source level?
 248      */
 249     boolean allowYieldStatement;
 250 
 251     /** Switch: are records allowed in this source level?
 252      */
 253     boolean allowRecords;
 254 








 255     /** Switch: are sealed types allowed in this source level?
 256      */
 257     boolean allowSealedTypes;
 258 
 259     /** The type of the method receiver, as specified by a first "this" parameter.
 260      */
 261     JCVariableDecl receiverParam;
 262 
 263     /** When terms are parsed, the mode determines which is expected:
 264      *     mode = EXPR        : an expression
 265      *     mode = TYPE        : a type
 266      *     mode = NOPARAMS    : no parameters allowed for type
 267      *     mode = TYPEARG     : type argument
 268      *     mode |= NOLAMBDA   : lambdas are not allowed
 269      */
 270     protected static final int EXPR          = 1 << 0;
 271     protected static final int TYPE          = 1 << 1;
 272     protected static final int NOPARAMS      = 1 << 2;
 273     protected static final int TYPEARG       = 1 << 3;
 274     protected static final int DIAMOND       = 1 << 4;

 498 
 499     /** If next input token matches given token, skip it, otherwise report
 500      *  an error.
 501      */
 502     public void accept(TokenKind tk) {
 503         accept(tk, Errors::Expected);
 504     }
 505 
 506     /** If next input token matches given token, skip it, otherwise report
 507      *  an error.
 508      */
 509     public void accept(TokenKind tk, Function<TokenKind, Error> errorProvider) {
 510         if (token.kind == tk) {
 511             nextToken();
 512         } else {
 513             setErrorEndPos(token.pos);
 514             reportSyntaxError(S.prevToken().endPos, errorProvider.apply(tk));
 515         }
 516     }
 517 
















 518     /** Report an illegal start of expression/type error at given position.
 519      */
 520     JCExpression illegal(int pos) {
 521         setErrorEndPos(pos);
 522         if (isMode(EXPR))
 523             return syntaxError(pos, Errors.IllegalStartOfExpr);
 524         else
 525             return syntaxError(pos, Errors.IllegalStartOfType);
 526 
 527     }
 528 
 529     /** Report an illegal start of expression/type error at current position.
 530      */
 531     JCExpression illegal() {
 532         return illegal(token.pos);
 533     }
 534 
 535     /** Diagnose a modifier flag from the set, if any. */
 536     protected void checkNoMods(long mods) {
 537         checkNoMods(token.pos, mods);

1488                         break loop;
1489                     case LPAREN:
1490                         if (isMode(EXPR)) {
1491                             selectExprMode();
1492                             t = arguments(typeArgs, t);
1493                             if (!annos.isEmpty()) t = illegal(annos.head.pos);
1494                             typeArgs = null;
1495                         }
1496                         break loop;
1497                     case DOT:
1498                         nextToken();
1499                         if (token.kind == TokenKind.IDENTIFIER && typeArgs != null) {
1500                             return illegal();
1501                         }
1502                         int prevmode = mode;
1503                         setMode(mode & ~NOPARAMS);
1504                         typeArgs = typeArgumentsOpt(EXPR);
1505                         setMode(prevmode);
1506                         if (isMode(EXPR)) {
1507                             switch (token.kind) {






1508                             case CLASS:
1509                                 if (typeArgs != null) return illegal();
1510                                 selectExprMode();
1511                                 t = to(F.at(pos).Select(t, names._class));
1512                                 nextToken();
1513                                 break loop;
1514                             case THIS:
1515                                 if (typeArgs != null) return illegal();
1516                                 selectExprMode();
1517                                 t = to(F.at(pos).Select(t, names._this));
1518                                 nextToken();
1519                                 break loop;
1520                             case SUPER:
1521                                 selectExprMode();
1522                                 t = to(F.at(pos).Select(t, names._super));
1523                                 t = superSuffix(typeArgs, t);
1524                                 typeArgs = null;
1525                                 break loop;
1526                             case NEW:
1527                                 if (typeArgs != null) return illegal();

1551                             token.kind == MONKEYS_AT) {
1552                             //error recovery, case like:
1553                             //int i = expr.<missing-ident>
1554                             //@Deprecated
1555                             if (typeArgs != null) illegal();
1556                             return toP(t);
1557                         }
1558                         if (tyannos != null && tyannos.nonEmpty()) {
1559                             t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
1560                         }
1561                         break;
1562                     case ELLIPSIS:
1563                         if (this.permitTypeAnnotationsPushBack) {
1564                             this.typeAnnotationsPushedBack = annos;
1565                         } else if (annos.nonEmpty()) {
1566                             // Don't return here -- error recovery attempt
1567                             illegal(annos.head.pos);
1568                         }
1569                         break loop;
1570                     case LT:
1571                         if (!isMode(TYPE) && isUnboundMemberRef()) {
1572                             //this is an unbound method reference whose qualifier
1573                             //is a generic type i.e. A<S>::m

1574                             int pos1 = token.pos;
1575                             accept(LT);
1576                             ListBuffer<JCExpression> args = new ListBuffer<>();
1577                             args.append(typeArgument());
1578                             while (token.kind == COMMA) {
1579                                 nextToken();
1580                                 args.append(typeArgument());
1581                             }
1582                             accept(GT);
1583                             t = toP(F.at(pos1).TypeApply(t, args.toList()));
1584                             while (token.kind == DOT) {
1585                                 nextToken();






1586                                 selectTypeMode();
1587                                 t = toP(F.at(token.pos).Select(t, ident()));
1588                                 t = typeArgumentsOpt(t);
1589                             }
1590                             t = bracketsOpt(t);
1591                             if (token.kind != COLCOL) {
1592                                 //method reference expected here
1593                                 t = illegal();
1594                             }
1595                             selectExprMode();
1596                             return term3Rest(t, typeArgs);
1597                         }
1598                         break loop;
1599                     default:
1600                         break loop;
1601                     }
1602                 }
1603             }
1604             if (typeArgs != null) illegal();
1605             t = typeArgumentsOpt(t);

1796                 if (!annos.isEmpty()) {
1797                     if (permitTypeAnnotationsPushBack)
1798                         typeAnnotationsPushedBack = annos;
1799                     else
1800                         return illegal(annos.head.pos);
1801                 }
1802                 break;
1803             }
1804         }
1805         while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && isMode(EXPR)) {
1806             selectExprMode();
1807             t = to(F.at(token.pos).Unary(
1808                   token.kind == PLUSPLUS ? POSTINC : POSTDEC, t));
1809             nextToken();
1810         }
1811         return toP(t);
1812     }
1813 
1814     /**
1815      * If we see an identifier followed by a '&lt;' it could be an unbound
1816      * method reference or a binary expression. To disambiguate, look for a

1817      * matching '&gt;' and see if the subsequent terminal is either '.' or '::'.
1818      */
1819     @SuppressWarnings("fallthrough")
1820     boolean isUnboundMemberRef() {
1821         int pos = 0, depth = 0;
1822         outer: for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
1823             switch (t.kind) {
1824                 case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
1825                 case DOT: case RBRACKET: case LBRACKET: case COMMA:
1826                 case BYTE: case SHORT: case INT: case LONG: case FLOAT:
1827                 case DOUBLE: case BOOLEAN: case CHAR:
1828                 case MONKEYS_AT:
1829                     break;
1830 
1831                 case LPAREN:
1832                     // skip annotation values
1833                     int nesting = 0;
1834                     for (; ; pos++) {
1835                         TokenKind tk2 = S.token(pos).kind;
1836                         switch (tk2) {
1837                             case EOF:
1838                                 return false;
1839                             case LPAREN:
1840                                 nesting++;

2407 
2408     private JCExpression bracketsOptCont(JCExpression t, int pos,
2409             List<JCAnnotation> annotations) {
2410         accept(RBRACKET);
2411         t = bracketsOpt(t);
2412         t = toP(F.at(pos).TypeArray(t));
2413         if (annotations.nonEmpty()) {
2414             t = toP(F.at(pos).AnnotatedType(annotations, t));
2415         }
2416         return t;
2417     }
2418 
2419     /** BracketsSuffixExpr = "." CLASS
2420      *  BracketsSuffixType =
2421      */
2422     JCExpression bracketsSuffix(JCExpression t) {
2423         if (isMode(EXPR) && token.kind == DOT) {
2424             selectExprMode();
2425             int pos = token.pos;
2426             nextToken();
2427             accept(CLASS);
2428             if (token.pos == endPosTable.errorEndPos) {
2429                 // error recovery
2430                 Name name;
2431                 if (LAX_IDENTIFIER.test(token.kind)) {
2432                     name = token.name();
2433                     nextToken();
2434                 } else {
2435                     name = names.error;
2436                 }
2437                 t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name))));
2438             } else {
2439                 Tag tag = t.getTag();
2440                 // Type annotations are illegal on class literals. Annotated non array class literals
2441                 // are complained about directly in term3(), Here check for type annotations on dimensions
2442                 // taking care to handle some interior dimension(s) being annotated.
2443                 if ((tag == TYPEARRAY && TreeInfo.containsTypeAnnotation(t)) || tag == ANNOTATED_TYPE)
2444                     syntaxError(token.pos, Errors.NoAnnotationsOnDotClass);
2445                 t = toP(F.at(pos).Select(t, names._class));




2446             }
2447         } else if (isMode(TYPE)) {
2448             if (token.kind != COLCOL) {
2449                 selectTypeMode();
2450             }
2451         } else if (token.kind != COLCOL) {
2452             syntaxError(token.pos, Errors.DotClassExpected);
2453         }
2454         return t;
2455     }
2456 
2457     /**
2458      * MemberReferenceSuffix = "::" [TypeArguments] Ident
2459      *                       | "::" [TypeArguments] "new"
2460      */
2461     JCExpression memberReferenceSuffix(JCExpression t) {
2462         int pos1 = token.pos;
2463         accept(COLCOL);
2464         return memberReferenceSuffix(pos1, t);
2465     }
2466 
2467     JCExpression memberReferenceSuffix(int pos1, JCExpression t) {
2468         selectExprMode();
2469         List<JCExpression> typeArgs = null;
2470         if (token.kind == LT) {
2471             typeArgs = typeArguments(false);
2472         }
2473         Name refName;
2474         ReferenceMode refMode;
2475         if (token.kind == NEW) {
2476             refMode = ReferenceMode.NEW;

2477             refName = names.init;
2478             nextToken();
2479         } else {
2480             refMode = ReferenceMode.INVOKE;
2481             refName = ident();
2482         }
2483         return toP(F.at(t.getStartPosition()).Reference(refMode, refName, t, typeArgs));
2484     }
2485 
2486     /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
2487      */
2488     JCExpression creator(int newpos, List<JCExpression> typeArgs) {
2489         List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
2490 
2491         switch (token.kind) {
2492         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
2493         case DOUBLE: case BOOLEAN:



2494             if (typeArgs == null) {
2495                 if (newAnnotations.isEmpty()) {
2496                     return arrayCreatorRest(newpos, basicType());
2497                 } else {
2498                     return arrayCreatorRest(newpos, toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, basicType())));
2499                 }
2500             }
2501             break;
2502         default:
2503         }
2504         JCExpression t = qualident(true);
2505 
2506         int prevmode = mode;
2507         selectTypeMode();
2508         boolean diamondFound = false;
2509         int lastTypeargsPos = -1;
2510         if (token.kind == LT) {
2511             lastTypeargsPos = token.pos;
2512             t = typeArguments(t, true);
2513             diamondFound = isMode(DIAMOND);

2542             JCExpression e = arrayCreatorRest(newpos, t);
2543             if (diamondFound) {
2544                 reportSyntaxError(lastTypeargsPos, Errors.CannotCreateArrayWithDiamond);
2545                 return toP(F.at(newpos).Erroneous(List.of(e)));
2546             }
2547             else if (typeArgs != null) {
2548                 int pos = newpos;
2549                 if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) {
2550                     // note: this should always happen but we should
2551                     // not rely on this as the parser is continuously
2552                     // modified to improve error recovery.
2553                     pos = typeArgs.head.pos;
2554                 }
2555                 setErrorEndPos(S.prevToken().endPos);
2556                 JCErroneous err = F.at(pos).Erroneous(typeArgs.prepend(e));
2557                 reportSyntaxError(err, Errors.CannotCreateArrayWithTypeArguments);
2558                 return toP(err);
2559             }
2560             return e;
2561         } else if (token.kind == LPAREN) {



2562             // handle type annotations for instantiations and anonymous classes
2563             if (newAnnotations.nonEmpty()) {
2564                 t = insertAnnotationsToMostInner(t, newAnnotations, false);
2565             }
2566             return classCreatorRest(newpos, null, typeArgs, t);




2567         } else {
2568             setErrorEndPos(token.pos);
2569             reportSyntaxError(token.pos, Errors.Expected2(LPAREN, LBRACKET));
2570             t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.nil(), null));
2571             return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
2572         }
2573     }
2574 
2575     /** InnerCreator = [Annotations] Ident [TypeArguments] ClassCreatorRest
2576      */
2577     JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
2578         List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
2579 
2580         JCExpression t = toP(F.at(token.pos).Ident(ident()));
2581 
2582         if (newAnnotations.nonEmpty()) {
2583             t = toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, t));
2584         }
2585 
2586         if (token.kind == LT) {
2587             int prevmode = mode;
2588             t = typeArguments(t, true);
2589             setMode(prevmode);
2590         }
2591         return classCreatorRest(newpos, encl, typeArgs, t);
2592     }
2593 
2594     /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
2595      *                         | Expression "]" {[Annotations]  "[" Expression "]"} BracketsOpt )
2596      */
2597     JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
2598         List<JCAnnotation> annos = typeAnnotationsOpt();
2599 
2600         accept(LBRACKET);
2601         if (token.kind == RBRACKET) {
2602             accept(RBRACKET);
2603             elemtype = bracketsOpt(elemtype, annos);
2604             if (token.kind == LBRACE) {
2605                 JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
2606                 if (annos.nonEmpty()) {
2607                     // when an array initializer is present then
2608                     // the parsed annotations should target the
2609                     // new array tree
2610                     // bracketsOpt inserts the annotation in
2611                     // elemtype, and it needs to be corrected

2649             if (token.kind == LBRACE) {
2650                 elems = arrayInitializerElements(newpos, elemtype);
2651             }
2652 
2653             JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), elems));
2654             na.dimAnnotations = dimAnnotations.toList();
2655 
2656             if (elems != null) {
2657                 return syntaxError(errpos, List.of(na), Errors.IllegalArrayCreationBothDimensionAndInitialization);
2658             }
2659 
2660             return na;
2661         }
2662     }
2663 
2664     /** ClassCreatorRest = Arguments [ClassBody]
2665      */
2666     JCNewClass classCreatorRest(int newpos,
2667                                   JCExpression encl,
2668                                   List<JCExpression> typeArgs,
2669                                   JCExpression t)

2670     {
2671         List<JCExpression> args = arguments();
2672         JCClassDecl body = null;
2673         if (token.kind == LBRACE) {
2674             int pos = token.pos;
2675             List<JCTree> defs = classInterfaceOrRecordBody(names.empty, false, false);
2676             JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2677             body = toP(F.at(pos).AnonymousClassDef(mods, defs));
2678         }
2679         return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));

2680     }
2681 
2682     /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
2683      */
2684     JCExpression arrayInitializer(int newpos, JCExpression t) {
2685         List<JCExpression> elems = arrayInitializerElements(newpos, t);
2686         return toP(F.at(newpos).NewArray(t, List.nil(), elems));
2687     }
2688 
2689     List<JCExpression> arrayInitializerElements(int newpos, JCExpression t) {
2690         accept(LBRACE);
2691         ListBuffer<JCExpression> elems = new ListBuffer<>();
2692         if (token.kind == COMMA) {
2693             nextToken();
2694         } else if (token.kind != RBRACE) {
2695             elems.append(variableInitializer());
2696             while (token.kind == COMMA) {
2697                 nextToken();
2698                 if (token.kind == RBRACE) break;
2699                 elems.append(variableInitializer());

2890                     accept(SEMI);
2891                     return List.of(toP(F.at(pos).Yield(t)));
2892                 }
2893 
2894                 //else intentional fall-through
2895             } else {
2896                 if (isNonSealedClassStart(true)) {
2897                     log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2898                     nextToken();
2899                     nextToken();
2900                     nextToken();
2901                     return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.comment(CommentStyle.JAVADOC)));
2902                 } else if (isSealedClassStart(true)) {
2903                     checkSourceLevel(Feature.SEALED_CLASSES);
2904                     log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2905                     nextToken();
2906                     return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.comment(CommentStyle.JAVADOC)));
2907                 }
2908             }
2909         }




2910         if (isRecordStart() && allowRecords) {
2911             dc = token.comment(CommentStyle.JAVADOC);
2912             return List.of(recordDeclaration(F.at(pos).Modifiers(0), dc));
2913         } else {
2914             Token prevToken = token;
2915             JCExpression t = term(EXPR | TYPE);
2916             if (token.kind == COLON && t.hasTag(IDENT)) {
2917                 nextToken();
2918                 JCStatement stat = parseStatementAsBlock();
2919                 return List.of(F.at(pos).Labelled(prevToken.name(), stat));
2920             } else if (wasTypeMode() && LAX_IDENTIFIER.test(token.kind)) {
2921                 pos = token.pos;
2922                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2923                 F.at(pos);
2924                 return localVariableDeclarations(mods, t);
2925             } else {
2926                 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
2927                 t = checkExprStat(t);
2928                 accept(SEMI);
2929                 JCExpressionStatement expr = toP(F.at(pos).Exec(t));

3381             nextToken();
3382             pos = token.pos;
3383             JCExpression t = parseExpression();
3384             // This Exec is a "StatementExpression"; it subsumes no terminating token
3385             stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
3386         }
3387         return stats;
3388     }
3389 
3390     /** ForInit = StatementExpression MoreStatementExpressions
3391      *           |  { FINAL | '@' Annotation } Type VariableDeclarators
3392      */
3393     List<JCStatement> forInit() {
3394         ListBuffer<JCStatement> stats = new ListBuffer<>();
3395         int pos = token.pos;
3396         if (token.kind == FINAL || token.kind == MONKEYS_AT) {
3397             return variableDeclarators(optFinal(0), parseType(true), stats, true).toList();
3398         } else {
3399             JCExpression t = term(EXPR | TYPE);
3400             if (wasTypeMode() && LAX_IDENTIFIER.test(token.kind)) {
3401                 return variableDeclarators(modifiersOpt(), t, stats, true).toList();



3402             } else if (wasTypeMode() && token.kind == COLON) {
3403                 log.error(DiagnosticFlag.SYNTAX, pos, Errors.BadInitializer("for-loop"));
3404                 return List.of((JCStatement)F.at(pos).VarDef(modifiersOpt(), names.error, t, null));
3405             } else {
3406                 return moreStatementExpressions(pos, t, stats).toList();
3407             }
3408         }
3409     }
3410 
3411     /** ForUpdate = StatementExpression MoreStatementExpressions
3412      */
3413     List<JCExpressionStatement> forUpdate() {
3414         return moreStatementExpressions(token.pos,
3415                                         parseExpression(),
3416                                         new ListBuffer<JCExpressionStatement>()).toList();
3417     }
3418 
3419     /** AnnotationsOpt = { '@' Annotation }
3420      *
3421      * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION

3478             case ABSTRACT    : flag = Flags.ABSTRACT; break;
3479             case NATIVE      : flag = Flags.NATIVE; break;
3480             case VOLATILE    : flag = Flags.VOLATILE; break;
3481             case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
3482             case STRICTFP    : flag = Flags.STRICTFP; break;
3483             case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
3484             case DEFAULT     : flag = Flags.DEFAULT; break;
3485             case ERROR       : flag = 0; nextToken(); break;
3486             case IDENTIFIER  : {
3487                 if (isNonSealedClassStart(false)) {
3488                     flag = Flags.NON_SEALED;
3489                     nextToken();
3490                     nextToken();
3491                     break;
3492                 }
3493                 if (isSealedClassStart(false)) {
3494                     checkSourceLevel(Feature.SEALED_CLASSES);
3495                     flag = Flags.SEALED;
3496                     break;
3497                 }












3498                 break loop;
3499             }
3500             default: break loop;
3501             }
3502             if ((flags & flag) != 0) log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.RepeatedModifier);
3503             lastPos = token.pos;
3504             nextToken();
3505             if (flag == Flags.ANNOTATION) {
3506                 if (token.kind != INTERFACE) {
3507                     JCAnnotation ann = annotation(lastPos, Tag.ANNOTATION);
3508                     // if first modifier is an annotation, set pos to annotation's.
3509                     if (flags == 0 && annotations.isEmpty())
3510                         pos = ann.pos;
3511                     annotations.append(ann);
3512                     flag = 0;
3513                 }
3514             }
3515             flags |= flag;
3516         }
3517         switch (token.kind) {

3744             if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) {
3745                 return Source.JDK10;
3746             } else if (shouldWarn) {
3747                 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK10));
3748             }
3749         }
3750         if (name == names.yield) {
3751             if (allowYieldStatement) {
3752                 return Source.JDK14;
3753             } else if (shouldWarn) {
3754                 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK14));
3755             }
3756         }
3757         if (name == names.record) {
3758             if (allowRecords) {
3759                 return Source.JDK14;
3760             } else if (shouldWarn) {
3761                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK14));
3762             }
3763         }



















3764         if (name == names.sealed) {
3765             if (allowSealedTypes) {
3766                 return Source.JDK15;
3767             } else if (shouldWarn) {
3768                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3769             }
3770         }
3771         if (name == names.permits) {
3772             if (allowSealedTypes) {
3773                 return Source.JDK15;
3774             } else if (shouldWarn) {
3775                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3776             }
3777         }
3778         return null;
3779     }
3780 
3781     /** VariableDeclaratorId = Ident BracketsOpt
3782      */
3783     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean catchParameter, boolean lambdaParameter, boolean recordComponent) {

4268         mods.flags |= Flags.RECORD;
4269         Name name = typeName();
4270 
4271         List<JCTypeParameter> typarams = typeParametersOpt();
4272 
4273         List<JCVariableDecl> headerFields = formalParameters(false, true);
4274 
4275         List<JCExpression> implementing = List.nil();
4276         if (token.kind == IMPLEMENTS) {
4277             nextToken();
4278             implementing = typeList();
4279         }
4280         List<JCTree> defs = classInterfaceOrRecordBody(name, false, true);
4281         java.util.List<JCVariableDecl> fields = new ArrayList<>();
4282         for (JCVariableDecl field : headerFields) {
4283             fields.add(field);
4284         }
4285         for (JCTree def : defs) {
4286             if (def.hasTag(METHODDEF)) {
4287                 JCMethodDecl methDef = (JCMethodDecl) def;
4288                 if (methDef.name == names.init && methDef.params.isEmpty() && (methDef.mods.flags & Flags.COMPACT_RECORD_CONSTRUCTOR) != 0) {

4289                     ListBuffer<JCVariableDecl> tmpParams = new ListBuffer<>();
4290                     for (JCVariableDecl param : headerFields) {
4291                         tmpParams.add(F.at(param)
4292                                 // we will get flags plus annotations from the record component
4293                                 .VarDef(F.Modifiers(Flags.PARAMETER | Flags.GENERATED_MEMBER | Flags.MANDATED | param.mods.flags & Flags.VARARGS,
4294                                         param.mods.annotations),
4295                                 param.name, param.vartype, null));
4296                     }
4297                     methDef.params = tmpParams.toList();
4298                 }
4299             }
4300         }
4301         for (int i = fields.size() - 1; i >= 0; i--) {
4302             JCVariableDecl field = fields.get(i);
4303             defs = defs.prepend(field);
4304         }
4305         JCClassDecl result = toP(F.at(pos).ClassDef(mods, name, typarams, null, implementing, defs));
4306         attach(result, dc);
4307         return result;
4308     }

4809             Token next = S.token(3);
4810             return allowedAfterSealedOrNonSealed(next, local, true);
4811         }
4812         return false;
4813     }
4814 
4815     protected boolean isNonSealedIdentifier(Token someToken, int lookAheadOffset) {
4816         if (someToken.name() == names.non && peekToken(lookAheadOffset, TokenKind.SUB, TokenKind.IDENTIFIER)) {
4817             Token tokenSub = S.token(lookAheadOffset + 1);
4818             Token tokenSealed = S.token(lookAheadOffset + 2);
4819             if (someToken.endPos == tokenSub.pos &&
4820                     tokenSub.endPos == tokenSealed.pos &&
4821                     tokenSealed.name() == names.sealed) {
4822                 checkSourceLevel(Feature.SEALED_CLASSES);
4823                 return true;
4824             }
4825         }
4826         return false;
4827     }
4828 














































































4829     protected boolean isSealedClassStart(boolean local) {
4830         if (token.name() == names.sealed) {
4831             Token next = S.token(1);
4832             if (allowedAfterSealedOrNonSealed(next, local, false)) {
4833                 checkSourceLevel(Feature.SEALED_CLASSES);
4834                 return true;
4835             }
4836         }
4837         return false;
4838     }
4839 
4840     private boolean allowedAfterSealedOrNonSealed(Token next, boolean local, boolean currentIsNonSealed) {
4841         return local ?
4842             switch (next.kind) {
4843                 case MONKEYS_AT -> {
4844                     Token afterNext = S.token(2);
4845                     yield afterNext.kind != INTERFACE || currentIsNonSealed;
4846                 }
4847                 case ABSTRACT, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4848                 default -> false;
4849             } :
4850             switch (next.kind) {
4851                 case MONKEYS_AT -> {
4852                     Token afterNext = S.token(2);
4853                     yield afterNext.kind != INTERFACE || currentIsNonSealed;
4854                 }
4855                 case PUBLIC, PROTECTED, PRIVATE, ABSTRACT, STATIC, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4856                 case IDENTIFIER -> isNonSealedIdentifier(next, currentIsNonSealed ? 3 : 1) || next.name() == names.sealed;



4857                 default -> false;
4858             };
4859     }
4860 
4861     /** MethodDeclaratorRest =
4862      *      FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
4863      *  VoidMethodDeclaratorRest =
4864      *      FormalParameters [THROWS TypeList] ( MethodBody | ";")
4865      *  ConstructorDeclaratorRest =
4866      *      "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
4867      */
4868     protected JCTree methodDeclaratorRest(int pos,
4869                               JCModifiers mods,
4870                               JCExpression type,
4871                               Name name,
4872                               List<JCTypeParameter> typarams,
4873                               boolean isInterface, boolean isVoid,
4874                               boolean isRecord,
4875                               Comment dc) {
4876         if (isInterface) {
4877             if ((mods.flags & Flags.PRIVATE) != 0) {
4878                 checkSourceLevel(Feature.PRIVATE_INTERFACE_METHODS);
4879             }
4880         }
4881         JCVariableDecl prevReceiverParam = this.receiverParam;
4882         try {
4883             this.receiverParam = null;
4884             // Parsing formalParameters sets the receiverParam, if present
4885             List<JCVariableDecl> params = List.nil();
4886             List<JCExpression> thrown = List.nil();
4887             if (!isRecord || name != names.init || token.kind == LPAREN) {
4888                 params = formalParameters();
4889                 if (!isVoid) type = bracketsOpt(type);
4890                 if (token.kind == THROWS) {
4891                     nextToken();
4892                     thrown = qualidentList(true);
4893                 }
4894             }
4895             JCBlock body = null;
4896             JCExpression defaultValue;
4897             if (token.kind == LBRACE) {
4898                 body = block();
4899                 defaultValue = null;
4900             } else {
4901                 if (token.kind == DEFAULT) {
4902                     accept(DEFAULT);
4903                     defaultValue = annotationValue();
4904                 } else {
4905                     defaultValue = null;
4906                 }
4907                 accept(SEMI);

5323         case INT:
5324             return TypeTag.INT;
5325         case LONG:
5326             return TypeTag.LONG;
5327         case FLOAT:
5328             return TypeTag.FLOAT;
5329         case DOUBLE:
5330             return TypeTag.DOUBLE;
5331         case BOOLEAN:
5332             return TypeTag.BOOLEAN;
5333         default:
5334             return TypeTag.NONE;
5335         }
5336     }
5337 
5338     void checkSourceLevel(Feature feature) {
5339         checkSourceLevel(token.pos, feature);
5340     }
5341 
5342     protected void checkSourceLevel(int pos, Feature feature) {
5343         if (preview.isPreview(feature) && !preview.isEnabled()) {



5344             //preview feature without --preview flag, error
5345             log.error(DiagnosticFlag.SOURCE_LEVEL, pos, preview.disabledError(feature));
5346         } else if (!feature.allowedInSource(source)) {
5347             //incompatible source level, error
5348             log.error(DiagnosticFlag.SOURCE_LEVEL, pos, feature.error(source.name));
5349         } else if (preview.isPreview(feature)) {
5350             //use of preview feature, warn
5351             preview.warnPreview(pos, feature);
5352         }
5353     }
5354 
5355     /*
5356      * a functional source tree and end position mappings
5357      */
5358     protected static class SimpleEndPosTable extends AbstractEndPosTable {
5359 
5360         private final IntHashTable endPosMap;
5361 
5362         SimpleEndPosTable(JavacParser parser) {
5363             super(parser);

  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 javax.lang.model.SourceVersion;
  34 
  35 import com.sun.source.tree.CaseTree;
  36 import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
  37 import com.sun.source.tree.ModuleTree.ModuleKind;
  38 
  39 import com.sun.tools.javac.code.*;
  40 import com.sun.tools.javac.code.Flags.Flag;
  41 import com.sun.tools.javac.code.Source.Feature;
  42 import com.sun.tools.javac.file.PathFileObject;
  43 import com.sun.tools.javac.parser.Tokens.*;
  44 import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
  45 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  46 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  47 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
  48 import com.sun.tools.javac.tree.*;
  49 import com.sun.tools.javac.tree.JCTree.*;
  50 import com.sun.tools.javac.util.*;
  51 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
  52 import com.sun.tools.javac.util.JCDiagnostic.Error;
  53 import com.sun.tools.javac.util.JCDiagnostic.Fragment;
  54 import com.sun.tools.javac.util.List;
  55 
  56 import static com.sun.tools.javac.code.Flags.asFlagSet;
  57 import static com.sun.tools.javac.parser.Tokens.TokenKind.*;
  58 import static com.sun.tools.javac.parser.Tokens.TokenKind.ASSERT;
  59 import static com.sun.tools.javac.parser.Tokens.TokenKind.CASE;
  60 import static com.sun.tools.javac.parser.Tokens.TokenKind.CATCH;
  61 import static com.sun.tools.javac.parser.Tokens.TokenKind.EQ;
  62 import static com.sun.tools.javac.parser.Tokens.TokenKind.GT;
  63 import static com.sun.tools.javac.parser.Tokens.TokenKind.IMPORT;
  64 import static com.sun.tools.javac.parser.Tokens.TokenKind.LT;
  65 import static com.sun.tools.javac.parser.Tokens.TokenKind.SYNCHRONIZED;
  66 import static com.sun.tools.javac.tree.JCTree.Tag.*;
  67 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.ImplicitAndExplicitNotAllowed;
  68 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.VarAndExplicitNotAllowed;
  69 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.VarAndImplicitNotAllowed;
  70 import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
  71 
  72 /**
  73  * The parser maps a token sequence into an abstract syntax tree.
  74  * The parser is a hand-written recursive-descent parser that
  75  * implements the grammar described in the Java Language Specification.
  76  * For efficiency reasons, an operator precedence scheme is used
  77  * for parsing binary operation expressions.
  78  *
  79  *  <p><b>This is NOT part of any supported API.
  80  *  If you write code that depends on this, you do so at your own risk.
  81  *  This code and its internal interfaces are subject to change or
  82  *  deletion without notice.</b>
  83  */
  84 public class JavacParser implements Parser {
  85 

 178                      boolean keepLineMap,
 179                      boolean keepEndPositions,
 180                      boolean parseModuleInfo) {
 181         this.S = S;
 182         nextToken(); // prime the pump
 183         this.F = fac.F;
 184         this.log = fac.log;
 185         this.names = fac.names;
 186         this.source = fac.source;
 187         this.preview = fac.preview;
 188         this.allowStringFolding = fac.options.getBoolean("allowStringFolding", true);
 189         this.keepDocComments = keepDocComments;
 190         this.parseModuleInfo = parseModuleInfo;
 191         this.docComments = newDocCommentTable(keepDocComments, fac);
 192         this.keepLineMap = keepLineMap;
 193         this.errorTree = F.Erroneous();
 194         this.endPosTable = newEndPosTable(keepEndPositions);
 195         this.allowYieldStatement = Feature.SWITCH_EXPRESSION.allowedInSource(source);
 196         this.allowRecords = Feature.RECORDS.allowedInSource(source);
 197         this.allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);
 198         this.allowPrimitiveClasses = Feature.PRIMITIVE_CLASSES.allowedInSource(source) && fac.options.isSet("enablePrimitiveClasses");
 199         this.allowValueClasses = Feature.VALUE_CLASSES.allowedInSource(source);
 200     }
 201 
 202     /** Construct a parser from an existing parser, with minimal overhead.
 203      */
 204     @SuppressWarnings("this-escape")
 205     protected JavacParser(JavacParser parser,
 206                           Lexer S) {
 207         this.S = S;
 208         this.token = parser.token;
 209         this.F = parser.F;
 210         this.log = parser.log;
 211         this.names = parser.names;
 212         this.source = parser.source;
 213         this.preview = parser.preview;
 214         this.allowStringFolding = parser.allowStringFolding;
 215         this.keepDocComments = false;
 216         this.parseModuleInfo = false;
 217         this.docComments = null;
 218         this.errorTree = F.Erroneous();
 219         this.endPosTable = newEndPosTable(false);
 220         this.allowYieldStatement = Feature.SWITCH_EXPRESSION.allowedInSource(source);
 221         this.allowRecords = Feature.RECORDS.allowedInSource(source);
 222         this.allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);
 223         this.allowPrimitiveClasses = parser.allowPrimitiveClasses;
 224         this.allowValueClasses = parser.allowValueClasses;
 225     }
 226 
 227     protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) {
 228         return  keepEndPositions
 229                 ? new SimpleEndPosTable(this)
 230                 : new EmptyEndPosTable(this);
 231     }
 232 
 233     protected DocCommentTable newDocCommentTable(boolean keepDocComments, ParserFactory fac) {
 234         return keepDocComments ? new LazyDocCommentTable(fac) : null;
 235     }
 236 
 237     /** Switch: should we fold strings?
 238      */
 239     boolean allowStringFolding;
 240 
 241     /** Switch: should we keep docComments?
 242      */
 243     boolean keepDocComments;
 244 
 245     /** Switch: should we keep line table?
 246      */
 247     boolean keepLineMap;
 248 
 249     /** Switch: is "this" allowed as an identifier?
 250      * This is needed to parse receiver types.
 251      */
 252     boolean allowThisIdent;
 253 
 254     /** Switch: is yield statement allowed in this source level?
 255      */
 256     boolean allowYieldStatement;
 257 
 258     /** Switch: are records allowed in this source level?
 259      */
 260     boolean allowRecords;
 261 
 262     /** Switch: are primitive classes allowed in this source level?
 263      */
 264      boolean allowPrimitiveClasses;
 265 
 266     /** Switch: are value classes allowed in this source level?
 267      */
 268     boolean allowValueClasses;
 269 
 270     /** Switch: are sealed types allowed in this source level?
 271      */
 272     boolean allowSealedTypes;
 273 
 274     /** The type of the method receiver, as specified by a first "this" parameter.
 275      */
 276     JCVariableDecl receiverParam;
 277 
 278     /** When terms are parsed, the mode determines which is expected:
 279      *     mode = EXPR        : an expression
 280      *     mode = TYPE        : a type
 281      *     mode = NOPARAMS    : no parameters allowed for type
 282      *     mode = TYPEARG     : type argument
 283      *     mode |= NOLAMBDA   : lambdas are not allowed
 284      */
 285     protected static final int EXPR          = 1 << 0;
 286     protected static final int TYPE          = 1 << 1;
 287     protected static final int NOPARAMS      = 1 << 2;
 288     protected static final int TYPEARG       = 1 << 3;
 289     protected static final int DIAMOND       = 1 << 4;

 513 
 514     /** If next input token matches given token, skip it, otherwise report
 515      *  an error.
 516      */
 517     public void accept(TokenKind tk) {
 518         accept(tk, Errors::Expected);
 519     }
 520 
 521     /** If next input token matches given token, skip it, otherwise report
 522      *  an error.
 523      */
 524     public void accept(TokenKind tk, Function<TokenKind, Error> errorProvider) {
 525         if (token.kind == tk) {
 526             nextToken();
 527         } else {
 528             setErrorEndPos(token.pos);
 529             reportSyntaxError(S.prevToken().endPos, errorProvider.apply(tk));
 530         }
 531     }
 532 
 533     /** If next input token matches one of the two given tokens, skip it, otherwise report
 534      *  an error.
 535      *
 536      * @return The actual token kind.
 537      */
 538     public TokenKind accept2(TokenKind tk1, TokenKind tk2) {
 539         TokenKind returnValue = token.kind;
 540         if (token.kind == tk1 || token.kind == tk2) {
 541             nextToken();
 542         } else {
 543             setErrorEndPos(token.pos);
 544             reportSyntaxError(S.prevToken().endPos, Errors.Expected2(tk1, tk2));
 545         }
 546         return returnValue;
 547     }
 548 
 549     /** Report an illegal start of expression/type error at given position.
 550      */
 551     JCExpression illegal(int pos) {
 552         setErrorEndPos(pos);
 553         if (isMode(EXPR))
 554             return syntaxError(pos, Errors.IllegalStartOfExpr);
 555         else
 556             return syntaxError(pos, Errors.IllegalStartOfType);
 557 
 558     }
 559 
 560     /** Report an illegal start of expression/type error at current position.
 561      */
 562     JCExpression illegal() {
 563         return illegal(token.pos);
 564     }
 565 
 566     /** Diagnose a modifier flag from the set, if any. */
 567     protected void checkNoMods(long mods) {
 568         checkNoMods(token.pos, mods);

1519                         break loop;
1520                     case LPAREN:
1521                         if (isMode(EXPR)) {
1522                             selectExprMode();
1523                             t = arguments(typeArgs, t);
1524                             if (!annos.isEmpty()) t = illegal(annos.head.pos);
1525                             typeArgs = null;
1526                         }
1527                         break loop;
1528                     case DOT:
1529                         nextToken();
1530                         if (token.kind == TokenKind.IDENTIFIER && typeArgs != null) {
1531                             return illegal();
1532                         }
1533                         int prevmode = mode;
1534                         setMode(mode & ~NOPARAMS);
1535                         typeArgs = typeArgumentsOpt(EXPR);
1536                         setMode(prevmode);
1537                         if (isMode(EXPR)) {
1538                             switch (token.kind) {
1539                             case DEFAULT:
1540                                 if (typeArgs != null) return illegal();
1541                                 selectExprMode();
1542                                 t = to(F.at(pos).DefaultValue(t));
1543                                 nextToken();
1544                                 break loop;
1545                             case CLASS:
1546                                 if (typeArgs != null) return illegal();
1547                                 selectExprMode();
1548                                 t = to(F.at(pos).Select(t, names._class));
1549                                 nextToken();
1550                                 break loop;
1551                             case THIS:
1552                                 if (typeArgs != null) return illegal();
1553                                 selectExprMode();
1554                                 t = to(F.at(pos).Select(t, names._this));
1555                                 nextToken();
1556                                 break loop;
1557                             case SUPER:
1558                                 selectExprMode();
1559                                 t = to(F.at(pos).Select(t, names._super));
1560                                 t = superSuffix(typeArgs, t);
1561                                 typeArgs = null;
1562                                 break loop;
1563                             case NEW:
1564                                 if (typeArgs != null) return illegal();

1588                             token.kind == MONKEYS_AT) {
1589                             //error recovery, case like:
1590                             //int i = expr.<missing-ident>
1591                             //@Deprecated
1592                             if (typeArgs != null) illegal();
1593                             return toP(t);
1594                         }
1595                         if (tyannos != null && tyannos.nonEmpty()) {
1596                             t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
1597                         }
1598                         break;
1599                     case ELLIPSIS:
1600                         if (this.permitTypeAnnotationsPushBack) {
1601                             this.typeAnnotationsPushedBack = annos;
1602                         } else if (annos.nonEmpty()) {
1603                             // Don't return here -- error recovery attempt
1604                             illegal(annos.head.pos);
1605                         }
1606                         break loop;
1607                     case LT:
1608                         if (!isMode(TYPE) && isParameterizedTypePrefix()) {
1609                             //this is either an unbound method reference whose qualifier
1610                             //is a generic type i.e. A<S>::m or a default value creation of
1611                             //the form ValueType<S>.default
1612                             int pos1 = token.pos;
1613                             accept(LT);
1614                             ListBuffer<JCExpression> args = new ListBuffer<>();
1615                             args.append(typeArgument());
1616                             while (token.kind == COMMA) {
1617                                 nextToken();
1618                                 args.append(typeArgument());
1619                             }
1620                             accept(GT);
1621                             t = toP(F.at(pos1).TypeApply(t, args.toList()));
1622                             while (token.kind == DOT) {
1623                                 nextToken();
1624                                 if (token.kind == DEFAULT) {
1625                                     t =  toP(F.at(token.pos).DefaultValue(t));
1626                                     nextToken();
1627                                     selectExprMode();
1628                                     return term3Rest(t, typeArgs);
1629                                 }
1630                                 selectTypeMode();
1631                                 t = toP(F.at(token.pos).Select(t, ident()));
1632                                 t = typeArgumentsOpt(t);
1633                             }
1634                             t = bracketsOpt(t);
1635                             if (token.kind != COLCOL) {
1636                                 //method reference expected here
1637                                 t = illegal();
1638                             }
1639                             selectExprMode();
1640                             return term3Rest(t, typeArgs);
1641                         }
1642                         break loop;
1643                     default:
1644                         break loop;
1645                     }
1646                 }
1647             }
1648             if (typeArgs != null) illegal();
1649             t = typeArgumentsOpt(t);

1840                 if (!annos.isEmpty()) {
1841                     if (permitTypeAnnotationsPushBack)
1842                         typeAnnotationsPushedBack = annos;
1843                     else
1844                         return illegal(annos.head.pos);
1845                 }
1846                 break;
1847             }
1848         }
1849         while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && isMode(EXPR)) {
1850             selectExprMode();
1851             t = to(F.at(token.pos).Unary(
1852                   token.kind == PLUSPLUS ? POSTINC : POSTDEC, t));
1853             nextToken();
1854         }
1855         return toP(t);
1856     }
1857 
1858     /**
1859      * If we see an identifier followed by a '&lt;' it could be an unbound
1860      * method reference or a default value creation that uses a parameterized type
1861      * or a binary expression. To disambiguate, look for a
1862      * matching '&gt;' and see if the subsequent terminal is either '.' or '::'.
1863      */
1864     @SuppressWarnings("fallthrough")
1865     boolean isParameterizedTypePrefix() {
1866         int pos = 0, depth = 0;
1867         outer: for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
1868             switch (t.kind) {
1869                 case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
1870                 case DOT: case RBRACKET: case LBRACKET: case COMMA:
1871                 case BYTE: case SHORT: case INT: case LONG: case FLOAT:
1872                 case DOUBLE: case BOOLEAN: case CHAR:
1873                 case MONKEYS_AT:
1874                     break;
1875 
1876                 case LPAREN:
1877                     // skip annotation values
1878                     int nesting = 0;
1879                     for (; ; pos++) {
1880                         TokenKind tk2 = S.token(pos).kind;
1881                         switch (tk2) {
1882                             case EOF:
1883                                 return false;
1884                             case LPAREN:
1885                                 nesting++;

2452 
2453     private JCExpression bracketsOptCont(JCExpression t, int pos,
2454             List<JCAnnotation> annotations) {
2455         accept(RBRACKET);
2456         t = bracketsOpt(t);
2457         t = toP(F.at(pos).TypeArray(t));
2458         if (annotations.nonEmpty()) {
2459             t = toP(F.at(pos).AnnotatedType(annotations, t));
2460         }
2461         return t;
2462     }
2463 
2464     /** BracketsSuffixExpr = "." CLASS
2465      *  BracketsSuffixType =
2466      */
2467     JCExpression bracketsSuffix(JCExpression t) {
2468         if (isMode(EXPR) && token.kind == DOT) {
2469             selectExprMode();
2470             int pos = token.pos;
2471             nextToken();
2472             TokenKind selector = accept2(CLASS, DEFAULT);
2473             if (token.pos == endPosTable.errorEndPos) {
2474                 // error recovery
2475                 Name name;
2476                 if (LAX_IDENTIFIER.test(token.kind)) {
2477                     name = token.name();
2478                     nextToken();
2479                 } else {
2480                     name = names.error;
2481                 }
2482                 t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name))));
2483             } else {
2484                 Tag tag = t.getTag();
2485                 // Type annotations are illegal on class literals. Annotated non array class literals
2486                 // are complained about directly in term3(), Here check for type annotations on dimensions
2487                 // taking care to handle some interior dimension(s) being annotated.
2488                 if ((tag == TYPEARRAY && TreeInfo.containsTypeAnnotation(t)) || tag == ANNOTATED_TYPE)
2489                     syntaxError(token.pos, Errors.NoAnnotationsOnDotClass);
2490                 if (selector == CLASS) {
2491                     t = toP(F.at(pos).Select(t, names._class));
2492                 } else {
2493                     t = toP(F.at(pos).DefaultValue(t));
2494                 }
2495             }
2496         } else if (isMode(TYPE)) {
2497             if (token.kind != COLCOL) {
2498                 selectTypeMode();
2499             }
2500         } else if (token.kind != COLCOL) {
2501             syntaxError(token.pos, Errors.DotClassExpected);
2502         }
2503         return t;
2504     }
2505 
2506     /**
2507      * MemberReferenceSuffix = "::" [TypeArguments] Ident
2508      *                       | "::" [TypeArguments] "new"
2509      */
2510     JCExpression memberReferenceSuffix(JCExpression t) {
2511         int pos1 = token.pos;
2512         accept(COLCOL);
2513         return memberReferenceSuffix(pos1, t);
2514     }
2515 
2516     JCExpression memberReferenceSuffix(int pos1, JCExpression t) {
2517         selectExprMode();
2518         List<JCExpression> typeArgs = null;
2519         if (token.kind == LT) {
2520             typeArgs = typeArguments(false);
2521         }
2522         Name refName;
2523         ReferenceMode refMode;
2524         if (token.kind == NEW) {
2525             refMode = ReferenceMode.NEW;
2526             // TODO - will be converted in Attr
2527             refName = names.init;
2528             nextToken();
2529         } else {
2530             refMode = ReferenceMode.INVOKE;
2531             refName = ident();
2532         }
2533         return toP(F.at(t.getStartPosition()).Reference(refMode, refName, t, typeArgs));
2534     }
2535 
2536     /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
2537      */
2538     JCExpression creator(int newpos, List<JCExpression> typeArgs) {
2539         final JCModifiers mods = modifiersOpt();
2540         List<JCAnnotation> newAnnotations = mods.annotations;
2541         switch (token.kind) {
2542         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
2543         case DOUBLE: case BOOLEAN:
2544             if (mods.flags != 0) {
2545                 log.error(token.pos, Errors.ModNotAllowedHere(asFlagSet(mods.flags)));
2546             }
2547             if (typeArgs == null) {
2548                 if (newAnnotations.isEmpty()) {
2549                     return arrayCreatorRest(newpos, basicType());
2550                 } else {
2551                     return arrayCreatorRest(newpos, toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, basicType())));
2552                 }
2553             }
2554             break;
2555         default:
2556         }
2557         JCExpression t = qualident(true);
2558 
2559         int prevmode = mode;
2560         selectTypeMode();
2561         boolean diamondFound = false;
2562         int lastTypeargsPos = -1;
2563         if (token.kind == LT) {
2564             lastTypeargsPos = token.pos;
2565             t = typeArguments(t, true);
2566             diamondFound = isMode(DIAMOND);

2595             JCExpression e = arrayCreatorRest(newpos, t);
2596             if (diamondFound) {
2597                 reportSyntaxError(lastTypeargsPos, Errors.CannotCreateArrayWithDiamond);
2598                 return toP(F.at(newpos).Erroneous(List.of(e)));
2599             }
2600             else if (typeArgs != null) {
2601                 int pos = newpos;
2602                 if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) {
2603                     // note: this should always happen but we should
2604                     // not rely on this as the parser is continuously
2605                     // modified to improve error recovery.
2606                     pos = typeArgs.head.pos;
2607                 }
2608                 setErrorEndPos(S.prevToken().endPos);
2609                 JCErroneous err = F.at(pos).Erroneous(typeArgs.prepend(e));
2610                 reportSyntaxError(err, Errors.CannotCreateArrayWithTypeArguments);
2611                 return toP(err);
2612             }
2613             return e;
2614         } else if (token.kind == LPAREN) {
2615             long badModifiers = mods.flags & ~(Flags.PRIMITIVE_CLASS | Flags.VALUE_CLASS | Flags.FINAL);
2616             if (badModifiers != 0)
2617                 log.error(token.pos, Errors.ModNotAllowedHere(asFlagSet(badModifiers)));
2618             // handle type annotations for instantiations and anonymous classes
2619             if (newAnnotations.nonEmpty()) {
2620                 t = insertAnnotationsToMostInner(t, newAnnotations, false);
2621             }
2622             JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t, mods.flags);
2623             if ((newClass.def == null) && (mods.flags != 0)) {
2624                 log.error(newClass.pos, Errors.ModNotAllowedHere(asFlagSet(mods.flags)));
2625             }
2626             return newClass;
2627         } else {
2628             setErrorEndPos(token.pos);
2629             reportSyntaxError(token.pos, Errors.Expected2(LPAREN, LBRACKET));
2630             t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.nil(), null));
2631             return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
2632         }
2633     }
2634 
2635     /** InnerCreator = [Annotations] Ident [TypeArguments] ClassCreatorRest
2636      */
2637     JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
2638         List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
2639 
2640         JCExpression t = toP(F.at(token.pos).Ident(ident()));
2641 
2642         if (newAnnotations.nonEmpty()) {
2643             t = toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, t));
2644         }
2645 
2646         if (token.kind == LT) {
2647             int prevmode = mode;
2648             t = typeArguments(t, true);
2649             setMode(prevmode);
2650         }
2651         return classCreatorRest(newpos, encl, typeArgs, t, 0);
2652     }
2653 
2654     /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
2655      *                         | Expression "]" {[Annotations]  "[" Expression "]"} BracketsOpt )
2656      */
2657     JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
2658         List<JCAnnotation> annos = typeAnnotationsOpt();
2659 
2660         accept(LBRACKET);
2661         if (token.kind == RBRACKET) {
2662             accept(RBRACKET);
2663             elemtype = bracketsOpt(elemtype, annos);
2664             if (token.kind == LBRACE) {
2665                 JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
2666                 if (annos.nonEmpty()) {
2667                     // when an array initializer is present then
2668                     // the parsed annotations should target the
2669                     // new array tree
2670                     // bracketsOpt inserts the annotation in
2671                     // elemtype, and it needs to be corrected

2709             if (token.kind == LBRACE) {
2710                 elems = arrayInitializerElements(newpos, elemtype);
2711             }
2712 
2713             JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), elems));
2714             na.dimAnnotations = dimAnnotations.toList();
2715 
2716             if (elems != null) {
2717                 return syntaxError(errpos, List.of(na), Errors.IllegalArrayCreationBothDimensionAndInitialization);
2718             }
2719 
2720             return na;
2721         }
2722     }
2723 
2724     /** ClassCreatorRest = Arguments [ClassBody]
2725      */
2726     JCNewClass classCreatorRest(int newpos,
2727                                   JCExpression encl,
2728                                   List<JCExpression> typeArgs,
2729                                   JCExpression t,
2730                                   long flags)
2731     {
2732         List<JCExpression> args = arguments();
2733         JCClassDecl body = null;
2734         if (token.kind == LBRACE) {
2735             int pos = token.pos;
2736             List<JCTree> defs = classInterfaceOrRecordBody(names.empty, false, false);
2737             JCModifiers mods = F.at(Position.NOPOS).Modifiers(flags);
2738             body = toP(F.at(pos).AnonymousClassDef(mods, defs));
2739         }
2740         JCNewClass newClass = toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
2741         return newClass;
2742     }
2743 
2744     /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
2745      */
2746     JCExpression arrayInitializer(int newpos, JCExpression t) {
2747         List<JCExpression> elems = arrayInitializerElements(newpos, t);
2748         return toP(F.at(newpos).NewArray(t, List.nil(), elems));
2749     }
2750 
2751     List<JCExpression> arrayInitializerElements(int newpos, JCExpression t) {
2752         accept(LBRACE);
2753         ListBuffer<JCExpression> elems = new ListBuffer<>();
2754         if (token.kind == COMMA) {
2755             nextToken();
2756         } else if (token.kind != RBRACE) {
2757             elems.append(variableInitializer());
2758             while (token.kind == COMMA) {
2759                 nextToken();
2760                 if (token.kind == RBRACE) break;
2761                 elems.append(variableInitializer());

2952                     accept(SEMI);
2953                     return List.of(toP(F.at(pos).Yield(t)));
2954                 }
2955 
2956                 //else intentional fall-through
2957             } else {
2958                 if (isNonSealedClassStart(true)) {
2959                     log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2960                     nextToken();
2961                     nextToken();
2962                     nextToken();
2963                     return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.comment(CommentStyle.JAVADOC)));
2964                 } else if (isSealedClassStart(true)) {
2965                     checkSourceLevel(Feature.SEALED_CLASSES);
2966                     log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2967                     nextToken();
2968                     return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.comment(CommentStyle.JAVADOC)));
2969                 }
2970             }
2971         }
2972         if ((isPrimitiveModifier() && allowPrimitiveClasses) || (isValueModifier() || isIdentityModifier()) && allowValueClasses) {
2973             dc = token.comment(CommentStyle.JAVADOC);
2974             return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
2975         }
2976         if (isRecordStart() && allowRecords) {
2977             dc = token.comment(CommentStyle.JAVADOC);
2978             return List.of(recordDeclaration(F.at(pos).Modifiers(0), dc));
2979         } else {
2980             Token prevToken = token;
2981             JCExpression t = term(EXPR | TYPE);
2982             if (token.kind == COLON && t.hasTag(IDENT)) {
2983                 nextToken();
2984                 JCStatement stat = parseStatementAsBlock();
2985                 return List.of(F.at(pos).Labelled(prevToken.name(), stat));
2986             } else if (wasTypeMode() && LAX_IDENTIFIER.test(token.kind)) {
2987                 pos = token.pos;
2988                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2989                 F.at(pos);
2990                 return localVariableDeclarations(mods, t);
2991             } else {
2992                 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
2993                 t = checkExprStat(t);
2994                 accept(SEMI);
2995                 JCExpressionStatement expr = toP(F.at(pos).Exec(t));

3447             nextToken();
3448             pos = token.pos;
3449             JCExpression t = parseExpression();
3450             // This Exec is a "StatementExpression"; it subsumes no terminating token
3451             stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
3452         }
3453         return stats;
3454     }
3455 
3456     /** ForInit = StatementExpression MoreStatementExpressions
3457      *           |  { FINAL | '@' Annotation } Type VariableDeclarators
3458      */
3459     List<JCStatement> forInit() {
3460         ListBuffer<JCStatement> stats = new ListBuffer<>();
3461         int pos = token.pos;
3462         if (token.kind == FINAL || token.kind == MONKEYS_AT) {
3463             return variableDeclarators(optFinal(0), parseType(true), stats, true).toList();
3464         } else {
3465             JCExpression t = term(EXPR | TYPE);
3466             if (wasTypeMode() && LAX_IDENTIFIER.test(token.kind)) {
3467                 pos = token.pos;
3468                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
3469                 F.at(pos);
3470                 return variableDeclarators(mods, t, stats, true).toList();
3471             } else if (wasTypeMode() && token.kind == COLON) {
3472                 log.error(DiagnosticFlag.SYNTAX, pos, Errors.BadInitializer("for-loop"));
3473                 return List.of((JCStatement)F.at(pos).VarDef(modifiersOpt(), names.error, t, null));
3474             } else {
3475                 return moreStatementExpressions(pos, t, stats).toList();
3476             }
3477         }
3478     }
3479 
3480     /** ForUpdate = StatementExpression MoreStatementExpressions
3481      */
3482     List<JCExpressionStatement> forUpdate() {
3483         return moreStatementExpressions(token.pos,
3484                                         parseExpression(),
3485                                         new ListBuffer<JCExpressionStatement>()).toList();
3486     }
3487 
3488     /** AnnotationsOpt = { '@' Annotation }
3489      *
3490      * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION

3547             case ABSTRACT    : flag = Flags.ABSTRACT; break;
3548             case NATIVE      : flag = Flags.NATIVE; break;
3549             case VOLATILE    : flag = Flags.VOLATILE; break;
3550             case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
3551             case STRICTFP    : flag = Flags.STRICTFP; break;
3552             case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
3553             case DEFAULT     : flag = Flags.DEFAULT; break;
3554             case ERROR       : flag = 0; nextToken(); break;
3555             case IDENTIFIER  : {
3556                 if (isNonSealedClassStart(false)) {
3557                     flag = Flags.NON_SEALED;
3558                     nextToken();
3559                     nextToken();
3560                     break;
3561                 }
3562                 if (isSealedClassStart(false)) {
3563                     checkSourceLevel(Feature.SEALED_CLASSES);
3564                     flag = Flags.SEALED;
3565                     break;
3566                 }
3567                 if (isPrimitiveModifier()) {
3568                     flag = Flags.PRIMITIVE_CLASS;
3569                     break;
3570                 }
3571                 if (isValueModifier()) {
3572                     flag = Flags.VALUE_CLASS;
3573                     break;
3574                 }
3575                 if (isIdentityModifier()) {
3576                     flag = Flags.IDENTITY_TYPE;
3577                     break;
3578                 }
3579                 break loop;
3580             }
3581             default: break loop;
3582             }
3583             if ((flags & flag) != 0) log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.RepeatedModifier);
3584             lastPos = token.pos;
3585             nextToken();
3586             if (flag == Flags.ANNOTATION) {
3587                 if (token.kind != INTERFACE) {
3588                     JCAnnotation ann = annotation(lastPos, Tag.ANNOTATION);
3589                     // if first modifier is an annotation, set pos to annotation's.
3590                     if (flags == 0 && annotations.isEmpty())
3591                         pos = ann.pos;
3592                     annotations.append(ann);
3593                     flag = 0;
3594                 }
3595             }
3596             flags |= flag;
3597         }
3598         switch (token.kind) {

3825             if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) {
3826                 return Source.JDK10;
3827             } else if (shouldWarn) {
3828                 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK10));
3829             }
3830         }
3831         if (name == names.yield) {
3832             if (allowYieldStatement) {
3833                 return Source.JDK14;
3834             } else if (shouldWarn) {
3835                 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK14));
3836             }
3837         }
3838         if (name == names.record) {
3839             if (allowRecords) {
3840                 return Source.JDK14;
3841             } else if (shouldWarn) {
3842                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK14));
3843             }
3844         }
3845         if (name == names.primitive) {
3846             if (allowPrimitiveClasses) {
3847                 return Source.JDK18;
3848             }
3849         }
3850         if (name == names.value) {
3851             if (allowValueClasses) {
3852                 return Source.JDK18;
3853             } else if (shouldWarn) {
3854                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK18));
3855             }
3856         }
3857         if (name == names.identity) {
3858             if (allowPrimitiveClasses) {
3859                 return Source.JDK18;
3860             } else if (shouldWarn) {
3861                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK18));
3862             }
3863         }
3864         if (name == names.sealed) {
3865             if (allowSealedTypes) {
3866                 return Source.JDK15;
3867             } else if (shouldWarn) {
3868                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3869             }
3870         }
3871         if (name == names.permits) {
3872             if (allowSealedTypes) {
3873                 return Source.JDK15;
3874             } else if (shouldWarn) {
3875                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3876             }
3877         }
3878         return null;
3879     }
3880 
3881     /** VariableDeclaratorId = Ident BracketsOpt
3882      */
3883     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean catchParameter, boolean lambdaParameter, boolean recordComponent) {

4368         mods.flags |= Flags.RECORD;
4369         Name name = typeName();
4370 
4371         List<JCTypeParameter> typarams = typeParametersOpt();
4372 
4373         List<JCVariableDecl> headerFields = formalParameters(false, true);
4374 
4375         List<JCExpression> implementing = List.nil();
4376         if (token.kind == IMPLEMENTS) {
4377             nextToken();
4378             implementing = typeList();
4379         }
4380         List<JCTree> defs = classInterfaceOrRecordBody(name, false, true);
4381         java.util.List<JCVariableDecl> fields = new ArrayList<>();
4382         for (JCVariableDecl field : headerFields) {
4383             fields.add(field);
4384         }
4385         for (JCTree def : defs) {
4386             if (def.hasTag(METHODDEF)) {
4387                 JCMethodDecl methDef = (JCMethodDecl) def;
4388                 // TODO - specifically for record.
4389                 if (names.isInitOrVNew(methDef.name) && methDef.params.isEmpty() && (methDef.mods.flags & Flags.COMPACT_RECORD_CONSTRUCTOR) != 0) {
4390                     ListBuffer<JCVariableDecl> tmpParams = new ListBuffer<>();
4391                     for (JCVariableDecl param : headerFields) {
4392                         tmpParams.add(F.at(param)
4393                                 // we will get flags plus annotations from the record component
4394                                 .VarDef(F.Modifiers(Flags.PARAMETER | Flags.GENERATED_MEMBER | Flags.MANDATED | param.mods.flags & Flags.VARARGS,
4395                                         param.mods.annotations),
4396                                 param.name, param.vartype, null));
4397                     }
4398                     methDef.params = tmpParams.toList();
4399                 }
4400             }
4401         }
4402         for (int i = fields.size() - 1; i >= 0; i--) {
4403             JCVariableDecl field = fields.get(i);
4404             defs = defs.prepend(field);
4405         }
4406         JCClassDecl result = toP(F.at(pos).ClassDef(mods, name, typarams, null, implementing, defs));
4407         attach(result, dc);
4408         return result;
4409     }

4910             Token next = S.token(3);
4911             return allowedAfterSealedOrNonSealed(next, local, true);
4912         }
4913         return false;
4914     }
4915 
4916     protected boolean isNonSealedIdentifier(Token someToken, int lookAheadOffset) {
4917         if (someToken.name() == names.non && peekToken(lookAheadOffset, TokenKind.SUB, TokenKind.IDENTIFIER)) {
4918             Token tokenSub = S.token(lookAheadOffset + 1);
4919             Token tokenSealed = S.token(lookAheadOffset + 2);
4920             if (someToken.endPos == tokenSub.pos &&
4921                     tokenSub.endPos == tokenSealed.pos &&
4922                     tokenSealed.name() == names.sealed) {
4923                 checkSourceLevel(Feature.SEALED_CLASSES);
4924                 return true;
4925             }
4926         }
4927         return false;
4928     }
4929 
4930     protected boolean isPrimitiveModifier() {
4931         if (token.kind == IDENTIFIER && token.name() == names.primitive) {
4932             boolean isPrimitiveModifier = false;
4933             Token next = S.token(1);
4934             switch (next.kind) {
4935                 case PRIVATE: case PROTECTED: case PUBLIC: case STATIC: case TRANSIENT:
4936                 case FINAL: case ABSTRACT: case NATIVE: case VOLATILE: case SYNCHRONIZED:
4937                 case STRICTFP: case MONKEYS_AT: case DEFAULT: case BYTE: case SHORT:
4938                 case CHAR: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
4939                 case CLASS: case INTERFACE: case ENUM:
4940                     isPrimitiveModifier = true;
4941                     break;
4942                 case IDENTIFIER: // primitive record R || primitive primitive || primitive identity || primitive value || new primitive Comparable() {}
4943                     if (next.name() == names.record || next.name() == names.primitive || next.name() == names.identity
4944                             || next.name() == names.value || (mode & EXPR) != 0)
4945                         isPrimitiveModifier = true;
4946                     break;
4947             }
4948             if (isPrimitiveModifier) {
4949                 checkSourceLevel(Feature.PRIMITIVE_CLASSES);
4950                 return true;
4951             }
4952         }
4953         return false;
4954     }
4955 
4956     protected boolean isValueModifier() {
4957         if (token.kind == IDENTIFIER && token.name() == names.value) {
4958             boolean isValueModifier = false;
4959             Token next = S.token(1);
4960             switch (next.kind) {
4961                 case PRIVATE: case PROTECTED: case PUBLIC: case STATIC: case TRANSIENT:
4962                 case FINAL: case ABSTRACT: case NATIVE: case VOLATILE: case SYNCHRONIZED:
4963                 case STRICTFP: case MONKEYS_AT: case DEFAULT: case BYTE: case SHORT:
4964                 case CHAR: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
4965                 case CLASS: case INTERFACE: case ENUM:
4966                     isValueModifier = true;
4967                     break;
4968                 case IDENTIFIER: // value record R || value value || value identity || value primitive || new value Comparable() {} ??
4969                     if (next.name() == names.record || next.name() == names.value || next.name() == names.identity
4970                             || next.name() == names.primitive || (mode & EXPR) != 0)
4971                         isValueModifier = true;
4972                     break;
4973             }
4974             if (isValueModifier) {
4975                 checkSourceLevel(Feature.VALUE_CLASSES);
4976                 return true;
4977             }
4978         }
4979         return false;
4980     }
4981 
4982     protected boolean isIdentityModifier() {
4983         if (token.kind == IDENTIFIER && token.name() == names.identity) {
4984             boolean isIdentityModifier = false;
4985             Token next = S.token(1);
4986             switch (next.kind) {
4987                 case PRIVATE: case PROTECTED: case PUBLIC: case STATIC: case TRANSIENT:
4988                 case FINAL: case ABSTRACT: case NATIVE: case VOLATILE: case SYNCHRONIZED:
4989                 case STRICTFP: case MONKEYS_AT: case DEFAULT: case BYTE: case SHORT:
4990                 case CHAR: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
4991                 case CLASS: case INTERFACE: case ENUM:
4992                     isIdentityModifier = true;
4993                     break;
4994                 case IDENTIFIER: // identity record R || identity primitive || || identity identity || identity value || new identity Comparable() {}
4995                     if (next.name() == names.record || next.name() == names.primitive || next.name() == names.identity
4996                             || next.name() == names.value || (mode & EXPR) != 0)
4997                         isIdentityModifier = true;
4998                     break;
4999             }
5000             if (isIdentityModifier) {
5001                 checkSourceLevel(Feature.VALUE_CLASSES);
5002                 return true;
5003             }
5004         }
5005         return false;
5006     }
5007 
5008     protected boolean isSealedClassStart(boolean local) {
5009         if (token.name() == names.sealed) {
5010             Token next = S.token(1);
5011             if (allowedAfterSealedOrNonSealed(next, local, false)) {
5012                 checkSourceLevel(Feature.SEALED_CLASSES);
5013                 return true;
5014             }
5015         }
5016         return false;
5017     }
5018 
5019     private boolean allowedAfterSealedOrNonSealed(Token next, boolean local, boolean currentIsNonSealed) {
5020         return local ?
5021             switch (next.kind) {
5022                 case MONKEYS_AT -> {
5023                     Token afterNext = S.token(2);
5024                     yield afterNext.kind != INTERFACE || currentIsNonSealed;
5025                 }
5026                 case ABSTRACT, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
5027                 default -> false;
5028             } :
5029             switch (next.kind) {
5030                 case MONKEYS_AT -> {
5031                     Token afterNext = S.token(2);
5032                     yield afterNext.kind != INTERFACE || currentIsNonSealed;
5033                 }
5034                 case PUBLIC, PROTECTED, PRIVATE, ABSTRACT, STATIC, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
5035                 case IDENTIFIER -> isNonSealedIdentifier(next, currentIsNonSealed ? 3 : 1) ||
5036                         next.name() == names.sealed ||
5037                         next.name() == names.value ||
5038                         next.name() == names.identity;
5039                 default -> false;
5040             };
5041     }
5042 
5043     /** MethodDeclaratorRest =
5044      *      FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
5045      *  VoidMethodDeclaratorRest =
5046      *      FormalParameters [THROWS TypeList] ( MethodBody | ";")
5047      *  ConstructorDeclaratorRest =
5048      *      "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
5049      */
5050     protected JCTree methodDeclaratorRest(int pos,
5051                               JCModifiers mods,
5052                               JCExpression type,
5053                               Name name,
5054                               List<JCTypeParameter> typarams,
5055                               boolean isInterface, boolean isVoid,
5056                               boolean isRecord,
5057                               Comment dc) {
5058         if (isInterface) {
5059             if ((mods.flags & Flags.PRIVATE) != 0) {
5060                 checkSourceLevel(Feature.PRIVATE_INTERFACE_METHODS);
5061             }
5062         }
5063         JCVariableDecl prevReceiverParam = this.receiverParam;
5064         try {
5065             this.receiverParam = null;
5066             // Parsing formalParameters sets the receiverParam, if present
5067             List<JCVariableDecl> params = List.nil();
5068             List<JCExpression> thrown = List.nil();
5069             if (!isRecord || !names.isInitOrVNew(name) || token.kind == LPAREN) {
5070                 params = formalParameters();
5071                 if (!isVoid) type = bracketsOpt(type);
5072                 if (token.kind == THROWS) {
5073                     nextToken();
5074                     thrown = qualidentList(true);
5075                 }
5076             }
5077             JCBlock body = null;
5078             JCExpression defaultValue;
5079             if (token.kind == LBRACE) {
5080                 body = block();
5081                 defaultValue = null;
5082             } else {
5083                 if (token.kind == DEFAULT) {
5084                     accept(DEFAULT);
5085                     defaultValue = annotationValue();
5086                 } else {
5087                     defaultValue = null;
5088                 }
5089                 accept(SEMI);

5505         case INT:
5506             return TypeTag.INT;
5507         case LONG:
5508             return TypeTag.LONG;
5509         case FLOAT:
5510             return TypeTag.FLOAT;
5511         case DOUBLE:
5512             return TypeTag.DOUBLE;
5513         case BOOLEAN:
5514             return TypeTag.BOOLEAN;
5515         default:
5516             return TypeTag.NONE;
5517         }
5518     }
5519 
5520     void checkSourceLevel(Feature feature) {
5521         checkSourceLevel(token.pos, feature);
5522     }
5523 
5524     protected void checkSourceLevel(int pos, Feature feature) {
5525         if (feature == Feature.PRIMITIVE_CLASSES && !allowPrimitiveClasses) {
5526             // primitive classes are special
5527             log.error(DiagnosticFlag.SOURCE_LEVEL, pos, feature.error(source.name));
5528         } else if (preview.isPreview(feature) && !preview.isEnabled()) {
5529             //preview feature without --preview flag, error
5530             log.error(DiagnosticFlag.SOURCE_LEVEL, pos, preview.disabledError(feature));
5531         } else if (!feature.allowedInSource(source)) {
5532             //incompatible source level, error
5533             log.error(DiagnosticFlag.SOURCE_LEVEL, pos, feature.error(source.name));
5534         } else if (preview.isPreview(feature)) {
5535             //use of preview feature, warn
5536             preview.warnPreview(pos, feature);
5537         }
5538     }
5539 
5540     /*
5541      * a functional source tree and end position mappings
5542      */
5543     protected static class SimpleEndPosTable extends AbstractEndPosTable {
5544 
5545         private final IntHashTable endPosMap;
5546 
5547         SimpleEndPosTable(JavacParser parser) {
5548             super(parser);
< prev index next >