< prev index next >

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

Print this page

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

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

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

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

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


 192     }
 193 
 194     protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) {
 195         return  keepEndPositions
 196                 ? new SimpleEndPosTable(this)
 197                 : new EmptyEndPosTable(this);
 198     }
 199 
 200     protected DocCommentTable newDocCommentTable(boolean keepDocComments, ParserFactory fac) {
 201         return keepDocComments ? new LazyDocCommentTable(fac) : null;
 202     }
 203 
 204     /** Switch: should we fold strings?
 205      */
 206     boolean allowStringFolding;
 207 
 208     /** Switch: should we keep docComments?
 209      */
 210     boolean keepDocComments;
 211 
 212     /** Switch: should we keep line table?
 213      */
 214     boolean keepLineMap;
 215 
 216     /** Switch: is "this" allowed as an identifier?
 217      * This is needed to parse receiver types.
 218      */
 219     boolean allowThisIdent;
 220 
 221     /** Switch: is yield statement allowed in this source level?
 222      */
 223     boolean allowYieldStatement;
 224 
 225     /** Switch: are records allowed in this source level?
 226      */
 227     boolean allowRecords;
 228 








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

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
















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

1348                         break loop;
1349                     case LPAREN:
1350                         if ((mode & EXPR) != 0) {
1351                             selectExprMode();
1352                             t = arguments(typeArgs, t);
1353                             if (!annos.isEmpty()) t = illegal(annos.head.pos);
1354                             typeArgs = null;
1355                         }
1356                         break loop;
1357                     case DOT:
1358                         nextToken();
1359                         if (token.kind == TokenKind.IDENTIFIER && typeArgs != null) {
1360                             return illegal();
1361                         }
1362                         int oldmode = mode;
1363                         mode &= ~NOPARAMS;
1364                         typeArgs = typeArgumentsOpt(EXPR);
1365                         mode = oldmode;
1366                         if ((mode & EXPR) != 0) {
1367                             switch (token.kind) {






1368                             case CLASS:
1369                                 if (typeArgs != null) return illegal();
1370                                 selectExprMode();
1371                                 t = to(F.at(pos).Select(t, names._class));
1372                                 nextToken();
1373                                 break loop;
1374                             case THIS:
1375                                 if (typeArgs != null) return illegal();
1376                                 selectExprMode();
1377                                 t = to(F.at(pos).Select(t, names._this));
1378                                 nextToken();
1379                                 break loop;
1380                             case SUPER:
1381                                 selectExprMode();
1382                                 t = to(F.at(pos).Select(t, names._super));
1383                                 t = superSuffix(typeArgs, t);
1384                                 typeArgs = null;
1385                                 break loop;
1386                             case NEW:
1387                                 if (typeArgs != null) return illegal();

1405                             token.kind == MONKEYS_AT) {
1406                             //error recovery, case like:
1407                             //int i = expr.<missing-ident>
1408                             //@Deprecated
1409                             if (typeArgs != null) illegal();
1410                             return toP(t);
1411                         }
1412                         if (tyannos != null && tyannos.nonEmpty()) {
1413                             t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
1414                         }
1415                         break;
1416                     case ELLIPSIS:
1417                         if (this.permitTypeAnnotationsPushBack) {
1418                             this.typeAnnotationsPushedBack = annos;
1419                         } else if (annos.nonEmpty()) {
1420                             // Don't return here -- error recovery attempt
1421                             illegal(annos.head.pos);
1422                         }
1423                         break loop;
1424                     case LT:
1425                         if ((mode & TYPE) == 0 && isUnboundMemberRef()) {
1426                             //this is an unbound method reference whose qualifier
1427                             //is a generic type i.e. A<S>::m

1428                             int pos1 = token.pos;
1429                             accept(LT);
1430                             ListBuffer<JCExpression> args = new ListBuffer<>();
1431                             args.append(typeArgument());
1432                             while (token.kind == COMMA) {
1433                                 nextToken();
1434                                 args.append(typeArgument());
1435                             }
1436                             accept(GT);
1437                             t = toP(F.at(pos1).TypeApply(t, args.toList()));
1438                             while (token.kind == DOT) {
1439                                 nextToken();






1440                                 selectTypeMode();
1441                                 t = toP(F.at(token.pos).Select(t, ident()));
1442                                 t = typeArgumentsOpt(t);
1443                             }
1444                             t = bracketsOpt(t);
1445                             if (token.kind != COLCOL) {
1446                                 //method reference expected here
1447                                 t = illegal();
1448                             }
1449                             selectExprMode();
1450                             return term3Rest(t, typeArgs);
1451                         }
1452                         break loop;
1453                     default:
1454                         break loop;
1455                     }
1456                 }
1457             }
1458             if (typeArgs != null) illegal();
1459             t = typeArgumentsOpt(t);

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

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

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

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




