6994946: option to specify only syntax errors as unrecoverable
authorjjg
Thu, 28 Oct 2010 18:58:43 -0700
changeset 7076 c96fa26247c8
parent 7075 8b20233fedeb
child 7077 55689b828dc5
6994946: option to specify only syntax errors as unrecoverable Reviewed-by: darcy, mcimadamore
langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java
langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java
langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java
langtools/src/share/classes/com/sun/tools/javac/util/AbstractLog.java
langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java
langtools/test/tools/javac/processing/6994946/SemanticErrorTest.1.out
langtools/test/tools/javac/processing/6994946/SemanticErrorTest.2.out
langtools/test/tools/javac/processing/6994946/SemanticErrorTest.java
langtools/test/tools/javac/processing/6994946/SyntaxErrorTest.java
langtools/test/tools/javac/processing/6994946/SyntaxErrorTest.out
langtools/test/tools/javac/processing/6994946/TestProcessor.java
--- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Thu Oct 28 10:17:47 2010 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Thu Oct 28 18:58:43 2010 -0700
@@ -1090,7 +1090,7 @@
 
     private boolean unrecoverableError() {
         for (JCDiagnostic d: log.deferredDiagnostics) {
-            if (d.getKind() == JCDiagnostic.Kind.ERROR && !d.isFlagSet(RESOLVE_ERROR))
+            if (d.getKind() == JCDiagnostic.Kind.ERROR && !d.isFlagSet(RECOVERABLE))
                 return true;
         }
         return false;
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Thu Oct 28 10:17:47 2010 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Thu Oct 28 18:58:43 2010 -0700
@@ -30,6 +30,7 @@
 import com.sun.tools.javac.tree.*;
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.util.*;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
 import com.sun.tools.javac.util.List;
 import static com.sun.tools.javac.util.ListBuffer.lb;
 
@@ -266,9 +267,9 @@
     private void reportSyntaxError(int pos, String key, Object... args) {
         if (pos > S.errPos() || pos == Position.NOPOS) {
             if (S.token() == EOF)
-                log.error(pos, "premature.eof");
+                error(pos, "premature.eof");
             else
-                log.error(pos, key, args);
+                error(pos, key, args);
         }
         S.errPos(pos);
         if (S.pos() == errorPos)
@@ -324,7 +325,7 @@
     void checkNoMods(long mods) {
         if (mods != 0) {
             long lowestMod = mods & -mods;
-            log.error(S.pos(), "mod.not.allowed.here",
+            error(S.pos(), "mod.not.allowed.here",
                       Flags.asFlagSet(lowestMod));
         }
     }
@@ -418,22 +419,22 @@
             return name;
         } else if (S.token() == ASSERT) {
             if (allowAsserts) {
-                log.error(S.pos(), "assert.as.identifier");
+                error(S.pos(), "assert.as.identifier");
                 S.nextToken();
                 return names.error;
             } else {
-                log.warning(S.pos(), "assert.as.identifier");
+                warning(S.pos(), "assert.as.identifier");
                 Name name = S.name();
                 S.nextToken();
                 return name;
             }
         } else if (S.token() == ENUM) {
             if (allowEnums) {
-                log.error(S.pos(), "enum.as.identifier");
+                error(S.pos(), "enum.as.identifier");
                 S.nextToken();
                 return names.error;
             } else {
-                log.warning(S.pos(), "enum.as.identifier");
+                warning(S.pos(), "enum.as.identifier");
                 Name name = S.name();
                 S.nextToken();
                 return name;
@@ -479,7 +480,7 @@
                     TypeTags.INT,
                     Convert.string2int(strval(prefix), S.radix()));
             } catch (NumberFormatException ex) {
-                log.error(S.pos(), "int.number.too.large", strval(prefix));
+                error(S.pos(), "int.number.too.large", strval(prefix));
             }
             break;
         case LONGLITERAL:
@@ -488,7 +489,7 @@
                     TypeTags.LONG,
                     new Long(Convert.string2long(strval(prefix), S.radix())));
             } catch (NumberFormatException ex) {
-                log.error(S.pos(), "int.number.too.large", strval(prefix));
+                error(S.pos(), "int.number.too.large", strval(prefix));
             }
             break;
         case FLOATLITERAL: {
@@ -501,9 +502,9 @@
                 n = Float.NaN;
             }
             if (n.floatValue() == 0.0f && !isZero(proper))
