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