langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
changeset 26993 513b2cae81c3
parent 25874 83c19f00452c
child 27844 8b5d79870a2f
equal deleted inserted replaced
26992:92e69fa21956 26993:513b2cae81c3
  2269             }
  2269             }
  2270         }
  2270         }
  2271     }
  2271     }
  2272 
  2272 
  2273     /*
  2273     /*
  2274      * This method parses a statement treating it as a block, relaxing the
  2274      * Parse a Statement (JLS 14.5). As an enhancement to improve error recovery,
  2275      * JLS restrictions, allows us to parse more faulty code, doing so
  2275      * this method will also recognize variable and class declarations (which are
  2276      * enables us to provide better and accurate diagnostics to the user.
  2276      * not legal for a Statement) by delegating the parsing to BlockStatement (JLS 14.2).
       
  2277      * If any illegal declarations are found, they will be wrapped in an erroneous tree,
       
  2278      * and an error will be produced by this method.
  2277      */
  2279      */
  2278     JCStatement parseStatementAsBlock() {
  2280     JCStatement parseStatementAsBlock() {
  2279         int pos = token.pos;
  2281         int pos = token.pos;
  2280         List<JCStatement> stats = blockStatement();
  2282         List<JCStatement> stats = blockStatement();
  2281         if (stats.isEmpty()) {
  2283         if (stats.isEmpty()) {
  2300             }
  2302             }
  2301             return first;
  2303             return first;
  2302         }
  2304         }
  2303     }
  2305     }
  2304 
  2306 
       
  2307     /**This method parses a statement appearing inside a block.
       
  2308      */
  2305     List<JCStatement> blockStatement() {
  2309     List<JCStatement> blockStatement() {
  2306         //todo: skip to anchor on error(?)
  2310         //todo: skip to anchor on error(?)
  2307         int pos = token.pos;
  2311         int pos = token.pos;
  2308         switch (token.kind) {
  2312         switch (token.kind) {
  2309         case RBRACE: case CASE: case DEFAULT: case EOF:
  2313         case RBRACE: case CASE: case DEFAULT: case EOF:
  2310             return List.nil();
  2314             return List.nil();
  2311         case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY:
  2315         case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY:
  2312         case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK:
  2316         case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK:
  2313         case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH:
  2317         case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH:
  2314             return List.of(parseStatement());
  2318         case ASSERT:
       
  2319             return List.of(parseSimpleStatement());
  2315         case MONKEYS_AT:
  2320         case MONKEYS_AT:
  2316         case FINAL: {
  2321         case FINAL: {
  2317             Comment dc = token.comment(CommentStyle.JAVADOC);
  2322             Comment dc = token.comment(CommentStyle.JAVADOC);
  2318             JCModifiers mods = modifiersOpt();
  2323             JCModifiers mods = modifiersOpt();
  2319             if (token.kind == INTERFACE ||
  2324             if (token.kind == INTERFACE ||
  2341             return List.of(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
  2346             return List.of(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
  2342         case ENUM:
  2347         case ENUM:
  2343             error(token.pos, "local.enum");
  2348             error(token.pos, "local.enum");
  2344             dc = token.comment(CommentStyle.JAVADOC);
  2349             dc = token.comment(CommentStyle.JAVADOC);
  2345             return List.of(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
  2350             return List.of(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
  2346         case ASSERT:
       
  2347             return List.of(parseStatement());
       
  2348         default:
  2351         default:
  2349             Token prevToken = token;
  2352             Token prevToken = token;
  2350             JCExpression t = term(EXPR | TYPE);
  2353             JCExpression t = term(EXPR | TYPE);
  2351             if (token.kind == COLON && t.hasTag(IDENT)) {
  2354             if (token.kind == COLON && t.hasTag(IDENT)) {
  2352                 nextToken();
  2355                 nextToken();
  2353                 JCStatement stat = parseStatement();
  2356                 JCStatement stat = parseStatementAsBlock();
  2354                 return List.<JCStatement>of(F.at(pos).Labelled(prevToken.name(), stat));
  2357                 return List.<JCStatement>of(F.at(pos).Labelled(prevToken.name(), stat));
  2355             } else if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
  2358             } else if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
  2356                 pos = token.pos;
  2359                 pos = token.pos;
  2357                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
  2360                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
  2358                 F.at(pos);
  2361                 F.at(pos);
  2387      *     | THROW Expression ";"
  2390      *     | THROW Expression ";"
  2388      *     | BREAK [Ident] ";"
  2391      *     | BREAK [Ident] ";"
  2389      *     | CONTINUE [Ident] ";"
  2392      *     | CONTINUE [Ident] ";"
  2390      *     | ASSERT Expression [ ":" Expression ] ";"
  2393      *     | ASSERT Expression [ ":" Expression ] ";"
  2391      *     | ";"
  2394      *     | ";"
  2392      *     | ExpressionStatement
  2395      */
  2393      *     | Ident ":" Statement
  2396     JCStatement parseSimpleStatement() {
  2394      */
       
  2395     public JCStatement parseStatement() {
       
  2396         int pos = token.pos;
  2397         int pos = token.pos;
  2397         switch (token.kind) {
  2398         switch (token.kind) {
  2398         case LBRACE:
  2399         case LBRACE:
  2399             return block();
  2400             return block();
  2400         case IF: {
  2401         case IF: {
  2540             }
  2541             }
  2541             accept(SEMI);
  2542             accept(SEMI);
  2542             JCAssert t = toP(F.at(pos).Assert(assertion, message));
  2543             JCAssert t = toP(F.at(pos).Assert(assertion, message));
  2543             return t;
  2544             return t;
  2544         }
  2545         }
  2545         case ENUM:
       
  2546         default:
  2546         default:
  2547             Token prevToken = token;
  2547             Assert.error();
  2548             JCExpression expr = parseExpression();
  2548             return null;
  2549             if (token.kind == COLON && expr.hasTag(IDENT)) {
  2549         }
  2550                 nextToken();
  2550     }
  2551                 JCStatement stat = parseStatement();
  2551 
  2552                 return F.at(pos).Labelled(prevToken.name(), stat);
  2552     @Override
  2553             } else {
  2553     public JCStatement parseStatement() {
  2554                 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
  2554         return parseStatementAsBlock();
  2555                 expr = checkExprStat(expr);
       
  2556                 accept(SEMI);
       
  2557                 JCExpressionStatement stat = toP(F.at(pos).Exec(expr));
       
  2558                 return stat;
       
  2559             }
       
  2560         }
       
  2561     }
  2555     }
  2562 
  2556 
  2563     private JCStatement doRecover(int startPos, ErrorRecoveryAction action, String key) {
  2557     private JCStatement doRecover(int startPos, ErrorRecoveryAction action, String key) {
  2564         int errPos = S.errPos();
  2558         int errPos = S.errPos();
  2565         JCTree stm = action.doRecover(this);
  2559         JCTree stm = action.doRecover(this);