Wed, 24 Sep 2014 11:38:26 -0700
Added tag jdk8u40-b07 for changeset 2fa3858a281f
1 /*
2 * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
24 /*
25 * @test
26 * @bug 6403465
27 * @summary javac should defer diagnostics until it can be determined they are persistent
28 */
30 import java.io.*;
31 import java.util.*;
32 import javax.annotation.processing.*;
33 import javax.lang.model.*;
34 import javax.lang.model.element.TypeElement;
35 import javax.tools.*;
37 import com.sun.source.util.JavacTask;
38 import com.sun.tools.javac.api.ClientCodeWrapper;
39 import com.sun.tools.javac.api.JavacTool;
40 import com.sun.tools.javac.util.JCDiagnostic;
42 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
45 public class TestSuppression {
46 public static void main(String... args) throws Exception {
47 new TestSuppression().run(args);
48 }
50 enum WarningKind { NO, YES };
52 String[] cases = {
53 // missing class C
54 "class X { C c; }",
55 "class X { C foo() { return null; } }",
56 "class X { void foo(C c) { } }",
57 "class X extends C { }",
58 "class X<T extends C> { }",
59 // missing interface I
60 "class X implements I { }",
61 "interface X extends I { }",
62 // missing exception E
63 "class X { void m() throws E { } }",
64 // missing method m
65 "class X extends C { int i = m(); }",
66 // missing field f
67 "class X extends C { int i = f; }"
68 };
70 void run(String... args) throws Exception {
71 for (String c: cases) {
72 for (WarningKind wk: WarningKind.values()) {
73 for (int g = 1; g <= 3; g++) {
74 try {
75 test(c, wk, g);
76 } catch (Throwable t) {
77 error("caught: " + t);
78 }
79 if (errors > 0) throw new AssertionError();
80 }
81 }
82 }
84 System.err.println(count + " test cases");
86 if (errors > 0)
87 throw new Exception(errors + " errors occurred");
88 }
90 void test(String src, WarningKind wk, int gen) throws Exception {
91 count++;
92 System.err.println("Test " + count + ": wk:" + wk + " gen:" + gen + " src:" +src);
94 File testDir = new File("test" + count);
95 File srcDir = createDir(testDir, "src");
96 File gensrcDir = createDir(testDir, "gensrc");
97 File classesDir = createDir(testDir, "classes");
99 File x = writeFile(new File(srcDir, "X.java"), src);
101 DiagListener dl = new DiagListener();
102 JavacTool tool = JavacTool.create();
103 StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null);
104 fm.setLocation(StandardLocation.CLASS_PATH,
105 Arrays.asList(classesDir, new File(System.getProperty("test.classes"))));
106 fm.setLocation(StandardLocation.CLASS_OUTPUT, Collections.singleton(classesDir));
107 fm.setLocation(StandardLocation.SOURCE_OUTPUT, Collections.singleton(gensrcDir));
108 List<String> args = new ArrayList<String>();
109 // args.add("-XprintProcessorInfo");
110 args.add("-XprintRounds");
111 args.add("-Agen=" + gen);
112 if (wk == WarningKind.YES)
113 args.add("-Xlint:serial");
114 Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(x);
116 StringWriter sw = new StringWriter();
117 PrintWriter pw = new PrintWriter(sw);
118 JavacTask task = tool.getTask(pw, fm, dl, args, null, files);
119 task.setProcessors(Arrays.asList(new AnnoProc()));
120 boolean ok = task.call();
121 pw.close();
123 System.err.println("ok:" + ok + " diags:" + dl.counts);
124 if (sw.toString().length() > 0) {
125 System.err.println("output:\n" + sw.toString());
126 }
128 for (Diagnostic.Kind dk: Diagnostic.Kind.values()) {
129 Integer v = dl.counts.get(dk);
130 int found = (v == null) ? 0 : v;
131 int expect = (dk == Diagnostic.Kind.WARNING && wk == WarningKind.YES) ? gen : 0;
132 if (found != expect) {
133 error("Unexpected value for " + dk + ": expected: " + expect + " found: " + found);
134 }
135 }
137 System.err.println();
138 }
140 File createDir(File parent, String name) {
141 File dir = new File(parent, name);
142 dir.mkdirs();
143 return dir;
144 }
146 File writeFile(File f, String content) throws IOException {
147 FileWriter out = new FileWriter(f);
148 try {
149 out.write(content);
150 } finally {
151 out.close();
152 }
153 return f;
154 }
156 <T> void add(List<T> list, T... values) {
157 for (T v: values)
158 list.add(v);
159 }
161 void error(String msg) {
162 System.err.println("Error: " + msg);
163 errors++;
164 }
166 int count;
167 int errors;
169 static class DiagListener implements DiagnosticListener<JavaFileObject> {
170 int total;
171 Map<Diagnostic.Kind,Integer> counts = new TreeMap<Diagnostic.Kind,Integer>();
173 public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
174 System.err.println((++total) + ": "
175 + "resolveError:" + isResolveError(unwrap(diagnostic)) + "\n"
176 + diagnostic);
177 Diagnostic.Kind dk = diagnostic.getKind();
178 Integer c = counts.get(dk);
179 counts.put(dk, (c == null ? 1 : c + 1));
180 }
182 private static boolean isResolveError(JCDiagnostic d) {
183 return d.isFlagSet(RESOLVE_ERROR);
184 }
186 private JCDiagnostic unwrap(Diagnostic<? extends JavaFileObject> diagnostic) {
187 if (diagnostic instanceof JCDiagnostic)
188 return (JCDiagnostic) diagnostic;
189 if (diagnostic instanceof ClientCodeWrapper.DiagnosticSourceUnwrapper)
190 return ((ClientCodeWrapper.DiagnosticSourceUnwrapper)diagnostic).d;
191 throw new IllegalArgumentException();
192 }
193 }
195 @SupportedAnnotationTypes("*")
196 @SupportedOptions("gen")
197 public static class AnnoProc extends AbstractProcessor {
198 Filer f;
199 Messager m;
200 int gen;
202 @Override
203 public void init(ProcessingEnvironment processingEnv) {
204 f = processingEnv.getFiler();
205 m = processingEnv.getMessager();
206 Map<String,String> options = processingEnv.getOptions();
207 gen = Integer.parseInt(options.get("gen"));
208 }
210 @Override
211 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
212 round++;
213 if (round < gen)
214 writeSource("Dummy" + round, "class Dummy" + round + " extends java.util.ArrayList{ }");
215 else if (round == gen) {
216 writeSource("C", "class C { int f; int m() { return 0; } }");
217 writeSource("I", "interface I { }");
218 writeSource("E", "class E extends Exception { }");
219 }
220 return true;
221 }
223 @Override
224 public SourceVersion getSupportedSourceVersion() {
225 return SourceVersion.latest();
226 }
228 private void writeSource(String name, String text) {
229 try {
230 JavaFileObject fo = f.createSourceFile(name);
231 Writer out = fo.openWriter();
232 out.write(text);
233 out.close();
234 } catch (IOException e) {
235 m.printMessage(Diagnostic.Kind.ERROR, e.toString());
236 }
237 }
239 int round = 0;
240 }
241 }