8000484: Bad error recovery when 'catch' without 'try' is found
authorvromero
Mon, 05 Nov 2012 16:26:09 +0000
changeset 14450 7a62c5b13d6e
parent 14449 8b4d83b2354e
child 14451 c18762e096ae
8000484: Bad error recovery when 'catch' without 'try' is found Reviewed-by: jjg, mcimadamore
langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java
langtools/test/tools/javac/diags/examples/CatchWithoutTry.java
langtools/test/tools/javac/incompleteStatements/T8000484.java
langtools/test/tools/javac/incompleteStatements/T8000484.out
--- 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