-                log.error(S.pos(), "fp.number.too.small");
+                error(S.pos(), "fp.number.too.small");
             else if (n.floatValue() == Float.POSITIVE_INFINITY)
-                log.error(S.pos(), "fp.number.too.large");
+                error(S.pos(), "fp.number.too.large");
             else
                 t = F.at(pos).Literal(TypeTags.FLOAT, n);
             break;
@@ -518,9 +519,9 @@
                 n = Double.NaN;
             }
             if (n.doubleValue() == 0.0d && !isZero(proper))
-                log.error(S.pos(), "fp.number.too.small");
+                error(S.pos(), "fp.number.too.small");
             else if (n.doubleValue() == Double.POSITIVE_INFINITY)
-                log.error(S.pos(), "fp.number.too.large");
+                error(S.pos(), "fp.number.too.large");
             else
                 t = F.at(pos).Literal(TypeTags.DOUBLE, n);
             break;
@@ -1581,7 +1582,7 @@
             case ENUM:
             case ASSERT:
                 if (allowEnums && S.token() == ENUM) {
-                    log.error(S.pos(), "local.enum");
+                    error(S.pos(), "local.enum");
                     stats.
                         append(classOrInterfaceOrEnumDeclaration(modifiersOpt(),
                                                                  S.docComment()));
@@ -1728,9 +1729,9 @@
             } else {
                 if (allowTWR) {
                     if (resources.isEmpty())
-                        log.error(pos, "try.without.catch.finally.or.resource.decls");
+                        error(pos, "try.without.catch.finally.or.resource.decls");
                 } else
-                    log.error(pos, "try.without.catch.or.finally");
+                    error(pos, "try.without.catch.or.finally");
             }
             return F.at(pos).Try(resources, body, catchers.toList(), finalizer);
         }
@@ -1985,7 +1986,7 @@
             case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
             default: break loop;
             }
-            if ((flags & flag) != 0) log.error(S.pos(), "repeated.modifier");
+            if ((flags & flag) != 0) error(S.pos(), "repeated.modifier");
             lastPos = S.pos();
             S.nextToken();
             if (flag == Flags.ANNOTATION) {
@@ -2331,7 +2332,7 @@
             }
         } else {
             if (S.token() == ENUM) {
-                log.error(S.pos(), "enums.not.supported.in.source", source.name);
+                error(S.pos(), "enums.not.supported.in.source", source.name);
                 allowEnums = true;
                 return enumDeclaration(mods, dc);
             }
@@ -2580,7 +2581,7 @@
                 }
                 if (S.token() == LPAREN && !isInterface && type.getTag() == JCTree.IDENT) {
                     if (isInterface || name != className)
-                        log.error(pos, "invalid.meth.decl.ret.type.req");
+                        error(pos, "invalid.meth.decl.ret.type.req");
                     return List.of(methodDeclaratorRest(
                         pos, mods, null, names.init, typarams,
                         isInterface, true, dc));
@@ -2759,6 +2760,14 @@
 
 /* ---------- auxiliary methods -------------- */
 
+    void error(int pos, String key, Object ... args) {
+        log.error(DiagnosticFlag.SYNTAX, pos, key, args);
+    }
+
+    void warning(int pos, String key, Object ... args) {
+        log.warning(pos, key, args);
+    }
+
     /** Check that given tree is a legal expression statement.
      */
     protected JCExpression checkExprStat(JCExpression t) {
@@ -2774,7 +2783,7 @@
         case JCTree.ERRONEOUS:
             return t;
         default:
-            log.error(t.pos, "not.stmt");
+            error(t.pos, "not.stmt");
             return F.at(t.pos).Erroneous(List.<JCTree>of(t));
         }
     }