2283             }
2284         } else if ((mode & TYPE) != 0) {
2285             if (token.kind != COLCOL) {
2286                 selectTypeMode();
2287             }
2288         } else if (token.kind != COLCOL) {
2289             syntaxError(token.pos, Errors.DotClassExpected);
2290         }
2291         return t;
2292     }
2293 
2294     /**
2295      * MemberReferenceSuffix = "::" [TypeArguments] Ident
2296      *                       | "::" [TypeArguments] "new"
2297      */
2298     JCExpression memberReferenceSuffix(JCExpression t) {
2299         int pos1 = token.pos;
2300         accept(COLCOL);
2301         return memberReferenceSuffix(pos1, t);
2302     }
2303 
2304     JCExpression memberReferenceSuffix(int pos1, JCExpression t) {
2305         selectExprMode();
2306         List<JCExpression> typeArgs = null;
2307         if (token.kind == LT) {
2308             typeArgs = typeArguments(false);
2309         }
2310         Name refName;
2311         ReferenceMode refMode;
2312         if (token.kind == NEW) {
2313             refMode = ReferenceMode.NEW;

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



2331             if (typeArgs == null) {
2332                 if (newAnnotations.isEmpty()) {
2333                     return arrayCreatorRest(newpos, basicType());
2334                 } else {
2335                     return arrayCreatorRest(newpos, toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, basicType())));
2336                 }
2337             }
2338             break;
2339         default:
2340         }
2341         JCExpression t = qualident(true);
2342 
2343         int oldmode = mode;
2344         selectTypeMode();
2345         boolean diamondFound = false;
2346         int lastTypeargsPos = -1;
2347         if (token.kind == LT) {
2348             lastTypeargsPos = token.pos;
2349             t = typeArguments(t, true);
2350             diamondFound = (mode & DIAMOND) != 0;

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



2399             // handle type annotations for instantiations and anonymous classes
2400             if (newAnnotations.nonEmpty()) {
2401                 t = insertAnnotationsToMostInner(t, newAnnotations, false);
2402             }
2403             return classCreatorRest(newpos, null, typeArgs, t);




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

2486             if (token.kind == LBRACE) {
2487                 elems = arrayInitializerElements(newpos, elemtype);
2488             }
2489 
2490             JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), elems));
2491             na.dimAnnotations = dimAnnotations.toList();
2492 
2493             if (elems != null) {
2494                 return syntaxError(errpos, List.of(na), Errors.IllegalArrayCreationBothDimensionAndInitialization);
2495             }
2496 
2497             return na;
2498         }
2499     }
2500 
2501     /** ClassCreatorRest = Arguments [ClassBody]
2502      */
2503     JCNewClass classCreatorRest(int newpos,
2504                                   JCExpression encl,
2505                                   List<JCExpression> typeArgs,
2506                                   JCExpression t)

2507     {
2508         List<JCExpression> args = arguments();
2509         JCClassDecl body = null;
2510         if (token.kind == LBRACE) {
2511             int pos = token.pos;
2512             List<JCTree> defs = classInterfaceOrRecordBody(names.empty, false, false);
2513             JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2514             body = toP(F.at(pos).AnonymousClassDef(mods, defs));
2515         }
2516         return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));

2517     }
2518 
2519     /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
2520      */
2521     JCExpression arrayInitializer(int newpos, JCExpression t) {
2522         List<JCExpression> elems = arrayInitializerElements(newpos, t);
2523         return toP(F.at(newpos).NewArray(t, List.nil(), elems));
2524     }
2525 
2526     List<JCExpression> arrayInitializerElements(int newpos, JCExpression t) {
2527         accept(LBRACE);
2528         ListBuffer<JCExpression> elems = new ListBuffer<>();
2529         if (token.kind == COMMA) {
2530             nextToken();
2531         } else if (token.kind != RBRACE) {
2532             elems.append(variableInitializer());
2533             while (token.kind == COMMA) {
2534                 nextToken();
2535                 if (token.kind == RBRACE) break;
2536                 elems.append(variableInitializer());

2729                     accept(SEMI);
2730                     return List.of(toP(F.at(pos).Yield(t)));
2731                 }
2732 
2733                 //else intentional fall-through
2734             } else {
2735                 if (isNonSealedClassStart(true)) {
2736                     log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2737                     nextToken();
2738                     nextToken();
2739                     nextToken();
2740                     return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.comment(CommentStyle.JAVADOC)));
2741                 } else if (isSealedClassStart(true)) {
2742                     checkSourceLevel(Feature.SEALED_CLASSES);
2743                     log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2744                     nextToken();
2745                     return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.comment(CommentStyle.JAVADOC)));
2746                 }
2747             }
2748         }




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

