test/tools/javac/varargs/warning/Warn4.java

changeset 580
46cf751559ae
child 581
f2fdd52e4e87
equal deleted inserted replaced
579:d33b91f360fc 580:46cf751559ae
1 /*
2 * Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24 /**
25 * @test
26 * @bug 6945418
27 * @summary Project Coin: Simplified Varargs Method Invocation
28 * @author mcimadamore
29 * @run main Warn4
30 */
31 import com.sun.source.util.JavacTask;
32 import java.net.URI;
33 import java.util.Arrays;
34 import java.util.Set;
35 import java.util.HashSet;
36 import javax.tools.Diagnostic;
37 import javax.tools.JavaCompiler;
38 import javax.tools.JavaFileObject;
39 import javax.tools.SimpleJavaFileObject;
40 import javax.tools.ToolProvider;
41
42 public class Warn4 {
43
44 final static Warning[] error = null;
45 final static Warning[] none = new Warning[] {};
46 final static Warning[] vararg = new Warning[] { Warning.VARARGS };
47 final static Warning[] unchecked = new Warning[] { Warning.UNCHECKED };
48 final static Warning[] both = new Warning[] { Warning.VARARGS, Warning.UNCHECKED };
49
50 enum Warning {
51 UNCHECKED("unchecked"),
52 VARARGS("varargs");
53
54 String category;
55
56 Warning(String category) {
57 this.category = category;
58 }
59
60 boolean isEnabled(XlintOption xlint, SuppressLevel suppressLevel) {
61 return Arrays.asList(xlint.enabledWarnings).contains(this);
62 }
63
64 boolean isSuppressed(SuppressLevel suppressLevel) {
65 return Arrays.asList(suppressLevel.suppressedWarnings).contains(VARARGS);
66 }
67 }
68
69 enum XlintOption {
70 NONE(),
71 UNCHECKED(Warning.UNCHECKED),
72 VARARGS(Warning.VARARGS),
73 ALL(Warning.UNCHECKED, Warning.VARARGS);
74
75 Warning[] enabledWarnings;
76
77 XlintOption(Warning... enabledWarnings) {
78 this.enabledWarnings = enabledWarnings;
79 }
80
81 String getXlintOption() {
82 StringBuilder buf = new StringBuilder();
83 String sep = "";
84 for (Warning w : enabledWarnings) {
85 buf.append(sep);
86 buf.append(w.category);
87 sep=",";
88 }
89 return "-Xlint:" +
90 (this == NONE ? "none" : buf.toString());
91 }
92 }
93
94 enum SuppressLevel {
95 NONE(),
96 UNCHECKED(Warning.UNCHECKED),
97 VARARGS(Warning.VARARGS),
98 ALL(Warning.UNCHECKED, Warning.VARARGS);
99
100 Warning[] suppressedWarnings;
101
102 SuppressLevel(Warning... suppressedWarnings) {
103 this.suppressedWarnings = suppressedWarnings;
104 }
105
106 String getSuppressAnnotation() {
107 StringBuilder buf = new StringBuilder();
108 String sep = "";
109 for (Warning w : suppressedWarnings) {
110 buf.append(sep);
111 buf.append("\"");
112 buf.append(w.category);
113 buf.append("\"");
114 sep=",";
115 }
116 return this == NONE ? "" :
117 "@SuppressWarnings({" + buf.toString() + "})";
118 }
119 }
120
121 enum Signature {
122
123 EXTENDS_TVAR("<Z> void #name(List<? extends Z>#arity arg) { #body }",
124 new Warning[][] {both, both, both, both, error, both, both, both, error}),
125 SUPER_TVAR("<Z> void #name(List<? super Z>#arity arg) { #body }",
126 new Warning[][] {error, both, error, both, error, error, both, both, error}),
127 UNBOUND("void #name(List<?>#arity arg) { #body }",
128 new Warning[][] {none, none, none, none, none, none, none, none, error}),
129 INVARIANT_TVAR("<Z> void #name(List<Z>#arity arg) { #body }",
130 new Warning[][] {both, both, both, both, error, both, both, both, error}),
131 TVAR("<Z> void #name(Z#arity arg) { #body }",
132 new Warning[][] {both, both, both, both, both, both, both, both, vararg}),
133 EXTENDS("void #name(List<? extends String>#arity arg) { #body }",
134 new Warning[][] {error, error, error, error, error, both, error, both, error}),
135 SUPER("void #name(List<? super String>#arity arg) { #body }",
136 new Warning[][] {error, error, error, error, error, error, both, both, error}),
137 INVARIANT("void #name(List<String>#arity arg) { #body }",
138 new Warning[][] {error, error, error, error, error, error, error, both, error}),
139 UNPARAMETERIZED("void #name(String#arity arg) { #body }",
140 new Warning[][] {error, error, error, error, error, error, error, error, none});
141
142 String template;
143 Warning[][] warnings;
144
145 Signature(String template, Warning[][] warnings) {
146 this.template = template;
147 this.warnings = warnings;
148 }
149
150 boolean isApplicableTo(Signature other) {
151 return warnings[other.ordinal()] != null;
152 }
153
154 boolean giveUnchecked(Signature other) {
155 return warnings[other.ordinal()] == unchecked ||
156 warnings[other.ordinal()] == both;
157 }
158
159 boolean giveVarargs(Signature other) {
160 return warnings[other.ordinal()] == vararg ||
161 warnings[other.ordinal()] == both;
162 }
163 }
164
165 public static void main(String... args) throws Exception {
166 for (XlintOption xlint : XlintOption.values()) {
167 for (SuppressLevel suppressLevel : SuppressLevel.values()) {
168 for (Signature vararg_meth : Signature.values()) {
169 for (Signature client_meth : Signature.values()) {
170 if (vararg_meth.isApplicableTo(client_meth)) {
171 test(xlint,
172 suppressLevel,
173 vararg_meth,
174 client_meth);
175 }
176 }
177 }
178 }
179 }
180 }
181
182 static void test(XlintOption xlint, SuppressLevel suppressLevel,
183 Signature vararg_meth, Signature client_meth) throws Exception {
184 final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
185 JavaSource source = new JavaSource(suppressLevel, vararg_meth, client_meth);
186 DiagnosticChecker dc = new DiagnosticChecker();
187 JavacTask ct = (JavacTask)tool.getTask(null, null, dc,
188 Arrays.asList(xlint.getXlintOption()), null, Arrays.asList(source));
189 ct.generate(); //to get mandatory notes
190 check(dc.warnings,
191 dc.notes,
192 new boolean[] {vararg_meth.giveUnchecked(client_meth),
193 vararg_meth.giveVarargs(client_meth)},
194 source, xlint, suppressLevel);
195 }
196
197 static void check(Set<Warning> warnings, Set<Warning> notes, boolean[] warnArr, JavaSource source, XlintOption xlint, SuppressLevel suppressLevel) {
198 boolean badOutput = false;
199 for (Warning wkind : Warning.values()) {
200 badOutput |= (warnArr[wkind.ordinal()] && !wkind.isSuppressed(suppressLevel)) !=
201 (wkind.isEnabled(xlint, suppressLevel) ?
202 warnings.contains(wkind) :
203 notes.contains(wkind));
204 }
205 if (badOutput) {
206 throw new Error("invalid diagnostics for source:\n" +
207 source.getCharContent(true) +
208 "\nOptions: " + xlint.getXlintOption() +
209 "\nExpected unchecked warning: " + warnArr[0] +
210 "\nExpected unsafe vararg warning: " + warnArr[1] +
211 "\nWarnings: " + warnings +
212 "\nNotes: " + notes);
213 }
214 }
215
216 static class JavaSource extends SimpleJavaFileObject {
217
218 String source;
219
220 public JavaSource(SuppressLevel suppressLevel, Signature vararg_meth, Signature client_meth) {
221 super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
222 String meth1 = vararg_meth.template.replace("#arity", "...");
223 meth1 = meth1.replace("#name", "m");
224 meth1 = meth1.replace("#body", "");
225 meth1 = suppressLevel.getSuppressAnnotation() + meth1;
226 String meth2 = client_meth.template.replace("#arity", "");
227 meth2 = meth2.replace("#name", "test");
228 meth2 = meth2.replace("#body", "m(arg);");
229 source = "import java.util.List;\n" +
230 "class Test {\n" + meth1 +
231 "\n" + meth2 + "\n}\n";
232 }
233
234 @Override
235 public CharSequence getCharContent(boolean ignoreEncodingErrors) {
236 return source;
237 }
238 }
239
240 static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
241
242 Set<Warning> warnings = new HashSet<>();
243 Set<Warning> notes = new HashSet<>();
244
245 public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
246 if (diagnostic.getKind() == Diagnostic.Kind.MANDATORY_WARNING ||
247 diagnostic.getKind() == Diagnostic.Kind.WARNING) {
248 warnings.add(diagnostic.getCode().contains("varargs") ?
249 Warning.VARARGS :
250 Warning.UNCHECKED);
251 }
252 else if (diagnostic.getKind() == Diagnostic.Kind.NOTE) {
253 notes.add(diagnostic.getCode().contains("varargs") ?
254 Warning.VARARGS :
255 Warning.UNCHECKED);
256 }
257 }
258 }
259 }

mercurial