Mon, 28 Feb 2011 13:37:48 -0800
7022741: warning counts are wrong after anno processing
Reviewed-by: mcimadamore
1.1 --- a/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Mon Feb 28 12:19:18 2011 -0800 1.2 +++ b/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Mon Feb 28 13:37:48 2011 -0800 1.3 @@ -807,8 +807,6 @@ 1.4 final JavaCompiler compiler; 1.5 /** The log for the round. */ 1.6 final Log log; 1.7 - /** The number of warnings in the previous round. */ 1.8 - final int priorWarnings; 1.9 1.10 /** The ASTs to be compiled. */ 1.11 List<JCCompilationUnit> roots; 1.12 @@ -826,10 +824,10 @@ 1.13 private Round(Context context, int number, int priorWarnings) { 1.14 this.context = context; 1.15 this.number = number; 1.16 - this.priorWarnings = priorWarnings; 1.17 1.18 compiler = JavaCompiler.instance(context); 1.19 log = Log.instance(context); 1.20 + log.nwarnings += priorWarnings; 1.21 log.deferDiagnostics = true; 1.22 1.23 // the following is for the benefit of JavacProcessingEnvironment.getContext() 1.24 @@ -904,8 +902,8 @@ 1.25 JavaCompiler finalCompiler(boolean errorStatus) { 1.26 try { 1.27 JavaCompiler c = JavaCompiler.instance(nextContext()); 1.28 + c.log.nwarnings += compiler.log.nwarnings; 1.29 if (errorStatus) { 1.30 - c.log.nwarnings += priorWarnings + compiler.log.nwarnings; 1.31 c.log.nerrors += compiler.log.nerrors; 1.32 } 1.33 return c;
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/test/tools/javac/processing/TestWarnErrorCount.java Mon Feb 28 13:37:48 2011 -0800 2.3 @@ -0,0 +1,340 @@ 2.4 +/* 2.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.7 + * 2.8 + * This code is free software; you can redistribute it and/or modify it 2.9 + * under the terms of the GNU General Public License version 2 only, as 2.10 + * published by the Free Software Foundation. 2.11 + * 2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.15 + * version 2 for more details (a copy is included in the LICENSE file that 2.16 + * accompanied this code). 2.17 + * 2.18 + * You should have received a copy of the GNU General Public License version 2.19 + * 2 along with this work; if not, write to the Free Software Foundation, 2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.21 + * 2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2.23 + * or visit www.oracle.com if you need additional information or have any 2.24 + * questions. 2.25 + */ 2.26 + 2.27 + 2.28 +/* 2.29 + * @test 2.30 + * @bug 7022337 2.31 + * @summary repeated warnings about bootclasspath not set 2.32 + * @library ../lib 2.33 + * @build JavacTestingAbstractProcessor TestWarnErrorCount 2.34 + * @run main TestWarnErrorCount 2.35 + */ 2.36 + 2.37 +import java.io.*; 2.38 +import java.util.*; 2.39 +import javax.annotation.processing.*; 2.40 +import javax.lang.model.element.*; 2.41 +import javax.tools.*; 2.42 + 2.43 +@SupportedOptions({"errKind", "msgrWarnKind", "javaWarnKind"}) 2.44 +public class TestWarnErrorCount extends JavacTestingAbstractProcessor { 2.45 + public static void main(String... args) throws Exception { 2.46 + new TestWarnErrorCount().run(args); 2.47 + } 2.48 + 2.49 + final int MAX_GEN = 10; 2.50 + final int ERROR_ROUND = MAX_GEN / 2; // when to generate error 2.51 + 2.52 + /** 2.53 + * Type of errors to generate in test case. 2.54 + */ 2.55 + enum ErrorKind { 2.56 + /** No errors. */ 2.57 + NONE, 2.58 + /** Source code errors. */ 2.59 + JAVA, 2.60 + /** Errors reported to Messager. */ 2.61 + MESSAGER, 2.62 + /** Error as a result of using -Werror. */ 2.63 + WERROR, 2.64 + } 2.65 + 2.66 + /** 2.67 + * Frequency of warnings in test case. 2.68 + */ 2.69 + enum WarnKind { 2.70 + /** No warnings. */ 2.71 + NONE { 2.72 + boolean warn(int round) { return false; } 2.73 + int count(int start, int end) { return 0; } 2.74 + }, 2.75 + /** Generate a warning if round count is a multiple of 2. */ 2.76 + EVERY_TWO { 2.77 + boolean warn(int round) { return (round % 2) == 0; } 2.78 + int count(int start, int end) { return (end / 2) - ((start - 1)/ 2); } 2.79 + }, 2.80 + /** Generate a warning if round count is a multiple of 3. */ 2.81 + EVERY_THREE { 2.82 + boolean warn(int round) { return (round % 3) == 0; } 2.83 + int count(int start, int end) { return (end / 3) - ((start - 1)/ 3); } 2.84 + }, 2.85 + /** Generate a warning every round. */ 2.86 + ALL { 2.87 + boolean warn(int round) { return true; } 2.88 + int count(int start, int end) { return (end - start + 1); } 2.89 + }; 2.90 + 2.91 + /** whether to generate a warning in round 'round'. */ 2.92 + abstract boolean warn(int round); 2.93 + 2.94 + /** number of warnings generated in a range of rounds, inclusive. */ 2.95 + abstract int count(int start, int end); 2.96 + } 2.97 + 2.98 + 2.99 + /** 2.100 + * Run test. 2.101 + * @param args provide ability to specify particular test cases for debugging. 2.102 + */ 2.103 + void run(String... args) throws Exception { 2.104 + for (String arg: args) { 2.105 + if (arg.matches("[0-9]+")) { 2.106 + if (testCases == null) 2.107 + testCases = new HashSet<Integer>(); 2.108 + testCases.add(Integer.valueOf(arg)); 2.109 + } else if (arg.equals("-stopOnError")) { 2.110 + stopOnError = true; 2.111 + } else 2.112 + throw new IllegalArgumentException(arg); 2.113 + } 2.114 + 2.115 + run (); 2.116 + 2.117 + if (errors > 0) 2.118 + throw new Exception(errors + " errors found"); 2.119 + } 2.120 + 2.121 + /** 2.122 + * Run test. 2.123 + */ 2.124 + void run() throws Exception { 2.125 + for (ErrorKind ek: ErrorKind.values()) { 2.126 + for (WarnKind mwk: WarnKind.values()) { 2.127 + for (WarnKind jwk: WarnKind.values()) { 2.128 + test(ek, mwk, jwk); 2.129 + if (stopOnError && errors > 0) 2.130 + throw new Exception(errors + " errors found"); 2.131 + } 2.132 + } 2.133 + } 2.134 + } 2.135 + 2.136 + boolean stopOnError; 2.137 + Set<Integer> testCases; 2.138 + int testNum = 0; 2.139 + 2.140 + /** 2.141 + * Run a test case. 2.142 + * @param ek The type of errors to generate 2.143 + * @param mwk The frequency of Messager warnings to generate 2.144 + * @param jwk The frequency of Java warnings to generate 2.145 + */ 2.146 + void test(ErrorKind ek, WarnKind mwk, WarnKind jwk) { 2.147 + testNum++; 2.148 + 2.149 + if (testCases != null && !testCases.contains(testNum)) 2.150 + return; 2.151 + 2.152 + System.err.println("Test " + testNum + ": ek:" + ek + " mwk:" + mwk + " jwk:" + jwk); 2.153 + 2.154 + File testDir = new File("test" + testNum); 2.155 + testDir.mkdirs(); 2.156 + 2.157 + String myName = TestWarnErrorCount.class.getSimpleName(); 2.158 + File testSrc = new File(System.getProperty("test.src")); 2.159 + File file = new File(testSrc, myName + ".java"); 2.160 + 2.161 + List<String> args = new ArrayList<String>(); 2.162 + args.addAll(Arrays.asList( 2.163 + "-XDrawDiagnostics", 2.164 + "-d", testDir.getPath(), 2.165 + "-processor", myName, 2.166 +// "-XprintRounds", 2.167 + "-Xlint", 2.168 + "-AerrKind=" + ek, 2.169 + "-AmsgrWarnKind=" + mwk, 2.170 + "-AjavaWarnKind=" + jwk)); 2.171 + if (ek == ErrorKind.WERROR) 2.172 + args.add("-Werror"); 2.173 + args.add(file.getPath()); 2.174 + 2.175 + String out = compile(args.toArray(new String[args.size()])); 2.176 + 2.177 + int errsFound = 0; 2.178 + int errsReported = 0; 2.179 + int warnsFound = 0; 2.180 + int warnsReported = 0; 2.181 + 2.182 + // Scan the output looking for messages of interest. 2.183 + 2.184 + for (String line: out.split("[\r\n]+")) { 2.185 + if (line.contains("compiler.err.")) { 2.186 + errsFound++; 2.187 + } else if (line.contains("compiler.warn.")) { 2.188 + warnsFound++; 2.189 + } else if (line.matches("[0-9]+ error(?:s?)")) { 2.190 + errsReported = Integer.valueOf(line.substring(0, line.indexOf("error")).trim()); 2.191 + } else if (line.matches("[0-9]+ warning(?:s?)")) { 2.192 + warnsReported = Integer.valueOf(line.substring(0, line.indexOf("warning")).trim()); 2.193 + } 2.194 + } 2.195 + 2.196 + // Compute the expected number of errors and warnings, based on 2.197 + // the test case parameters. 2.198 + // This is highly specific to the annotation processor below, and to 2.199 + // the files it generates. 2.200 + // Generally, the rules are: 2.201 + // -- errors stop annotation processing, allowing for one extra "last round" 2.202 + // -- messager warnings are immediate 2.203 + // -- javac warnings are not shown before the final compilation 2.204 + // (FIXME? -Werror does not stop processing for java warnings) 2.205 + int errsExpected; 2.206 + int msgrWarnsExpected; 2.207 + int javaWarnsExpected; 2.208 + switch (ek) { 2.209 + case NONE: 2.210 + errsExpected = 0; 2.211 + msgrWarnsExpected = mwk.count(1, 1 + MAX_GEN + 1); 2.212 + javaWarnsExpected = jwk.count(2, 1 + MAX_GEN); 2.213 + break; 2.214 + case MESSAGER: 2.215 + errsExpected = 1; 2.216 + msgrWarnsExpected = mwk.count(1, ERROR_ROUND + 1); 2.217 + javaWarnsExpected = 0; 2.218 + break; 2.219 + case JAVA: 2.220 + errsExpected = 2; 2.221 + msgrWarnsExpected = mwk.count(1, ERROR_ROUND + 1); 2.222 + javaWarnsExpected = 0; 2.223 + break; 2.224 + case WERROR: 2.225 + errsExpected = (mwk != WarnKind.NONE || jwk != WarnKind.NONE) ? 1 : 0; 2.226 + switch (mwk) { 2.227 + case NONE: 2.228 + msgrWarnsExpected = 0; 2.229 + javaWarnsExpected = (jwk == WarnKind.NONE) 2.230 + ? 0 2.231 + : 1; // this is surprising: javac only reports warning in first file 2.232 + break; 2.233 + case EVERY_TWO: 2.234 + msgrWarnsExpected = mwk.count(1, 2 + 1); 2.235 + javaWarnsExpected = 0; 2.236 + break; 2.237 + case EVERY_THREE: 2.238 + msgrWarnsExpected = mwk.count(1, 3 + 1); 2.239 + javaWarnsExpected = 0; 2.240 + break; 2.241 + case ALL: 2.242 + msgrWarnsExpected = mwk.count(1, 1 + 1); 2.243 + javaWarnsExpected = 0; 2.244 + break; 2.245 + default: 2.246 + throw new IllegalStateException(); 2.247 + } 2.248 + break; 2.249 + default: 2.250 + throw new IllegalStateException(); 2.251 + } 2.252 + 2.253 + int warnsExpected = msgrWarnsExpected + javaWarnsExpected; 2.254 + System.err.println("mwk: " + msgrWarnsExpected 2.255 + + ", jwk: " + javaWarnsExpected 2.256 + + ", total: " + warnsExpected); 2.257 + 2.258 + boolean ok; 2.259 + ok = checkEqual("errors", "reported", errsFound, errsReported); 2.260 + ok &= checkEqual("errors", "expected", errsFound, errsExpected); 2.261 + ok &= checkEqual("warnings", "reported", warnsFound, warnsReported); 2.262 + ok &= checkEqual("warnings", "expected", warnsFound, warnsExpected); 2.263 + if (ok) 2.264 + System.err.println("OK"); 2.265 + 2.266 + System.err.println(); 2.267 + } 2.268 + 2.269 + String compile(String... args) { 2.270 + StringWriter sw = new StringWriter(); 2.271 + PrintWriter pw = new PrintWriter(sw); 2.272 + int rc = com.sun.tools.javac.Main.compile(args, pw); 2.273 + pw.close(); 2.274 + String out = sw.toString(); 2.275 + if (!out.isEmpty()) 2.276 + System.err.println(out); 2.277 + if (rc != 0) 2.278 + System.err.println("compilation failed: rc=" + rc); 2.279 + return out; 2.280 + } 2.281 + 2.282 + boolean checkEqual(String l1, String l2, int i1, int i2) { 2.283 + if (i1 != i2) 2.284 + error("number of " + l1 + " found, " + i1 + ", does not match number " + l2 + ", " + i2); 2.285 + return (i1 == i2); 2.286 + } 2.287 + 2.288 + void error(String msg) { 2.289 + System.err.println("Error: " + msg); 2.290 + errors++; 2.291 + } 2.292 + 2.293 + int errors = 0; 2.294 + 2.295 + // ----- Annotation processor ----- 2.296 + 2.297 + int round = 0; 2.298 + 2.299 + @Override 2.300 + public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 2.301 + round++; 2.302 + 2.303 + ErrorKind ek = ErrorKind.valueOf(options.get("errKind")); 2.304 + WarnKind mwk = WarnKind.valueOf(options.get("msgrWarnKind")); 2.305 + WarnKind jwk = WarnKind.valueOf(options.get("javaWarnKind")); 2.306 + messager.printMessage(Diagnostic.Kind.NOTE, 2.307 + "Round " + round 2.308 + + " " + roundEnv.getRootElements() 2.309 + + ", last round: " + roundEnv.processingOver()); 2.310 + messager.printMessage(Diagnostic.Kind.NOTE, 2.311 + "ek: " + ek + ", mwk: " + mwk + ", jwk: " + jwk); 2.312 + 2.313 + if (round <= MAX_GEN && !roundEnv.processingOver()) 2.314 + generate("Gen" + round, 2.315 + (ek == ErrorKind.JAVA) && (round == ERROR_ROUND), 2.316 + jwk.warn(round)); 2.317 + 2.318 + if (mwk.warn(round)) 2.319 + messager.printMessage(Diagnostic.Kind.WARNING, "round " + round); 2.320 + 2.321 + if ((ek == ErrorKind.MESSAGER) && (round == ERROR_ROUND)) 2.322 + messager.printMessage(Diagnostic.Kind.ERROR, "round " + round); 2.323 + 2.324 + return true; 2.325 + } 2.326 + 2.327 + void generate(String name, boolean error, boolean warn) { 2.328 + try { 2.329 + JavaFileObject fo = filer.createSourceFile(name); 2.330 + Writer out = fo.openWriter(); 2.331 + try { 2.332 + out.write("class " + name + " {\n" 2.333 + + (warn ? " int i = (int) 0;\n" : "") 2.334 + + (error ? " ERROR\n" : "") 2.335 + + "}\n"); 2.336 + } finally { 2.337 + out.close(); 2.338 + } 2.339 + } catch (IOException e) { 2.340 + throw new Error(e); 2.341 + } 2.342 + } 2.343 +}
3.1 --- a/test/tools/javac/processing/warnings/gold_0.out Mon Feb 28 12:19:18 2011 -0800 3.2 +++ b/test/tools/javac/processing/warnings/gold_0.out Mon Feb 28 13:37:48 2011 -0800 3.3 @@ -1,1 +1,2 @@ 3.4 - compiler.warn.proc.messager: No SourceVersion option given 3.5 +1 warning
4.1 --- a/test/tools/javac/processing/warnings/gold_sv_warn_0_2.out Mon Feb 28 12:19:18 2011 -0800 4.2 +++ b/test/tools/javac/processing/warnings/gold_sv_warn_0_2.out Mon Feb 28 13:37:48 2011 -0800 4.3 @@ -1,1 +1,2 @@ 4.4 - compiler.warn.proc.processor.incompatible.source.version: RELEASE_0, TestSourceVersionWarnings, 1.2 4.5 +1 warning
5.1 --- a/test/tools/javac/processing/warnings/gold_sv_warn_2_3.out Mon Feb 28 12:19:18 2011 -0800 5.2 +++ b/test/tools/javac/processing/warnings/gold_sv_warn_2_3.out Mon Feb 28 13:37:48 2011 -0800 5.3 @@ -1,1 +1,2 @@ 5.4 - compiler.warn.proc.processor.incompatible.source.version: RELEASE_2, TestSourceVersionWarnings, 1.3 5.5 +1 warning
6.1 --- a/test/tools/javac/processing/warnings/gold_sv_warn_5_6.out Mon Feb 28 12:19:18 2011 -0800 6.2 +++ b/test/tools/javac/processing/warnings/gold_sv_warn_5_6.out Mon Feb 28 13:37:48 2011 -0800 6.3 @@ -1,1 +1,2 @@ 6.4 - compiler.warn.proc.processor.incompatible.source.version: RELEASE_5, TestSourceVersionWarnings, 1.6 6.5 +1 warning