6994946: option to specify only syntax errors as unrecoverable
Reviewed-by: darcy, mcimadamore
--- 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;
+ }
+}
+