@@ -2921,49 +2930,49 @@
 
     void checkGenerics() {
         if (!allowGenerics) {
-            log.error(S.pos(), "generics.not.supported.in.source", source.name);
+            error(S.pos(), "generics.not.supported.in.source", source.name);
             allowGenerics = true;
         }
     }
     void checkVarargs() {
         if (!allowVarargs) {
-            log.error(S.pos(), "varargs.not.supported.in.source", source.name);
+            error(S.pos(), "varargs.not.supported.in.source", source.name);
             allowVarargs = true;
         }
     }
     void checkForeach() {
         if (!allowForeach) {
-            log.error(S.pos(), "foreach.not.supported.in.source", source.name);
+            error(S.pos(), "foreach.not.supported.in.source", source.name);
             allowForeach = true;
         }
     }
     void checkStaticImports() {
         if (!allowStaticImport) {
-            log.error(S.pos(), "static.import.not.supported.in.source", source.name);
+            error(S.pos(), "static.import.not.supported.in.source", source.name);
             allowStaticImport = true;
         }
     }
     void checkAnnotations() {
         if (!allowAnnotations) {
-            log.error(S.pos(), "annotations.not.supported.in.source", source.name);
+            error(S.pos(), "annotations.not.supported.in.source", source.name);
             allowAnnotations = true;
         }
     }
     void checkDiamond() {
         if (!allowDiamond) {
-            log.error(S.pos(), "diamond.not.supported.in.source", source.name);
+            error(S.pos(), "diamond.not.supported.in.source", source.name);
             allowDiamond = true;
         }
     }
     void checkMulticatch() {
         if (!allowMulticatch) {
-            log.error(S.pos(), "multicatch.not.supported.in.source", source.name);
+            error(S.pos(), "multicatch.not.supported.in.source", source.name);
             allowMulticatch = true;
         }
     }
     void checkAutomaticResourceManagement() {
         if (!allowTWR) {
-            log.error(S.pos(), "automatic.resource.management.not.supported.in.source", source.name);
+            error(S.pos(), "automatic.resource.management.not.supported.in.source", source.name);
             allowTWR = true;
         }
     }
--- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Thu Oct 28 10:17:47 2010 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Thu Oct 28 18:58:43 2010 -0700
@@ -939,7 +939,7 @@
                         break;
 
                     case ERROR:
-                        if (fatalErrors || !d.isFlagSet(RESOLVE_ERROR))
+                        if (fatalErrors || !d.isFlagSet(RECOVERABLE))
                             return true;
                         break;
                 }
--- a/langtools/src/share/classes/com/sun/tools/javac/util/AbstractLog.java	Thu Oct 28 10:17:47 2010 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/AbstractLog.java	Thu Oct 28 18:58:43 2010 -0700
@@ -30,6 +30,7 @@
 import javax.tools.JavaFileObject;
 
 import com.sun.tools.javac.code.Lint.LintCategory;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
 
@@ -103,6 +104,19 @@
         report(diags.error(source, wrap(pos), key, args));
     }
 
