Thu, 28 Oct 2010 18:58:43 -0700
6994946: option to specify only syntax errors as unrecoverable
Reviewed-by: darcy, mcimadamore
1.1 --- a/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Thu Oct 28 10:17:47 2010 -0700 1.2 +++ b/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Thu Oct 28 18:58:43 2010 -0700 1.3 @@ -1090,7 +1090,7 @@ 1.4 1.5 private boolean unrecoverableError() { 1.6 for (JCDiagnostic d: log.deferredDiagnostics) { 1.7 - if (d.getKind() == JCDiagnostic.Kind.ERROR && !d.isFlagSet(RESOLVE_ERROR)) 1.8 + if (d.getKind() == JCDiagnostic.Kind.ERROR && !d.isFlagSet(RECOVERABLE)) 1.9 return true; 1.10 } 1.11 return false;
2.1 --- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Thu Oct 28 10:17:47 2010 -0700 2.2 +++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Thu Oct 28 18:58:43 2010 -0700 2.3 @@ -30,6 +30,7 @@ 2.4 import com.sun.tools.javac.tree.*; 2.5 import com.sun.tools.javac.code.*; 2.6 import com.sun.tools.javac.util.*; 2.7 +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; 2.8 import com.sun.tools.javac.util.List; 2.9 import static com.sun.tools.javac.util.ListBuffer.lb; 2.10 2.11 @@ -266,9 +267,9 @@ 2.12 private void reportSyntaxError(int pos, String key, Object... args) { 2.13 if (pos > S.errPos() || pos == Position.NOPOS) { 2.14 if (S.token() == EOF) 2.15 - log.error(pos, "premature.eof"); 2.16 + error(pos, "premature.eof"); 2.17 else 2.18 - log.error(pos, key, args); 2.19 + error(pos, key, args); 2.20 } 2.21 S.errPos(pos); 2.22 if (S.pos() == errorPos) 2.23 @@ -324,7 +325,7 @@ 2.24 void checkNoMods(long mods) { 2.25 if (mods != 0) { 2.26 long lowestMod = mods & -mods; 2.27 - log.error(S.pos(), "mod.not.allowed.here", 2.28 + error(S.pos(), "mod.not.allowed.here", 2.29 Flags.asFlagSet(lowestMod)); 2.30 } 2.31 } 2.32 @@ -418,22 +419,22 @@ 2.33 return name; 2.34 } else if (S.token() == ASSERT) { 2.35 if (allowAsserts) { 2.36 - log.error(S.pos(), "assert.as.identifier"); 2.37 + error(S.pos(), "assert.as.identifier"); 2.38 S.nextToken(); 2.39 return names.error; 2.40 } else { 2.41 - log.warning(S.pos(), "assert.as.identifier"); 2.42 + warning(S.pos(), "assert.as.identifier"); 2.43 Name name = S.name(); 2.44 S.nextToken(); 2.45 return name; 2.46 } 2.47 } else if (S.token() == ENUM) { 2.48 if (allowEnums) { 2.49 - log.error(S.pos(), "enum.as.identifier"); 2.50 + error(S.pos(), "enum.as.identifier"); 2.51 S.nextToken(); 2.52 return names.error; 2.53 } else { 2.54 - log.warning(S.pos(), "enum.as.identifier"); 2.55 + warning(S.pos(), "enum.as.identifier"); 2.56 Name name = S.name(); 2.57 S.nextToken(); 2.58 return name; 2.59 @@ -479,7 +480,7 @@ 2.60 TypeTags.INT, 2.61 Convert.string2int(strval(prefix), S.radix())); 2.62 } catch (NumberFormatException ex) { 2.63 - log.error(S.pos(), "int.number.too.large", strval(prefix)); 2.64 + error(S.pos(), "int.number.too.large", strval(prefix)); 2.65 } 2.66 break; 2.67 case LONGLITERAL: 2.68 @@ -488,7 +489,7 @@ 2.69 TypeTags.LONG, 2.70 new Long(Convert.string2long(strval(prefix), S.radix()))); 2.71 } catch (NumberFormatException ex) { 2.72 - log.error(S.pos(), "int.number.too.large", strval(prefix)); 2.73 + error(S.pos(), "int.number.too.large", strval(prefix)); 2.74 } 2.75 break; 2.76 case FLOATLITERAL: { 2.77 @@ -501,9 +502,9 @@ 2.78 n = Float.NaN; 2.79 } 2.80 if (n.floatValue() == 0.0f && !isZero(proper)) 2.81 - log.error(S.pos(), "fp.number.too.small"); 2.82 + error(S.pos(), "fp.number.too.small"); 2.83 else if (n.floatValue() == Float.POSITIVE_INFINITY) 2.84 - log.error(S.pos(), "fp.number.too.large"); 2.85 + error(S.pos(), "fp.number.too.large"); 2.86 else 2.87 t = F.at(pos).Literal(TypeTags.FLOAT, n); 2.88 break; 2.89 @@ -518,9 +519,9 @@ 2.90 n = Double.NaN; 2.91 } 2.92 if (n.doubleValue() == 0.0d && !isZero(proper)) 2.93 - log.error(S.pos(), "fp.number.too.small"); 2.94 + error(S.pos(), "fp.number.too.small"); 2.95 else if (n.doubleValue() == Double.POSITIVE_INFINITY) 2.96 - log.error(S.pos(), "fp.number.too.large"); 2.97 + error(S.pos(), "fp.number.too.large"); 2.98 else 2.99 t = F.at(pos).Literal(TypeTags.DOUBLE, n); 2.100 break; 2.101 @@ -1581,7 +1582,7 @@ 2.102 case ENUM: 2.103 case ASSERT: 2.104 if (allowEnums && S.token() == ENUM) { 2.105 - log.error(S.pos(), "local.enum"); 2.106 + error(S.pos(), "local.enum"); 2.107 stats. 2.108 append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), 2.109 S.docComment())); 2.110 @@ -1728,9 +1729,9 @@ 2.111 } else { 2.112 if (allowTWR) { 2.113 if (resources.isEmpty()) 2.114 - log.error(pos, "try.without.catch.finally.or.resource.decls"); 2.115 + error(pos, "try.without.catch.finally.or.resource.decls"); 2.116 } else 2.117 - log.error(pos, "try.without.catch.or.finally"); 2.118 + error(pos, "try.without.catch.or.finally"); 2.119 } 2.120 return F.at(pos).Try(resources, body, catchers.toList(), finalizer); 2.121 } 2.122 @@ -1985,7 +1986,7 @@ 2.123 case MONKEYS_AT : flag = Flags.ANNOTATION; break; 2.124 default: break loop; 2.125 } 2.126 - if ((flags & flag) != 0) log.error(S.pos(), "repeated.modifier"); 2.127 + if ((flags & flag) != 0) error(S.pos(), "repeated.modifier"); 2.128 lastPos = S.pos(); 2.129 S.nextToken(); 2.130 if (flag == Flags.ANNOTATION) { 2.131 @@ -2331,7 +2332,7 @@ 2.132 } 2.133 } else { 2.134 if (S.token() == ENUM) { 2.135 - log.error(S.pos(), "enums.not.supported.in.source", source.name); 2.136 + error(S.pos(), "enums.not.supported.in.source", source.name); 2.137 allowEnums = true; 2.138 return enumDeclaration(mods, dc); 2.139 } 2.140 @@ -2580,7 +2581,7 @@ 2.141 } 2.142 if (S.token() == LPAREN && !isInterface && type.getTag() == JCTree.IDENT) { 2.143 if (isInterface || name != className) 2.144 - log.error(pos, "invalid.meth.decl.ret.type.req"); 2.145 + error(pos, "invalid.meth.decl.ret.type.req"); 2.146 return List.of(methodDeclaratorRest( 2.147 pos, mods, null, names.init, typarams, 2.148 isInterface, true, dc)); 2.149 @@ -2759,6 +2760,14 @@ 2.150 2.151 /* ---------- auxiliary methods -------------- */ 2.152 2.153 + void error(int pos, String key, Object ... args) { 2.154 + log.error(DiagnosticFlag.SYNTAX, pos, key, args); 2.155 + } 2.156 + 2.157 + void warning(int pos, String key, Object ... args) { 2.158 + log.warning(pos, key, args); 2.159 + } 2.160 + 2.161 /** Check that given tree is a legal expression statement. 2.162 */ 2.163 protected JCExpression checkExprStat(JCExpression t) { 2.164 @@ -2774,7 +2783,7 @@ 2.165 case JCTree.ERRONEOUS: 2.166 return t; 2.167 default: 2.168 - log.error(t.pos, "not.stmt"); 2.169 + error(t.pos, "not.stmt"); 2.170 return F.at(t.pos).Erroneous(List.<JCTree>of(t)); 2.171 } 2.172 } 2.173 @@ -2921,49 +2930,49 @@ 2.174 2.175 void checkGenerics() { 2.176 if (!allowGenerics) { 2.177 - log.error(S.pos(), "generics.not.supported.in.source", source.name); 2.178 + error(S.pos(), "generics.not.supported.in.source", source.name); 2.179 allowGenerics = true; 2.180 } 2.181 } 2.182 void checkVarargs() { 2.183 if (!allowVarargs) { 2.184 - log.error(S.pos(), "varargs.not.supported.in.source", source.name); 2.185 + error(S.pos(), "varargs.not.supported.in.source", source.name); 2.186 allowVarargs = true; 2.187 } 2.188 } 2.189 void checkForeach() { 2.190 if (!allowForeach) { 2.191 - log.error(S.pos(), "foreach.not.supported.in.source", source.name); 2.192 + error(S.pos(), "foreach.not.supported.in.source", source.name); 2.193 allowForeach = true; 2.194 } 2.195 } 2.196 void checkStaticImports() { 2.197 if (!allowStaticImport) { 2.198 - log.error(S.pos(), "static.import.not.supported.in.source", source.name); 2.199 + error(S.pos(), "static.import.not.supported.in.source", source.name); 2.200 allowStaticImport = true; 2.201 } 2.202 } 2.203 void checkAnnotations() { 2.204 if (!allowAnnotations) { 2.205 - log.error(S.pos(), "annotations.not.supported.in.source", source.name); 2.206 + error(S.pos(), "annotations.not.supported.in.source", source.name); 2.207 allowAnnotations = true; 2.208 } 2.209 } 2.210 void checkDiamond() { 2.211 if (!allowDiamond) { 2.212 - log.error(S.pos(), "diamond.not.supported.in.source", source.name); 2.213 + error(S.pos(), "diamond.not.supported.in.source", source.name); 2.214 allowDiamond = true; 2.215 } 2.216 } 2.217 void checkMulticatch() { 2.218 if (!allowMulticatch) { 2.219 - log.error(S.pos(), "multicatch.not.supported.in.source", source.name); 2.220 + error(S.pos(), "multicatch.not.supported.in.source", source.name); 2.221 allowMulticatch = true; 2.222 } 2.223 } 2.224 void checkAutomaticResourceManagement() { 2.225 if (!allowTWR) { 2.226 - log.error(S.pos(), "automatic.resource.management.not.supported.in.source", source.name); 2.227 + error(S.pos(), "automatic.resource.management.not.supported.in.source", source.name); 2.228 allowTWR = true; 2.229 } 2.230 }
3.1 --- a/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Thu Oct 28 10:17:47 2010 -0700 3.2 +++ b/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Thu Oct 28 18:58:43 2010 -0700 3.3 @@ -939,7 +939,7 @@ 3.4 break; 3.5 3.6 case ERROR: 3.7 - if (fatalErrors || !d.isFlagSet(RESOLVE_ERROR)) 3.8 + if (fatalErrors || !d.isFlagSet(RECOVERABLE)) 3.9 return true; 3.10 break; 3.11 }
4.1 --- a/src/share/classes/com/sun/tools/javac/util/AbstractLog.java Thu Oct 28 10:17:47 2010 -0700 4.2 +++ b/src/share/classes/com/sun/tools/javac/util/AbstractLog.java Thu Oct 28 18:58:43 2010 -0700 4.3 @@ -30,6 +30,7 @@ 4.4 import javax.tools.JavaFileObject; 4.5 4.6 import com.sun.tools.javac.code.Lint.LintCategory; 4.7 +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; 4.8 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 4.9 import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition; 4.10 4.11 @@ -103,6 +104,19 @@ 4.12 report(diags.error(source, wrap(pos), key, args)); 4.13 } 4.14 4.15 + /** Report an error, unless another error was already reported at same 4.16 + * source position. 4.17 + * @param flag A flag to set on the diagnostic 4.18 + * @param pos The source position at which to report the error. 4.19 + * @param key The key for the localized error message. 4.20 + * @param args Fields of the error message. 4.21 + */ 4.22 + public void error(DiagnosticFlag flag, int pos, String key, Object ... args) { 4.23 + JCDiagnostic d = diags.error(source, wrap(pos), key, args); 4.24 + d.setFlag(flag); 4.25 + report(d); 4.26 + } 4.27 + 4.28 /** Report a warning, unless suppressed by the -nowarn option or the 4.29 * maximum number of warnings has been reached. 4.30 * @param pos The source position at which to report the warning.
5.1 --- a/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java Thu Oct 28 10:17:47 2010 -0700 5.2 +++ b/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java Thu Oct 28 18:58:43 2010 -0700 5.3 @@ -63,17 +63,23 @@ 5.4 5.5 DiagnosticFormatter<JCDiagnostic> formatter; 5.6 final String prefix; 5.7 + final Set<DiagnosticFlag> defaultErrorFlags; 5.8 5.9 /** Create a new diagnostic factory. */ 5.10 protected Factory(Context context) { 5.11 this(JavacMessages.instance(context), "compiler"); 5.12 context.put(diagnosticFactoryKey, this); 5.13 + 5.14 + Options options = Options.instance(context); 5.15 + if (options.isSet("onlySyntaxErrorsUnrecoverable")) 5.16 + defaultErrorFlags.add(DiagnosticFlag.RECOVERABLE); 5.17 } 5.18 5.19 /** Create a new diagnostic factory. */ 5.20 public Factory(JavacMessages messages, String prefix) { 5.21 this.prefix = prefix; 5.22 this.formatter = new BasicDiagnosticFormatter(messages); 5.23 + defaultErrorFlags = EnumSet.of(DiagnosticFlag.MANDATORY); 5.24 } 5.25 5.26 /** 5.27 @@ -85,7 +91,7 @@ 5.28 */ 5.29 public JCDiagnostic error( 5.30 DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) { 5.31 - return create(ERROR, null, EnumSet.of(DiagnosticFlag.MANDATORY), source, pos, key, args); 5.32 + return create(ERROR, null, defaultErrorFlags, source, pos, key, args); 5.33 } 5.34 5.35 /** 5.36 @@ -331,7 +337,9 @@ 5.37 5.38 public enum DiagnosticFlag { 5.39 MANDATORY, 5.40 - RESOLVE_ERROR 5.41 + RESOLVE_ERROR, 5.42 + SYNTAX, 5.43 + RECOVERABLE 5.44 } 5.45 5.46 private final DiagnosticType type; 5.47 @@ -547,6 +555,17 @@ 5.48 5.49 public void setFlag(DiagnosticFlag flag) { 5.50 flags.add(flag); 5.51 + 5.52 + if (type == DiagnosticType.ERROR) { 5.53 + switch (flag) { 5.54 + case SYNTAX: 5.55 + flags.remove(DiagnosticFlag.RECOVERABLE); 5.56 + break; 5.57 + case RESOLVE_ERROR: 5.58 + flags.add(DiagnosticFlag.RECOVERABLE); 5.59 + break; 5.60 + } 5.61 + } 5.62 } 5.63 5.64 public boolean isFlagSet(DiagnosticFlag flag) {
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/test/tools/javac/processing/6994946/SemanticErrorTest.1.out Thu Oct 28 18:58:43 2010 -0700 6.3 @@ -0,0 +1,2 @@ 6.4 +SemanticErrorTest.java:11:46: compiler.err.repeated.interface 6.5 +1 error
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/test/tools/javac/processing/6994946/SemanticErrorTest.2.out Thu Oct 28 18:58:43 2010 -0700 7.3 @@ -0,0 +1,4 @@ 7.4 +SemanticErrorTest.java:11:46: compiler.err.repeated.interface 7.5 +- compiler.err.proc.messager: Deliberate Error 7.6 +SemanticErrorTest.java:11:46: compiler.err.repeated.interface 7.7 +1 error
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/test/tools/javac/processing/6994946/SemanticErrorTest.java Thu Oct 28 18:58:43 2010 -0700 8.3 @@ -0,0 +1,13 @@ 8.4 +/* 8.5 + * @test /nodynamiccopyright/ 8.6 + * @bug 6994946 8.7 + * @summary option to specify only syntax errors as unrecoverable 8.8 + * @library ../../lib 8.9 + * @build JavacTestingAbstractProcessor TestProcessor 8.10 + * @compile/fail/ref=SemanticErrorTest.1.out -XDrawDiagnostics -processor TestProcessor SemanticErrorTest.java 8.11 + * @compile/fail/ref=SemanticErrorTest.2.out -XDrawDiagnostics -XDonlySyntaxErrorsUnrecoverable -processor TestProcessor SemanticErrorTest.java 8.12 + */ 8.13 + 8.14 +class SemanticErrorTest implements Runnable, Runnable { 8.15 + public void run() { } 8.16 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/test/tools/javac/processing/6994946/SyntaxErrorTest.java Thu Oct 28 18:58:43 2010 -0700 9.3 @@ -0,0 +1,13 @@ 9.4 +/* 9.5 + * @test /nodynamiccopyright/ 9.6 + * @bug 6994946 9.7 + * @summary option to specify only syntax errors as unrecoverable 9.8 + * @library ../../lib 9.9 + * @build JavacTestingAbstractProcessor TestProcessor 9.10 + * @compile/fail/ref=SyntaxErrorTest.out -XDrawDiagnostics -processor TestProcessor SyntaxErrorTest.java 9.11 + * @compile/fail/ref=SyntaxErrorTest.out -XDrawDiagnostics -XDonlySyntaxErrorsUnrecoverable -processor TestProcessor SyntaxErrorTest.java 9.12 + */ 9.13 + 9.14 +class SyntaxErrorTest { 9.15 + int i 9.16 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/test/tools/javac/processing/6994946/SyntaxErrorTest.out Thu Oct 28 18:58:43 2010 -0700 10.3 @@ -0,0 +1,2 @@ 10.4 +SyntaxErrorTest.java:12:10: compiler.err.expected: ';' 10.5 +1 error
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/test/tools/javac/processing/6994946/TestProcessor.java Thu Oct 28 18:58:43 2010 -0700 11.3 @@ -0,0 +1,40 @@ 11.4 +/* 11.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 11.7 + * 11.8 + * This code is free software; you can redistribute it and/or modify it 11.9 + * under the terms of the GNU General Public License version 2 only, as 11.10 + * published by the Free Software Foundation. 11.11 + * 11.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 11.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11.15 + * version 2 for more details (a copy is included in the LICENSE file that 11.16 + * accompanied this code). 11.17 + * 11.18 + * You should have received a copy of the GNU General Public License version 11.19 + * 2 along with this work; if not, write to the Free Software Foundation, 11.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 11.21 + * 11.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 11.23 + * or visit www.oracle.com if you need additional information or have any 11.24 + * questions. 11.25 + */ 11.26 + 11.27 +import java.util.*; 11.28 +import javax.annotation.processing.*; 11.29 +import javax.lang.model.*; 11.30 +import javax.lang.model.element.*; 11.31 +import static javax.tools.Diagnostic.Kind.*; 11.32 + 11.33 +public class TestProcessor extends JavacTestingAbstractProcessor { 11.34 + private int round = 0; 11.35 + 11.36 + public boolean process(Set<? extends TypeElement> annotations, 11.37 + RoundEnvironment roundEnv) { 11.38 + if (++round == 1) 11.39 + messager.printMessage(ERROR, "Deliberate Error"); 11.40 + return false; 11.41 + } 11.42 +} 11.43 +