3302             nextToken();
3303             pos = token.pos;
3304             JCExpression t = parseExpression();
3305             // This Exec is a "StatementExpression"; it subsumes no terminating token
3306             stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
3307         }
3308         return stats;
3309     }
3310 
3311     /** ForInit = StatementExpression MoreStatementExpressions
3312      *           |  { FINAL | '@' Annotation } Type VariableDeclarators
3313      */
3314     List<JCStatement> forInit() {
3315         ListBuffer<JCStatement> stats = new ListBuffer<>();
3316         int pos = token.pos;
3317         if (token.kind == FINAL || token.kind == MONKEYS_AT) {
3318             return variableDeclarators(optFinal(0), parseType(true), stats, true).toList();
3319         } else {
3320             JCExpression t = term(EXPR | TYPE);
3321             if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.test(token.kind)) {
3322                 return variableDeclarators(modifiersOpt(), t, stats, true).toList();



3323             } else if ((lastmode & TYPE) != 0 && token.kind == COLON) {
3324                 log.error(DiagnosticFlag.SYNTAX, pos, Errors.BadInitializer("for-loop"));
3325                 return List.of((JCStatement)F.at(pos).VarDef(modifiersOpt(), names.error, t, null));
3326             } else {
3327                 return moreStatementExpressions(pos, t, stats).toList();
3328             }
3329         }
3330     }
3331 
3332     /** ForUpdate = StatementExpression MoreStatementExpressions
3333      */
3334     List<JCExpressionStatement> forUpdate() {
3335         return moreStatementExpressions(token.pos,
3336                                         parseExpression(),
3337                                         new ListBuffer<JCExpressionStatement>()).toList();
3338     }
3339 
3340     /** AnnotationsOpt = { '@' Annotation }
3341      *
3342      * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION

3399             case ABSTRACT    : flag = Flags.ABSTRACT; break;
3400             case NATIVE      : flag = Flags.NATIVE; break;
3401             case VOLATILE    : flag = Flags.VOLATILE; break;
3402             case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
3403             case STRICTFP    : flag = Flags.STRICTFP; break;
3404             case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
3405             case DEFAULT     : flag = Flags.DEFAULT; break;
3406             case ERROR       : flag = 0; nextToken(); break;
3407             case IDENTIFIER  : {
3408                 if (isNonSealedClassStart(false)) {
3409                     flag = Flags.NON_SEALED;
3410                     nextToken();
3411                     nextToken();
3412                     break;
3413                 }
3414                 if (isSealedClassStart(false)) {
3415                     checkSourceLevel(Feature.SEALED_CLASSES);
3416                     flag = Flags.SEALED;
3417                     break;
3418                 }












3419                 break loop;
3420             }
3421             default: break loop;
3422             }
3423             if ((flags & flag) != 0) log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.RepeatedModifier);
3424             lastPos = token.pos;
3425             nextToken();
3426             if (flag == Flags.ANNOTATION) {
3427                 if (token.kind != INTERFACE) {
3428                     JCAnnotation ann = annotation(lastPos, Tag.ANNOTATION);
3429                     // if first modifier is an annotation, set pos to annotation's.
3430                     if (flags == 0 && annotations.isEmpty())
3431                         pos = ann.pos;
3432                     annotations.append(ann);
3433                     flag = 0;
3434                 }
3435             }
3436             flags |= flag;
3437         }
3438         switch (token.kind) {

3650             if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) {
3651                 return Source.JDK10;
3652             } else if (shouldWarn) {
3653                 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK10));
3654             }
3655         }
3656         if (name == names.yield) {
3657             if (allowYieldStatement) {
3658                 return Source.JDK14;
3659             } else if (shouldWarn) {
3660                 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK14));
3661             }
3662         }
3663         if (name == names.record) {
3664             if (allowRecords) {
3665                 return Source.JDK14;
3666             } else if (shouldWarn) {
3667                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK14));
3668             }
3669         }



















3670         if (name == names.sealed) {
3671             if (allowSealedTypes) {
3672                 return Source.JDK15;
3673             } else if (shouldWarn) {
3674                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3675             }
3676         }
3677         if (name == names.permits) {
3678             if (allowSealedTypes) {
3679                 return Source.JDK15;
3680             } else if (shouldWarn) {
3681                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3682             }
3683         }
3684         return null;
3685     }
3686 
3687     /** VariableDeclaratorId = Ident BracketsOpt
3688      */
3689     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {

4087         mods.flags |= Flags.RECORD;
4088         Name name = typeName();
4089 
4090         List<JCTypeParameter> typarams = typeParametersOpt();
4091 
4092         List<JCVariableDecl> headerFields = formalParameters(false, true);
4093 
4094         List<JCExpression> implementing = List.nil();
4095         if (token.kind == IMPLEMENTS) {
4096             nextToken();
4097             implementing = typeList();
4098         }
4099         List<JCTree> defs = classInterfaceOrRecordBody(name, false, true);
4100         java.util.List<JCVariableDecl> fields = new ArrayList<>();
4101         for (JCVariableDecl field : headerFields) {
4102             fields.add(field);
4103         }
4104         for (JCTree def : defs) {
4105             if (def.hasTag(METHODDEF)) {
4106                 JCMethodDecl methDef = (JCMethodDecl) def;
4107                 if (methDef.name == names.init && methDef.params.isEmpty() && (methDef.mods.flags & Flags.COMPACT_RECORD_CONSTRUCTOR) != 0) {

4108                     ListBuffer<JCVariableDecl> tmpParams = new ListBuffer<>();
4109                     for (JCVariableDecl param : headerFields) {
4110                         tmpParams.add(F.at(param)
4111                                 // we will get flags plus annotations from the record component
4112                                 .VarDef(F.Modifiers(Flags.PARAMETER | Flags.GENERATED_MEMBER | param.mods.flags & Flags.VARARGS,
4113                                         param.mods.annotations),
4114                                 param.name, param.vartype, null));
4115                     }
4116                     methDef.params = tmpParams.toList();
4117                 }
4118             }
4119         }
4120         for (int i = fields.size() - 1; i >= 0; i--) {
4121             JCVariableDecl field = fields.get(i);
4122             defs = defs.prepend(field);
4123         }
4124         JCClassDecl result = toP(F.at(pos).ClassDef(mods, name, typarams, null, implementing, defs));
4125         attach(result, dc);
4126         return result;
4127     }

