8000484: Bad error recovery when 'catch' without 'try' is found
Reviewed-by: jjg, mcimadamore
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Tue Nov 06 18:41:56 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Mon Nov 05 16:26:09 2012 +0000
@@ -88,6 +88,15 @@
/** End position mappings container */
private final AbstractEndPosTable endPosTable;
+ interface ErrorRecoveryAction {
+ JCTree doRecover(JavacParser parser);
+ }
+
+ enum BasicErrorRecoveryAction implements ErrorRecoveryAction {
+ BLOCK_STMT {public JCTree doRecover(JavacParser parser) { return parser.parseStatementAsBlock(); }},
+ CATCH_CLAUSE {public JCTree doRecover(JavacParser parser) { return parser.catchClause(); }}
+ }
+
/** Construct a parser from a given scanner, tree factory and log.
*/
protected JavacParser(ParserFactory fac,
@@ -2102,11 +2111,15 @@
nextToken();
return toP(F.at(pos).Skip());
case ELSE:
- return toP(F.Exec(syntaxError("else.without.if")));
+ int elsePos = token.pos;
+ nextToken();
+ return doRecover(elsePos, BasicErrorRecoveryAction.BLOCK_STMT, "else.without.if");
case FINALLY:
- return toP(F.Exec(syntaxError("finally.without.try")));
+ int finallyPos = token.pos;
+ nextToken();
+ return doRecover(finallyPos, BasicErrorRecoveryAction.BLOCK_STMT, "finally.without.try");
case CATCH:
- return toP(F.Exec(syntaxError("catch.without.try")));
+ return doRecover(token.pos, BasicErrorRecoveryAction.CATCH_CLAUSE, "catch.without.try");
case ASSERT: {
if (allowAsserts && token.kind == ASSERT) {
nextToken();
@@ -2139,6 +2152,13 @@
}
}
+ private JCStatement doRecover(int startPos, ErrorRecoveryAction action, String key) {
+ int errPos = S.errPos();
+ JCTree stm = action.doRecover(this);
+ S.errPos(errPos);
+ return toP(F.Exec(syntaxError(startPos, List.<JCTree>of(stm), key)));
+ }
+
/** CatchClause = CATCH "(" FormalParameter ")" Block
*/
protected JCCatch catchClause() {
--- a/langtools/test/tools/javac/diags/examples/CatchWithoutTry.java Tue Nov 06 18:41:56 2012 -0800
+++ b/langtools/test/tools/javac/diags/examples/CatchWithoutTry.java Mon Nov 05 16:26:09 2012 +0000
@@ -22,9 +22,6 @@
*/
// key: compiler.err.catch.without.try
-// key: compiler.err.expected
-// key: compiler.err.not.stmt
-// key: compiler.err.lambda.not.supported.in.source
class CatchWithoutTry {
void m() {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/incompleteStatements/T8000484.java Mon Nov 05 16:26:09 2012 +0000
@@ -0,0 +1,17 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8000484
+ * @summary Bad error recovery when 'catch' without 'try' is found
+ * @compile/fail/ref=T8000484.out -XDrawDiagnostics T8000484.java
+ */
+
+public class T8000484 {
+ void m() {
+ catch (Exception e){}
+ else{}
+ finally{}
+ catch (Exception e) {catch (Exception e){}}
+ else{else{}}
+ finally{finally{}}
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/incompleteStatements/T8000484.out Mon Nov 05 16:26:09 2012 +0000
@@ -0,0 +1,10 @@
+T8000484.java:10:9: compiler.err.catch.without.try
+T8000484.java:11:9: compiler.err.else.without.if
+T8000484.java:12:9: compiler.err.finally.without.try
+T8000484.java:13:30: compiler.err.catch.without.try
+T8000484.java:13:9: compiler.err.catch.without.try
+T8000484.java:14:14: compiler.err.else.without.if
+T8000484.java:14:9: compiler.err.else.without.if
+T8000484.java:15:17: compiler.err.finally.without.try
+T8000484.java:15:9: compiler.err.finally.without.try
+9 errors