< prev index next >

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

Print this page
rev 51258 : imported patch switch


  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  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.stream.Collectors;
  30 

  31 import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
  32 import com.sun.source.tree.ModuleTree.ModuleKind;
  33 
  34 import com.sun.tools.javac.code.*;
  35 import com.sun.tools.javac.code.Source.Feature;
  36 import com.sun.tools.javac.parser.Tokens.*;
  37 import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
  38 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  39 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  40 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
  41 import com.sun.tools.javac.tree.*;
  42 import com.sun.tools.javac.tree.JCTree.*;
  43 import com.sun.tools.javac.util.*;
  44 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
  45 import com.sun.tools.javac.util.JCDiagnostic.Error;
  46 import com.sun.tools.javac.util.JCDiagnostic.Fragment;
  47 import com.sun.tools.javac.util.List;
  48 
  49 import static com.sun.tools.javac.parser.Tokens.TokenKind.*;
  50 import static com.sun.tools.javac.parser.Tokens.TokenKind.ASSERT;


 207     /** Switch: is "this" allowed as an identifier?
 208      * This is needed to parse receiver types.
 209      */
 210     boolean allowThisIdent;
 211 
 212     /** The type of the method receiver, as specified by a first "this" parameter.
 213      */
 214     JCVariableDecl receiverParam;
 215 
 216     /** When terms are parsed, the mode determines which is expected:
 217      *     mode = EXPR        : an expression
 218      *     mode = TYPE        : a type
 219      *     mode = NOPARAMS    : no parameters allowed for type
 220      *     mode = TYPEARG     : type argument
 221      */
 222     protected static final int EXPR = 0x1;
 223     protected static final int TYPE = 0x2;
 224     protected static final int NOPARAMS = 0x4;
 225     protected static final int TYPEARG = 0x8;
 226     protected static final int DIAMOND = 0x10;

 227 
 228     /** The current mode.
 229      */
 230     protected int mode = 0;
 231 
 232     /** The mode of the term that was parsed last.
 233      */
 234     protected int lastmode = 0;
 235 
 236     /* ---------- token management -------------- */
 237 
 238     protected Token token;
 239 
 240     public Token token() {
 241         return token;
 242     }
 243 
 244     public void nextToken() {
 245         S.nextToken();
 246         token = S.token();


1176                     JCFieldAccess sel = (JCFieldAccess) expr;
1177 
1178                     if (sel.name != names._class) {
1179                         return illegal();
1180                     } else {
1181                         log.error(token.pos, Errors.NoAnnotationsOnDotClass);
1182                         return expr;
1183                     }
1184                 }
1185                 default:
1186                     return illegal(typeAnnos.head.pos);
1187                 }
1188 
1189             } else {
1190                 // Type annotations targeting a cast
1191                 t = insertAnnotationsToMostInner(expr, typeAnnos, false);
1192             }
1193             break;
1194         case UNDERSCORE: case IDENTIFIER: case ASSERT: case ENUM:
1195             if (typeArgs != null) return illegal();
1196             if ((mode & EXPR) != 0 && peekToken(ARROW)) {
1197                 t = lambdaExpressionOrStatement(false, false, pos);
1198             } else {
1199                 t = toP(F.at(token.pos).Ident(ident()));
1200                 loop: while (true) {
1201                     pos = token.pos;
1202                     final List<JCAnnotation> annos = typeAnnotationsOpt();
1203 
1204                     // need to report an error later if LBRACKET is for array
1205                     // index access rather than array creation level
1206                     if (!annos.isEmpty() && token.kind != LBRACKET && token.kind != ELLIPSIS)
1207                         return illegal(annos.head.pos);
1208 
1209                     switch (token.kind) {
1210                     case LBRACKET:
1211                         nextToken();
1212                         if (token.kind == RBRACKET) {
1213                             nextToken();
1214                             t = bracketsOpt(t);
1215                             t = toP(F.at(pos).TypeArray(t));
1216                             if (annos.nonEmpty()) {


1339         case VOID:
1340             if (typeArgs != null) illegal();
1341             if ((mode & EXPR) != 0) {
1342                 nextToken();
1343                 if (token.kind == DOT) {
1344                     JCPrimitiveTypeTree ti = toP(F.at(pos).TypeIdent(TypeTag.VOID));
1345                     t = bracketsSuffix(ti);
1346                 } else {
1347                     return illegal(pos);
1348                 }
1349             } else {
1350                 // Support the corner case of myMethodHandle.<void>invoke() by passing
1351                 // a void type (like other primitive types) to the next phase.
1352                 // The error will be reported in Attr.attribTypes or Attr.visitApply.
1353                 JCPrimitiveTypeTree ti = to(F.at(pos).TypeIdent(TypeTag.VOID));
1354                 nextToken();
1355                 return ti;
1356                 //return illegal();
1357             }
1358             break;
























1359         default:
1360             return illegal();
1361         }
1362         return term3Rest(t, typeArgs);
1363     }
1364 














































1365     JCExpression term3Rest(JCExpression t, List<JCExpression> typeArgs) {
1366         if (typeArgs != null) illegal();
1367         while (true) {
1368             int pos1 = token.pos;
1369             final List<JCAnnotation> annos = typeAnnotationsOpt();
1370 
1371             if (token.kind == LBRACKET) {
1372                 nextToken();
1373                 if ((mode & TYPE) != 0) {
1374                     int oldmode = mode;
1375                     mode = TYPE;
1376                     if (token.kind == RBRACKET) {
1377                         nextToken();
1378                         t = bracketsOpt(t);
1379                         t = toP(F.at(pos1).TypeArray(t));
1380                         if (token.kind == COLCOL) {
1381                             mode = EXPR;
1382                             continue;
1383                         }
1384                         if (annos.nonEmpty()) {


2600             JCExpression lock = parExpression();
2601             JCBlock body = block();
2602             return F.at(pos).Synchronized(lock, body);
2603         }
2604         case RETURN: {
2605             nextToken();
2606             JCExpression result = token.kind == SEMI ? null : parseExpression();
2607             accept(SEMI);
2608             JCReturn t = toP(F.at(pos).Return(result));
2609             return t;
2610         }
2611         case THROW: {
2612             nextToken();
2613             JCExpression exc = parseExpression();
2614             accept(SEMI);
2615             JCThrow t = toP(F.at(pos).Throw(exc));
2616             return t;
2617         }
2618         case BREAK: {
2619             nextToken();
2620             Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null;
2621             accept(SEMI);
2622             JCBreak t = toP(F.at(pos).Break(label));
2623             return t;
2624         }
2625         case CONTINUE: {
2626             nextToken();
2627             Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null;
2628             accept(SEMI);
2629             JCContinue t =  toP(F.at(pos).Continue(label));
2630             return t;
2631         }
2632         case SEMI:
2633             nextToken();
2634             return toP(F.at(pos).Skip());
2635         case ELSE:
2636             int elsePos = token.pos;
2637             nextToken();
2638             return doRecover(elsePos, BasicErrorRecoveryAction.BLOCK_STMT, Errors.ElseWithoutIf);
2639         case FINALLY:
2640             int finallyPos = token.pos;
2641             nextToken();
2642             return doRecover(finallyPos, BasicErrorRecoveryAction.BLOCK_STMT, Errors.FinallyWithoutTry);


2696         while (token.kind == BAR) {
2697             nextToken();
2698             // Instead of qualident this is now parseType.
2699             // But would that allow too much, e.g. arrays or generics?
2700             catchTypes.add(parseType());
2701         }
2702         return catchTypes.toList();
2703     }
2704 
2705     /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup }
2706      *  SwitchBlockStatementGroup = SwitchLabel BlockStatements
2707      *  SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":"
2708      */
2709     List<JCCase> switchBlockStatementGroups() {
2710         ListBuffer<JCCase> cases = new ListBuffer<>();
2711         while (true) {
2712             int pos = token.pos;
2713             switch (token.kind) {
2714             case CASE:
2715             case DEFAULT:
2716                 cases.append(switchBlockStatementGroup());
2717                 break;
2718             case RBRACE: case EOF:
2719                 return cases.toList();
2720             default:
2721                 nextToken(); // to ensure progress
2722                 syntaxError(pos, Errors.Expected3(CASE, DEFAULT, RBRACE));
2723             }
2724         }
2725     }
2726 
2727     protected JCCase switchBlockStatementGroup() {
2728         int pos = token.pos;
2729         List<JCStatement> stats;
2730         JCCase c;

2731         switch (token.kind) {
2732         case CASE:





2733             nextToken();
2734             JCExpression pat = parseExpression();















2735             accept(COLON);

2736             stats = blockStatements();
2737             c = F.at(pos).Case(pat, stats);

2738             if (stats.isEmpty())
2739                 storeEnd(c, S.prevToken().endPos);
2740             return c;
2741         case DEFAULT:

2742             nextToken();




2743             accept(COLON);

2744             stats = blockStatements();
2745             c = F.at(pos).Case(null, stats);











2746             if (stats.isEmpty())
2747                 storeEnd(c, S.prevToken().endPos);
2748             return c;

2749         }
2750         throw new AssertionError("should not reach here");
2751     }
2752 
2753     /** MoreStatementExpressions = { COMMA StatementExpression }
2754      */
2755     <T extends ListBuffer<? super JCExpressionStatement>> T moreStatementExpressions(int pos,
2756                                                                     JCExpression first,
2757                                                                     T stats) {
2758         // This Exec is a "StatementExpression"; it subsumes no terminating token
2759         stats.append(toP(F.at(pos).Exec(checkExprStat(first))));
2760         while (token.kind == COMMA) {
2761             nextToken();
2762             pos = token.pos;
2763             JCExpression t = parseExpression();
2764             // This Exec is a "StatementExpression"; it subsumes no terminating token
2765             stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
2766         }
2767         return stats;
2768     }




  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  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.stream.Collectors;
  30 
  31 import com.sun.source.tree.CaseTree.CaseKind;
  32 import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
  33 import com.sun.source.tree.ModuleTree.ModuleKind;
  34 
  35 import com.sun.tools.javac.code.*;
  36 import com.sun.tools.javac.code.Source.Feature;
  37 import com.sun.tools.javac.parser.Tokens.*;
  38 import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
  39 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  40 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  41 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
  42 import com.sun.tools.javac.tree.*;
  43 import com.sun.tools.javac.tree.JCTree.*;
  44 import com.sun.tools.javac.util.*;
  45 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
  46 import com.sun.tools.javac.util.JCDiagnostic.Error;
  47 import com.sun.tools.javac.util.JCDiagnostic.Fragment;
  48 import com.sun.tools.javac.util.List;
  49 
  50 import static com.sun.tools.javac.parser.Tokens.TokenKind.*;
  51 import static com.sun.tools.javac.parser.Tokens.TokenKind.ASSERT;


 208     /** Switch: is "this" allowed as an identifier?
 209      * This is needed to parse receiver types.
 210      */
 211     boolean allowThisIdent;
 212 
 213     /** The type of the method receiver, as specified by a first "this" parameter.
 214      */
 215     JCVariableDecl receiverParam;
 216 
 217     /** When terms are parsed, the mode determines which is expected:
 218      *     mode = EXPR        : an expression
 219      *     mode = TYPE        : a type
 220      *     mode = NOPARAMS    : no parameters allowed for type
 221      *     mode = TYPEARG     : type argument
 222      */
 223     protected static final int EXPR = 0x1;
 224     protected static final int TYPE = 0x2;
 225     protected static final int NOPARAMS = 0x4;
 226     protected static final int TYPEARG = 0x8;
 227     protected static final int DIAMOND = 0x10;
 228     protected static final int NOLAMBDA = 0x20;
 229 
 230     /** The current mode.
 231      */
 232     protected int mode = 0;
 233 
 234     /** The mode of the term that was parsed last.
 235      */
 236     protected int lastmode = 0;
 237 
 238     /* ---------- token management -------------- */
 239 
 240     protected Token token;
 241 
 242     public Token token() {
 243         return token;
 244     }
 245 
 246     public void nextToken() {
 247         S.nextToken();
 248         token = S.token();


1178                     JCFieldAccess sel = (JCFieldAccess) expr;
1179 
1180                     if (sel.name != names._class) {
1181                         return illegal();
1182                     } else {
1183                         log.error(token.pos, Errors.NoAnnotationsOnDotClass);
1184                         return expr;
1185                     }
1186                 }
1187                 default:
1188                     return illegal(typeAnnos.head.pos);
1189                 }
1190 
1191             } else {
1192                 // Type annotations targeting a cast
1193                 t = insertAnnotationsToMostInner(expr, typeAnnos, false);
1194             }
1195             break;
1196         case UNDERSCORE: case IDENTIFIER: case ASSERT: case ENUM:
1197             if (typeArgs != null) return illegal();
1198             if ((mode & EXPR) != 0 && (mode & NOLAMBDA) == 0 && peekToken(ARROW)) {
1199                 t = lambdaExpressionOrStatement(false, false, pos);
1200             } else {
1201                 t = toP(F.at(token.pos).Ident(ident()));
1202                 loop: while (true) {
1203                     pos = token.pos;
1204                     final List<JCAnnotation> annos = typeAnnotationsOpt();
1205 
1206                     // need to report an error later if LBRACKET is for array
1207                     // index access rather than array creation level
1208                     if (!annos.isEmpty() && token.kind != LBRACKET && token.kind != ELLIPSIS)
1209                         return illegal(annos.head.pos);
1210 
1211                     switch (token.kind) {
1212                     case LBRACKET:
1213                         nextToken();
1214                         if (token.kind == RBRACKET) {
1215                             nextToken();
1216                             t = bracketsOpt(t);
1217                             t = toP(F.at(pos).TypeArray(t));
1218                             if (annos.nonEmpty()) {


1341         case VOID:
1342             if (typeArgs != null) illegal();
1343             if ((mode & EXPR) != 0) {
1344                 nextToken();
1345                 if (token.kind == DOT) {
1346                     JCPrimitiveTypeTree ti = toP(F.at(pos).TypeIdent(TypeTag.VOID));
1347                     t = bracketsSuffix(ti);
1348                 } else {
1349                     return illegal(pos);
1350                 }
1351             } else {
1352                 // Support the corner case of myMethodHandle.<void>invoke() by passing
1353                 // a void type (like other primitive types) to the next phase.
1354                 // The error will be reported in Attr.attribTypes or Attr.visitApply.
1355                 JCPrimitiveTypeTree ti = to(F.at(pos).TypeIdent(TypeTag.VOID));
1356                 nextToken();
1357                 return ti;
1358                 //return illegal();
1359             }
1360             break;
1361         case SWITCH:
1362             checkSourceLevel(Feature.SWITCH_EXPRESSION);
1363             int switchPos = token.pos;
1364             nextToken();
1365             JCExpression selector = parExpression();
1366             accept(LBRACE);
1367             ListBuffer<JCCase> cases = new ListBuffer<>();
1368             while (true) {
1369                 pos = token.pos;
1370                 switch (token.kind) {
1371                 case CASE:
1372                 case DEFAULT:
1373                     cases.appendList(switchExpressionStatementGroup());
1374                     break;
1375                 case RBRACE: case EOF:
1376                     JCSwitchExpression e = to(F.at(switchPos).SwitchExpression(selector,
1377                                                                                cases.toList()));
1378                     accept(RBRACE);
1379                     return e;
1380                 default:
1381                     nextToken(); // to ensure progress
1382                     syntaxError(pos, Errors.Expected3(CASE, DEFAULT, RBRACE));
1383                 }
1384             }
1385         default:
1386             return illegal();
1387         }
1388         return term3Rest(t, typeArgs);
1389     }
1390 
1391     private List<JCCase> switchExpressionStatementGroup() {
1392         ListBuffer<JCCase> caseExprs = new ListBuffer<>();
1393         int casePos = token.pos;
1394         ListBuffer<JCExpression> pats = new ListBuffer<>();
1395 
1396         if (token.kind == DEFAULT) {
1397             nextToken();
1398         } else {
1399             accept(CASE);
1400             while (true) {
1401                 pats.append(term(EXPR | NOLAMBDA));
1402                 if (token.kind != COMMA) break;
1403                 checkSourceLevel(Feature.SWITCH_MULTIPLE_CASE_LABELS);
1404                 nextToken();
1405             };
1406         }
1407         List<JCStatement> stats = null;
1408         JCTree body = null;
1409         @SuppressWarnings("removal")
1410         CaseKind kind;
1411         switch (token.kind) {
1412             case ARROW:
1413                 checkSourceLevel(Feature.SWITCH_RULE);
1414                 nextToken();
1415                 if (token.kind == TokenKind.THROW || token.kind == TokenKind.LBRACE) {
1416                     stats = List.of(parseStatement());
1417                     body = stats.head;
1418                     kind = JCCase.RULE;
1419                 } else {
1420                     JCExpression value = parseExpression();
1421                     stats = List.of(to(F.at(value).Break(value)));
1422                     body = value;
1423                     kind = JCCase.RULE;
1424                     accept(SEMI);
1425                 }
1426                 break;
1427             default:
1428                 accept(COLON);
1429                 stats = blockStatements();
1430                 kind = JCCase.STATEMENT;
1431                 break;
1432         }
1433         caseExprs.append(toP(F.at(casePos).Case(kind, pats.toList(), stats, body)));
1434         return caseExprs.toList();
1435     }
1436 
1437     JCExpression term3Rest(JCExpression t, List<JCExpression> typeArgs) {
1438         if (typeArgs != null) illegal();
1439         while (true) {
1440             int pos1 = token.pos;
1441             final List<JCAnnotation> annos = typeAnnotationsOpt();
1442 
1443             if (token.kind == LBRACKET) {
1444                 nextToken();
1445                 if ((mode & TYPE) != 0) {
1446                     int oldmode = mode;
1447                     mode = TYPE;
1448                     if (token.kind == RBRACKET) {
1449                         nextToken();
1450                         t = bracketsOpt(t);
1451                         t = toP(F.at(pos1).TypeArray(t));
1452                         if (token.kind == COLCOL) {
1453                             mode = EXPR;
1454                             continue;
1455                         }
1456                         if (annos.nonEmpty()) {


2672             JCExpression lock = parExpression();
2673             JCBlock body = block();
2674             return F.at(pos).Synchronized(lock, body);
2675         }
2676         case RETURN: {
2677             nextToken();
2678             JCExpression result = token.kind == SEMI ? null : parseExpression();
2679             accept(SEMI);
2680             JCReturn t = toP(F.at(pos).Return(result));
2681             return t;
2682         }
2683         case THROW: {
2684             nextToken();
2685             JCExpression exc = parseExpression();
2686             accept(SEMI);
2687             JCThrow t = toP(F.at(pos).Throw(exc));
2688             return t;
2689         }
2690         case BREAK: {
2691             nextToken();
2692             JCExpression value = token.kind == SEMI ? null : parseExpression();
2693             accept(SEMI);
2694             JCBreak t = toP(F.at(pos).Break(value));
2695             return t;
2696         }
2697         case CONTINUE: {
2698             nextToken();
2699             Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null;
2700             accept(SEMI);
2701             JCContinue t =  toP(F.at(pos).Continue(label));
2702             return t;
2703         }
2704         case SEMI:
2705             nextToken();
2706             return toP(F.at(pos).Skip());
2707         case ELSE:
2708             int elsePos = token.pos;
2709             nextToken();
2710             return doRecover(elsePos, BasicErrorRecoveryAction.BLOCK_STMT, Errors.ElseWithoutIf);
2711         case FINALLY:
2712             int finallyPos = token.pos;
2713             nextToken();
2714             return doRecover(finallyPos, BasicErrorRecoveryAction.BLOCK_STMT, Errors.FinallyWithoutTry);


2768         while (token.kind == BAR) {
2769             nextToken();
2770             // Instead of qualident this is now parseType.
2771             // But would that allow too much, e.g. arrays or generics?
2772             catchTypes.add(parseType());
2773         }
2774         return catchTypes.toList();
2775     }
2776 
2777     /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup }
2778      *  SwitchBlockStatementGroup = SwitchLabel BlockStatements
2779      *  SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":"
2780      */
2781     List<JCCase> switchBlockStatementGroups() {
2782         ListBuffer<JCCase> cases = new ListBuffer<>();
2783         while (true) {
2784             int pos = token.pos;
2785             switch (token.kind) {
2786             case CASE:
2787             case DEFAULT:
2788                 cases.appendList(switchBlockStatementGroup());
2789                 break;
2790             case RBRACE: case EOF:
2791                 return cases.toList();
2792             default:
2793                 nextToken(); // to ensure progress
2794                 syntaxError(pos, Errors.Expected3(CASE, DEFAULT, RBRACE));
2795             }
2796         }
2797     }
2798 
2799     protected List<JCCase> switchBlockStatementGroup() {
2800         int pos = token.pos;
2801         List<JCStatement> stats;
2802         JCCase c;
2803         ListBuffer<JCCase> cases = new ListBuffer<JCCase>();
2804         switch (token.kind) {
2805         case CASE: {
2806             nextToken();
2807             ListBuffer<JCExpression> pats = new ListBuffer<>();
2808             while (true) {
2809                 pats.append(term(EXPR | NOLAMBDA));
2810                 if (token.kind != COMMA) break;
2811                 nextToken();
2812                 checkSourceLevel(Feature.SWITCH_MULTIPLE_CASE_LABELS);
2813             };
2814             @SuppressWarnings("removal")
2815             CaseKind caseKind;
2816             JCTree body = null;
2817             if (token.kind == ARROW) {
2818                 checkSourceLevel(Feature.SWITCH_RULE);
2819                 accept(ARROW);
2820                 caseKind = JCCase.RULE;
2821                 JCStatement statement = parseStatementAsBlock();
2822                 if (!statement.hasTag(EXEC) && !statement.hasTag(BLOCK) && !statement.hasTag(Tag.THROW)) {
2823                     log.error(statement.pos(), Errors.SwitchCaseUnexpectedStatement);
2824                 }
2825                 stats = List.of(statement);
2826                 body = stats.head;
2827             } else {
2828                 accept(COLON);
2829                 caseKind = JCCase.STATEMENT;
2830                 stats = blockStatements();
2831             }
2832             c = F.at(pos).Case(caseKind, pats.toList(), stats, body);
2833             if (stats.isEmpty())
2834                 storeEnd(c, S.prevToken().endPos);
2835             return cases.append(c).toList();
2836         }
2837         case DEFAULT: {
2838             nextToken();
2839             @SuppressWarnings("removal")
2840             CaseKind caseKind;
2841             JCTree body = null;
2842             if (token.kind == COLON) {
2843                 accept(COLON);
2844                 caseKind = JCCase.STATEMENT;
2845                 stats = blockStatements();
2846             } else {
2847                 checkSourceLevel(Feature.SWITCH_RULE);
2848                 accept(ARROW);
2849                 caseKind = JCCase.RULE;
2850                 JCStatement statement = parseStatementAsBlock();
2851                 if (!statement.hasTag(EXEC) && !statement.hasTag(BLOCK) && !statement.hasTag(Tag.THROW)) {
2852                     log.error(statement.pos(), Errors.SwitchCaseUnexpectedStatement);
2853                 }
2854                 stats = List.of(statement);
2855                 body = stats.head;
2856             }
2857             c = F.at(pos).Case(caseKind, List.nil(), stats, body);
2858             if (stats.isEmpty())
2859                 storeEnd(c, S.prevToken().endPos);
2860             return cases.append(c).toList();
2861         }
2862         }
2863         throw new AssertionError("should not reach here");
2864     }
2865 
2866     /** MoreStatementExpressions = { COMMA StatementExpression }
2867      */
2868     <T extends ListBuffer<? super JCExpressionStatement>> T moreStatementExpressions(int pos,
2869                                                                     JCExpression first,
2870                                                                     T stats) {
2871         // This Exec is a "StatementExpression"; it subsumes no terminating token
2872         stats.append(toP(F.at(pos).Exec(checkExprStat(first))));
2873         while (token.kind == COMMA) {
2874             nextToken();
2875             pos = token.pos;
2876             JCExpression t = parseExpression();
2877             // This Exec is a "StatementExpression"; it subsumes no terminating token
2878             stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
2879         }
2880         return stats;
2881     }


< prev index next >