4539             Token next = S.token(3);
4540             return allowedAfterSealedOrNonSealed(next, local, true);
4541         }
4542         return false;
4543     }
4544 
4545     protected boolean isNonSealedIdentifier(Token someToken, int lookAheadOffset) {
4546         if (someToken.name() == names.non && peekToken(lookAheadOffset, TokenKind.SUB, TokenKind.IDENTIFIER)) {
4547             Token tokenSub = S.token(lookAheadOffset + 1);
4548             Token tokenSealed = S.token(lookAheadOffset + 2);
4549             if (someToken.endPos == tokenSub.pos &&
4550                     tokenSub.endPos == tokenSealed.pos &&
4551                     tokenSealed.name() == names.sealed) {
4552                 checkSourceLevel(Feature.SEALED_CLASSES);
4553                 return true;
4554             }
4555         }
4556         return false;
4557     }
4558 














































































4559     protected boolean isSealedClassStart(boolean local) {
4560         if (token.name() == names.sealed) {
4561             Token next = S.token(1);
4562             if (allowedAfterSealedOrNonSealed(next, local, false)) {
4563                 checkSourceLevel(Feature.SEALED_CLASSES);
4564                 return true;
4565             }
4566         }
4567         return false;
4568     }
4569 
4570     private boolean allowedAfterSealedOrNonSealed(Token next, boolean local, boolean currentIsNonSealed) {
4571         return local ?
4572             switch (next.kind) {
4573                 case MONKEYS_AT -> {
4574                     Token afterNext = S.token(2);
4575                     yield afterNext.kind != INTERFACE || currentIsNonSealed;
4576                 }
4577                 case ABSTRACT, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4578                 default -> false;
4579             } :
4580             switch (next.kind) {
4581                 case MONKEYS_AT -> {
4582                     Token afterNext = S.token(2);
4583                     yield afterNext.kind != INTERFACE || currentIsNonSealed;
4584                 }
4585                 case PUBLIC, PROTECTED, PRIVATE, ABSTRACT, STATIC, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4586                 case IDENTIFIER -> isNonSealedIdentifier(next, currentIsNonSealed ? 3 : 1) || next.name() == names.sealed;



4587                 default -> false;
4588             };
4589     }
4590 
4591     /** MethodDeclaratorRest =
4592      *      FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
4593      *  VoidMethodDeclaratorRest =
4594      *      FormalParameters [THROWS TypeList] ( MethodBody | ";")
4595      *  ConstructorDeclaratorRest =
4596      *      "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
4597      */
4598     protected JCTree methodDeclaratorRest(int pos,
4599                               JCModifiers mods,
4600                               JCExpression type,
4601                               Name name,
4602                               List<JCTypeParameter> typarams,
4603                               boolean isInterface, boolean isVoid,
4604                               boolean isRecord,
4605                               Comment dc) {
4606         if (isInterface) {
4607             if ((mods.flags & Flags.PRIVATE) != 0) {
4608                 checkSourceLevel(Feature.PRIVATE_INTERFACE_METHODS);
4609             }
4610         }
4611         JCVariableDecl prevReceiverParam = this.receiverParam;
4612         try {
4613             this.receiverParam = null;
4614             // Parsing formalParameters sets the receiverParam, if present
4615             List<JCVariableDecl> params = List.nil();
4616             List<JCExpression> thrown = List.nil();
4617             if (!isRecord || name != names.init || token.kind == LPAREN) {
4618                 params = formalParameters();
4619                 if (!isVoid) type = bracketsOpt(type);
4620                 if (token.kind == THROWS) {
4621                     nextToken();
4622                     thrown = qualidentList(true);
4623                 }
4624             }
4625             JCBlock body = null;
4626             JCExpression defaultValue;
4627             if (token.kind == LBRACE) {
4628                 body = block();
4629                 defaultValue = null;
4630             } else {
4631                 if (token.kind == DEFAULT) {
4632                     accept(DEFAULT);
4633                     defaultValue = annotationValue();
4634                 } else {
4635                     defaultValue = null;
4636                 }
4637                 accept(SEMI);

5053         case INT:
5054             return TypeTag.INT;
5055         case LONG:
5056             return TypeTag.LONG;
5057         case FLOAT:
5058             return TypeTag.FLOAT;
5059         case DOUBLE:
5060             return TypeTag.DOUBLE;
5061         case BOOLEAN:
5062             return TypeTag.BOOLEAN;
5063         default:
5064             return TypeTag.NONE;
5065         }
5066     }
5067 
5068     void checkSourceLevel(Feature feature) {
5069         checkSourceLevel(token.pos, feature);
5070     }
5071 
5072     protected void checkSourceLevel(int pos, Feature feature) {
5073         if (preview.isPreview(feature) && !preview.isEnabled()) {



5074             //preview feature without --preview flag, error
5075             log.error(DiagnosticFlag.SOURCE_LEVEL, pos, preview.disabledError(feature));
5076         } else if (!feature.allowedInSource(source)) {
5077             //incompatible source level, error
5078             log.error(DiagnosticFlag.SOURCE_LEVEL, pos, feature.error(source.name));
5079         } else if (preview.isPreview(feature)) {
5080             //use of preview feature, warn
5081             preview.warnPreview(pos, feature);
5082         }
5083     }
5084 
5085     /*
5086      * a functional source tree and end position mappings
5087      */
5088     protected static class SimpleEndPosTable extends AbstractEndPosTable {
5089 
5090         private final IntHashTable endPosMap;
5091 
5092         SimpleEndPosTable(JavacParser parser) {
5093             super(parser);

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

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

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

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

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

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

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

2287 
2288     private JCExpression bracketsOptCont(JCExpression t, int pos,
2289             List<JCAnnotation> annotations) {
2290         accept(RBRACKET);
2291         t = bracketsOpt(t);
2292         t = toP(F.at(pos).TypeArray(t));
2293         if (annotations.nonEmpty()) {
2294             t = toP(F.at(pos).AnnotatedType(annotations, t));
2295         }
2296         return t;
2297     }
2298 
2299     /** BracketsSuffixExpr = "." CLASS
2300      *  BracketsSuffixType =
2301      */
2302     JCExpression bracketsSuffix(JCExpression t) {
2303         if ((mode & EXPR) != 0 && token.kind == DOT) {
2304             selectExprMode();
2305             int pos = token.pos;
2306             nextToken();
2307             TokenKind selector = accept2(CLASS, DEFAULT);
2308             if (token.pos == endPosTable.errorEndPos) {
2309                 // error recovery
2310                 Name name;
2311                 if (LAX_IDENTIFIER.test(token.kind)) {
2312                     name = token.name();
2313                     nextToken();
2314                 } else {
2315                     name = names.error;
2316                 }
2317                 t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name))));
2318             } else {
2319                 Tag tag = t.getTag();
2320                 // Type annotations are illegal on class literals. Annotated non array class literals
2321                 // are complained about directly in term3(), Here check for type annotations on dimensions
2322                 // taking care to handle some interior dimension(s) being annotated.
2323                 if ((tag == TYPEARRAY && TreeInfo.containsTypeAnnotation(t)) || tag == ANNOTATED_TYPE)
2324                     syntaxError(token.pos, Errors.NoAnnotationsOnDotClass);
2325                 if (selector == CLASS) {
2326                     t = toP(F.at(pos).Select(t, names._class));
2327                 } else {
2328                     t = toP(F.at(pos).DefaultValue(t));
2329                 }
2330             }
2331         } else if ((mode & TYPE) != 0) {
2332             if (token.kind != COLCOL) {
2333                 selectTypeMode();
2334             }
2335         } else if (token.kind != COLCOL) {
2336             syntaxError(token.pos, Errors.DotClassExpected);
2337         }
2338         return t;
2339     }
2340 
2341     /**
2342      * MemberReferenceSuffix = "::" [TypeArguments] Ident
2343      *                       | "::" [TypeArguments] "new"
2344      */
2345     JCExpression memberReferenceSuffix(JCExpression t) {
2346         int pos1 = token.pos;
2347         accept(COLCOL);
2348         return memberReferenceSuffix(pos1, t);
2349     }
2350 
2351     JCExpression memberReferenceSuffix(int pos1, JCExpression t) {
2352         selectExprMode();
2353         List<JCExpression> typeArgs = null;
2354         if (token.kind == LT) {
2355             typeArgs = typeArguments(false);
2356         }
2357         Name refName;
2358         ReferenceMode refMode;
2359         if (token.kind == NEW) {
2360             refMode = ReferenceMode.NEW;
2361             // TODO - will be converted in Attr
2362             refName = names.init;
2363             nextToken();
2364         } else {
2365             refMode = ReferenceMode.INVOKE;
2366             refName = ident();
2367         }
2368         return toP(F.at(t.getStartPosition()).Reference(refMode, refName, t, typeArgs));
2369     }
2370 
2371     /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
2372      */
2373     JCExpression creator(int newpos, List<JCExpression> typeArgs) {
2374         final JCModifiers mods = modifiersOpt();
2375         List<JCAnnotation> newAnnotations = mods.annotations;
2376         switch (token.kind) {
2377         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
2378         case DOUBLE: case BOOLEAN:
2379             if (mods.flags != 0) {
2380                 log.error(token.pos, Errors.ModNotAllowedHere(asFlagSet(mods.flags)));
2381             }
2382             if (typeArgs == null) {
2383                 if (newAnnotations.isEmpty()) {
2384                     return arrayCreatorRest(newpos, basicType());
2385                 } else {
2386                     return arrayCreatorRest(newpos, toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, basicType())));
2387                 }
2388             }
2389             break;
2390         default:
2391         }
2392         JCExpression t = qualident(true);
2393 
2394         int oldmode = mode;
2395         selectTypeMode();
2396         boolean diamondFound = false;
2397         int lastTypeargsPos = -1;
2398         if (token.kind == LT) {
2399             lastTypeargsPos = token.pos;
2400             t = typeArguments(t, true);
2401             diamondFound = (mode & DIAMOND) != 0;

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

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

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

3366             nextToken();
3367             pos = token.pos;
3368             JCExpression t = parseExpression();
3369             // This Exec is a "StatementExpression"; it subsumes no terminating token
3370             stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
3371         }
3372         return stats;
3373     }
3374 
3375     /** ForInit = StatementExpression MoreStatementExpressions
3376      *           |  { FINAL | '@' Annotation } Type VariableDeclarators
3377      */
3378     List<JCStatement> forInit() {
3379         ListBuffer<JCStatement> stats = new ListBuffer<>();
3380         int pos = token.pos;
3381         if (token.kind == FINAL || token.kind == MONKEYS_AT) {
3382             return variableDeclarators(optFinal(0), parseType(true), stats, true).toList();
3383         } else {
3384             JCExpression t = term(EXPR | TYPE);
3385             if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.test(token.kind)) {
3386                 pos = token.pos;
3387                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
3388                 F.at(pos);
3389                 return variableDeclarators(mods, t, stats, true).toList();
3390             } else if ((lastmode & TYPE) != 0 && token.kind == COLON) {
3391                 log.error(DiagnosticFlag.SYNTAX, pos, Errors.BadInitializer("for-loop"));
3392                 return List.of((JCStatement)F.at(pos).VarDef(modifiersOpt(), names.error, t, null));
3393             } else {
3394                 return moreStatementExpressions(pos, t, stats).toList();
3395             }
3396         }
3397     }
3398 
3399     /** ForUpdate = StatementExpression MoreStatementExpressions
3400      */
3401     List<JCExpressionStatement> forUpdate() {
3402         return moreStatementExpressions(token.pos,
3403                                         parseExpression(),
3404                                         new ListBuffer<JCExpressionStatement>()).toList();
3405     }
3406 
3407     /** AnnotationsOpt = { '@' Annotation }
3408      *
3409      * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION

3466             case ABSTRACT    : flag = Flags.ABSTRACT; break;
3467             case NATIVE      : flag = Flags.NATIVE; break;
3468             case VOLATILE    : flag = Flags.VOLATILE; break;
3469             case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
3470             case STRICTFP    : flag = Flags.STRICTFP; break;
3471             case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
3472             case DEFAULT     : flag = Flags.DEFAULT; break;
3473             case ERROR       : flag = 0; nextToken(); break;
3474             case IDENTIFIER  : {
3475                 if (isNonSealedClassStart(false)) {
3476                     flag = Flags.NON_SEALED;
3477                     nextToken();
3478                     nextToken();
3479                     break;
3480                 }
3481                 if (isSealedClassStart(false)) {
3482                     checkSourceLevel(Feature.SEALED_CLASSES);
3483                     flag = Flags.SEALED;
3484                     break;
3485                 }
3486                 if (isPrimitiveModifier()) {
3487                     flag = Flags.PRIMITIVE_CLASS;
3488                     break;
3489                 }
3490                 if (isValueModifier()) {
3491                     flag = Flags.VALUE_CLASS;
3492                     break;
3493                 }
3494                 if (isIdentityModifier()) {
3495                     flag = Flags.IDENTITY_TYPE;
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) {

3729             if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) {
3730                 return Source.JDK10;
3731             } else if (shouldWarn) {
3732                 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK10));
3733             }
3734         }
3735         if (name == names.yield) {
3736             if (allowYieldStatement) {
3737                 return Source.JDK14;
3738             } else if (shouldWarn) {
3739                 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK14));
3740             }
3741         }
3742         if (name == names.record) {
3743             if (allowRecords) {
3744                 return Source.JDK14;
3745             } else if (shouldWarn) {
3746                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK14));
3747             }
3748         }
3749         if (name == names.primitive) {
3750             if (allowPrimitiveClasses) {
3751                 return Source.JDK18;
3752             }
3753         }
3754         if (name == names.value) {
3755             if (allowValueClasses) {
3756                 return Source.JDK18;
3757             } else if (shouldWarn) {
3758                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK18));
3759             }
3760         }
3761         if (name == names.identity) {
3762             if (allowPrimitiveClasses) {
3763                 return Source.JDK18;
3764             } else if (shouldWarn) {
3765                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK18));
3766             }
3767         }
3768         if (name == names.sealed) {
3769             if (allowSealedTypes) {
3770                 return Source.JDK15;
3771             } else if (shouldWarn) {
3772                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3773             }
3774         }
3775         if (name == names.permits) {
3776             if (allowSealedTypes) {
3777                 return Source.JDK15;
3778             } else if (shouldWarn) {
3779                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3780             }
3781         }
3782         return null;
3783     }
3784 
3785     /** VariableDeclaratorId = Ident BracketsOpt
3786      */
3787     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {

4185         mods.flags |= Flags.RECORD;
4186         Name name = typeName();
4187 
4188         List<JCTypeParameter> typarams = typeParametersOpt();
4189 
4190         List<JCVariableDecl> headerFields = formalParameters(false, true);
4191 
4192         List<JCExpression> implementing = List.nil();
4193         if (token.kind == IMPLEMENTS) {
4194             nextToken();
4195             implementing = typeList();
4196         }
4197         List<JCTree> defs = classInterfaceOrRecordBody(name, false, true);
4198         java.util.List<JCVariableDecl> fields = new ArrayList<>();
4199         for (JCVariableDecl field : headerFields) {
4200             fields.add(field);
4201         }
4202         for (JCTree def : defs) {
4203             if (def.hasTag(METHODDEF)) {
4204                 JCMethodDecl methDef = (JCMethodDecl) def;
4205                 // TODO - specifically for record.
4206                 if (names.isInitOrVNew(methDef.name) && methDef.params.isEmpty() && (methDef.mods.flags & Flags.COMPACT_RECORD_CONSTRUCTOR) != 0) {
4207                     ListBuffer<JCVariableDecl> tmpParams = new ListBuffer<>();
4208                     for (JCVariableDecl param : headerFields) {
4209                         tmpParams.add(F.at(param)
4210                                 // we will get flags plus annotations from the record component
4211                                 .VarDef(F.Modifiers(Flags.PARAMETER | Flags.GENERATED_MEMBER | param.mods.flags & Flags.VARARGS,
4212                                         param.mods.annotations),
4213                                 param.name, param.vartype, null));
4214                     }
4215                     methDef.params = tmpParams.toList();
4216                 }
4217             }
4218         }
4219         for (int i = fields.size() - 1; i >= 0; i--) {
4220             JCVariableDecl field = fields.get(i);
4221             defs = defs.prepend(field);
4222         }
4223         JCClassDecl result = toP(F.at(pos).ClassDef(mods, name, typarams, null, implementing, defs));
4224         attach(result, dc);
4225         return result;
4226     }