+    /** Report an error, unless another error was already reported at same
+     *  source position.
+     *  @param flag   A flag to set on the diagnostic
+     *  @param pos    The source position at which to report the error.
+     *  @param key    The key for the localized error message.
+     *  @param args   Fields of the error message.
+     */
+    public void error(DiagnosticFlag flag, int pos, String key, Object ... args) {
+        JCDiagnostic d = diags.error(source, wrap(pos), key, args);
+        d.setFlag(flag);
+        report(d);
+    }
+
     /** Report a warning, unless suppressed by the  -nowarn option or the
      *  maximum number of warnings has been reached.
      *  @param pos    The source position at which to report the warning.
--- a/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java	Thu Oct 28 10:17:47 2010 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java	Thu Oct 28 18:58:43 2010 -0700
@@ -63,17 +63,23 @@
 
         DiagnosticFormatter<JCDiagnostic> formatter;
         final String prefix;
+        final Set<DiagnosticFlag> defaultErrorFlags;
 
         /** Create a new diagnostic factory. */
         protected Factory(Context context) {
             this(JavacMessages.instance(context), "compiler");
             context.put(diagnosticFactoryKey, this);
+
+            Options options = Options.instance(context);
+            if (options.isSet("onlySyntaxErrorsUnrecoverable"))
+                defaultErrorFlags.add(DiagnosticFlag.RECOVERABLE);
         }
 
         /** Create a new diagnostic factory. */
         public Factory(JavacMessages messages, String prefix) {
             this.prefix = prefix;
             this.formatter = new BasicDiagnosticFormatter(messages);
+            defaultErrorFlags = EnumSet.of(DiagnosticFlag.MANDATORY);
         }
 
         /**
@@ -85,7 +91,7 @@
          */
         public JCDiagnostic error(
                 DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
-            return create(ERROR, null, EnumSet.of(DiagnosticFlag.MANDATORY), source, pos, key, args);
+            return create(ERROR, null, defaultErrorFlags, source, pos, key, args);
         }
 
         /**
@@ -331,7 +337,9 @@
 
     public enum DiagnosticFlag {
         MANDATORY,
-        RESOLVE_ERROR
+        RESOLVE_ERROR,
+        SYNTAX,
+        RECOVERABLE
     }
 
     private final DiagnosticType type;
@@ -547,6 +555,17 @@
 
     public void setFlag(DiagnosticFlag flag) {
         flags.add(flag);
+
+        if (type == DiagnosticType.ERROR) {
+            switch (flag) {
+                case SYNTAX:
+                    flags.remove(DiagnosticFlag.RECOVERABLE);
+                    break;
+                case RESOLVE_ERROR:
+                    flags.add(DiagnosticFlag.RECOVERABLE);
+                    break;
+            }
+        }
     }
 
     public boolean isFlagSet(DiagnosticFlag flag) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/6994946/SemanticErrorTest.1.out	Thu Oct 28 18:58:43 2010 -0700
@@ -0,0 +1,2 @@
+SemanticErrorTest.java:11:46: compiler.err.repeated.interface
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/6994946/SemanticErrorTest.2.out	Thu Oct 28 18:58:43 2010 -0700
@@ -0,0 +1,4 @@
+SemanticErrorTest.java:11:46: compiler.err.repeated.interface
+- compiler.err.proc.messager: Deliberate Error
+SemanticErrorTest.java:11:46: compiler.err.repeated.interface
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/6994946/SemanticErrorTest.java	Thu Oct 28 18:58:43 2010 -0700
@@ -0,0 +1,13 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6994946
+ * @summary option to specify only syntax errors as unrecoverable
+ * @library ../../lib
+ * @build JavacTestingAbstractProcessor TestProcessor
+ * @compile/fail/ref=SemanticErrorTest.1.out -XDrawDiagnostics                                  -processor TestProcessor SemanticErrorTest.java
+ * @compile/fail/ref=SemanticErrorTest.2.out -XDrawDiagnostics -XDonlySyntaxErrorsUnrecoverable -processor TestProcessor SemanticErrorTest.java
+ */
+
+class SemanticErrorTest implements Runnable, Runnable {
+    public void run() { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/6994946/SyntaxErrorTest.java	Thu Oct 28 18:58:43 2010 -0700
@@ -0,0 +1,13 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6994946
+ * @summary option to specify only syntax errors as unrecoverable
+ * @library ../../lib
+ * @build JavacTestingAbstractProcessor TestProcessor
+ * @compile/fail/ref=SyntaxErrorTest.out -XDrawDiagnostics                                  -processor TestProcessor SyntaxErrorTest.java
+ * @compile/fail/ref=SyntaxErrorTest.out -XDrawDiagnostics -XDonlySyntaxErrorsUnrecoverable -processor TestProcessor SyntaxErrorTest.java
+ */
+
+class SyntaxErrorTest {
+    int i
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/6994946/SyntaxErrorTest.out	Thu Oct 28 18:58:43 2010 -0700
@@ -0,0 +1,2 @@
+SyntaxErrorTest.java:12:10: compiler.err.expected: ';'
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/6994946/TestProcessor.java	Thu Oct 28 18:58:43 2010 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.*;
+import javax.annotation.processing.*;
+import javax.lang.model.*;
+import javax.lang.model.element.*;
+import static javax.tools.Diagnostic.Kind.*;
+
+public class TestProcessor extends JavacTestingAbstractProcessor {
+   private int round = 0;
+
+   public boolean process(Set<? extends TypeElement> annotations,
+                  RoundEnvironment roundEnv) {
+        if (++round == 1)
+            messager.printMessage(ERROR, "Deliberate Error");
+        return false;
+   }
+}
+