4638             Token next = S.token(3);
4639             return allowedAfterSealedOrNonSealed(next, local, true);
4640         }
4641         return false;
4642     }
4643 
4644     protected boolean isNonSealedIdentifier(Token someToken, int lookAheadOffset) {
4645         if (someToken.name() == names.non && peekToken(lookAheadOffset, TokenKind.SUB, TokenKind.IDENTIFIER)) {
4646             Token tokenSub = S.token(lookAheadOffset + 1);
4647             Token tokenSealed = S.token(lookAheadOffset + 2);
4648             if (someToken.endPos == tokenSub.pos &&
4649                     tokenSub.endPos == tokenSealed.pos &&
4650                     tokenSealed.name() == names.sealed) {
4651                 checkSourceLevel(Feature.SEALED_CLASSES);
4652                 return true;
4653             }
4654         }
4655         return false;
4656     }
4657 
4658     protected boolean isPrimitiveModifier() {
4659         if (token.kind == IDENTIFIER && token.name() == names.primitive) {
4660             boolean isPrimitiveModifier = false;
4661             Token next = S.token(1);
4662             switch (next.kind) {
4663                 case PRIVATE: case PROTECTED: case PUBLIC: case STATIC: case TRANSIENT:
4664                 case FINAL: case ABSTRACT: case NATIVE: case VOLATILE: case SYNCHRONIZED:
4665                 case STRICTFP: case MONKEYS_AT: case DEFAULT: case BYTE: case SHORT:
4666                 case CHAR: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
4667                 case CLASS: case INTERFACE: case ENUM:
4668                     isPrimitiveModifier = true;
4669                     break;
4670                 case IDENTIFIER: // primitive record R || primitive primitive || primitive identity || primitive value || new primitive Comparable() {}
4671                     if (next.name() == names.record || next.name() == names.primitive || next.name() == names.identity
4672                             || next.name() == names.value || (mode & EXPR) != 0)
4673                         isPrimitiveModifier = true;
4674                     break;
4675             }
4676             if (isPrimitiveModifier) {
4677                 checkSourceLevel(Feature.PRIMITIVE_CLASSES);
4678                 return true;
4679             }
4680         }
4681         return false;
4682     }
4683 
4684     protected boolean isValueModifier() {
4685         if (token.kind == IDENTIFIER && token.name() == names.value) {
4686             boolean isValueModifier = false;
4687             Token next = S.token(1);
4688             switch (next.kind) {
4689                 case PRIVATE: case PROTECTED: case PUBLIC: case STATIC: case TRANSIENT:
4690                 case FINAL: case ABSTRACT: case NATIVE: case VOLATILE: case SYNCHRONIZED:
4691                 case STRICTFP: case MONKEYS_AT: case DEFAULT: case BYTE: case SHORT:
4692                 case CHAR: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
4693                 case CLASS: case INTERFACE: case ENUM:
4694                     isValueModifier = true;
4695                     break;
4696                 case IDENTIFIER: // value record R || value value || value identity || value primitive || new value Comparable() {} ??
4697                     if (next.name() == names.record || next.name() == names.value || next.name() == names.identity
4698                             || next.name() == names.primitive || (mode & EXPR) != 0)
4699                         isValueModifier = true;
4700                     break;
4701             }
4702             if (isValueModifier) {
4703                 checkSourceLevel(Feature.VALUE_CLASSES);
4704                 return true;
4705             }
4706         }
4707         return false;
4708     }
4709 
4710     protected boolean isIdentityModifier() {
4711         if (token.kind == IDENTIFIER && token.name() == names.identity) {
4712             boolean isIdentityModifier = false;
4713             Token next = S.token(1);
4714             switch (next.kind) {
4715                 case PRIVATE: case PROTECTED: case PUBLIC: case STATIC: case TRANSIENT:
4716                 case FINAL: case ABSTRACT: case NATIVE: case VOLATILE: case SYNCHRONIZED:
4717                 case STRICTFP: case MONKEYS_AT: case DEFAULT: case BYTE: case SHORT:
4718                 case CHAR: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
4719                 case CLASS: case INTERFACE: case ENUM:
4720                     isIdentityModifier = true;
4721                     break;
4722                 case IDENTIFIER: // identity record R || identity primitive || || identity identity || identity value || new identity Comparable() {}
4723                     if (next.name() == names.record || next.name() == names.primitive || next.name() == names.identity
4724                             || next.name() == names.value || (mode & EXPR) != 0)
4725                         isIdentityModifier = true;
4726                     break;
4727             }
4728             if (isIdentityModifier) {
4729                 checkSourceLevel(Feature.VALUE_CLASSES);
4730                 return true;
4731             }
4732         }
4733         return false;
4734     }
4735 
4736     protected boolean isSealedClassStart(boolean local) {
4737         if (token.name() == names.sealed) {
4738             Token next = S.token(1);
4739             if (allowedAfterSealedOrNonSealed(next, local, false)) {
4740                 checkSourceLevel(Feature.SEALED_CLASSES);
4741                 return true;
4742             }
4743         }
4744         return false;
4745     }
4746 
4747     private boolean allowedAfterSealedOrNonSealed(Token next, boolean local, boolean currentIsNonSealed) {
4748         return local ?
4749             switch (next.kind) {
4750                 case MONKEYS_AT -> {
4751                     Token afterNext = S.token(2);
4752                     yield afterNext.kind != INTERFACE || currentIsNonSealed;
4753                 }
4754                 case ABSTRACT, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4755                 default -> false;
4756             } :
4757             switch (next.kind) {
4758                 case MONKEYS_AT -> {
4759                     Token afterNext = S.token(2);
4760                     yield afterNext.kind != INTERFACE || currentIsNonSealed;
4761                 }
4762                 case PUBLIC, PROTECTED, PRIVATE, ABSTRACT, STATIC, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4763                 case IDENTIFIER -> isNonSealedIdentifier(next, currentIsNonSealed ? 3 : 1) ||
4764                         next.name() == names.sealed ||
4765                         next.name() == names.value ||
4766                         next.name() == names.identity;
4767                 default -> false;
4768             };
4769     }
4770 
4771     /** MethodDeclaratorRest =
4772      *      FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
4773      *  VoidMethodDeclaratorRest =
4774      *      FormalParameters [THROWS TypeList] ( MethodBody | ";")
4775      *  ConstructorDeclaratorRest =
4776      *      "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
4777      */
4778     protected JCTree methodDeclaratorRest(int pos,
4779                               JCModifiers mods,
4780                               JCExpression type,
4781                               Name name,
4782                               List<JCTypeParameter> typarams,
4783                               boolean isInterface, boolean isVoid,
4784                               boolean isRecord,
4785                               Comment dc) {
4786         if (isInterface) {
4787             if ((mods.flags & Flags.PRIVATE) != 0) {
4788                 checkSourceLevel(Feature.PRIVATE_INTERFACE_METHODS);
4789             }
4790         }
4791         JCVariableDecl prevReceiverParam = this.receiverParam;
4792         try {
4793             this.receiverParam = null;
4794             // Parsing formalParameters sets the receiverParam, if present
4795             List<JCVariableDecl> params = List.nil();
4796             List<JCExpression> thrown = List.nil();
4797             if (!isRecord || !names.isInitOrVNew(name) || token.kind == LPAREN) {
4798                 params = formalParameters();
4799                 if (!isVoid) type = bracketsOpt(type);
4800                 if (token.kind == THROWS) {
4801                     nextToken();
4802                     thrown = qualidentList(true);
4803                 }
4804             }
4805             JCBlock body = null;
4806             JCExpression defaultValue;
4807             if (token.kind == LBRACE) {
4808                 body = block();
4809                 defaultValue = null;
4810             } else {
4811                 if (token.kind == DEFAULT) {
4812                     accept(DEFAULT);
4813                     defaultValue = annotationValue();
4814                 } else {
4815                     defaultValue = null;
4816                 }
4817                 accept(SEMI);

5233         case INT:
5234             return TypeTag.INT;
5235         case LONG:
5236             return TypeTag.LONG;
5237         case FLOAT:
5238             return TypeTag.FLOAT;
5239         case DOUBLE:
5240             return TypeTag.DOUBLE;
5241         case BOOLEAN:
5242             return TypeTag.BOOLEAN;
5243         default:
5244             return TypeTag.NONE;
5245         }
5246     }
5247 
5248     void checkSourceLevel(Feature feature) {
5249         checkSourceLevel(token.pos, feature);
5250     }
5251 
5252     protected void checkSourceLevel(int pos, Feature feature) {
5253         if (feature == Feature.PRIMITIVE_CLASSES && !allowPrimitiveClasses) {
5254             // primitive classes are special
5255             log.error(DiagnosticFlag.SOURCE_LEVEL, pos, feature.error(source.name));
5256         } else if (preview.isPreview(feature) && !preview.isEnabled()) {
5257             //preview feature without --preview flag, error
5258             log.error(DiagnosticFlag.SOURCE_LEVEL, pos, preview.disabledError(feature));
5259         } else if (!feature.allowedInSource(source)) {
5260             //incompatible source level, error
5261             log.error(DiagnosticFlag.SOURCE_LEVEL, pos, feature.error(source.name));
5262         } else if (preview.isPreview(feature)) {
5263             //use of preview feature, warn
5264             preview.warnPreview(pos, feature);
5265         }
5266     }
5267 
5268     /*
5269      * a functional source tree and end position mappings
5270      */
5271     protected static class SimpleEndPosTable extends AbstractEndPosTable {
5272 
5273         private final IntHashTable endPosMap;
5274 
5275         SimpleEndPosTable(JavacParser parser) {
5276             super(parser);
< prev index next >