Warn4.java revision 3019:176472b94f2e
1/* 2 * Copyright (c) 2010, 2015, 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 */ 23 24/** 25 * @test 26 * @bug 6945418 6993978 8006694 7196160 8129962 27 * @summary Project Coin: Simplified Varargs Method Invocation 28 * temporarily workaround combo tests are causing time out in several platforms 29 * @library /tools/javac/lib 30 * @modules jdk.compiler/com.sun.tools.javac.api 31 * jdk.compiler/com.sun.tools.javac.code 32 * jdk.compiler/com.sun.tools.javac.comp 33 * jdk.compiler/com.sun.tools.javac.main 34 * jdk.compiler/com.sun.tools.javac.tree 35 * jdk.compiler/com.sun.tools.javac.util 36 * @build combo.ComboTestHelper 37 * @run main Warn4 38 */ 39 40import java.io.IOException; 41import java.util.Set; 42import java.util.HashSet; 43import javax.tools.Diagnostic; 44import javax.tools.Diagnostic.Kind; 45import javax.tools.JavaFileObject; 46 47import combo.ComboInstance; 48import combo.ComboParameter; 49import combo.ComboTask.Result; 50import combo.ComboTestHelper; 51 52public class Warn4 extends ComboInstance<Warn4> { 53 54 final static Warning[] error = null; 55 final static Warning[] none = new Warning[] {}; 56 final static Warning[] vararg = new Warning[] { Warning.VARARGS }; 57 final static Warning[] unchecked = new Warning[] { Warning.UNCHECKED }; 58 final static Warning[] both = new Warning[] { Warning.VARARGS, Warning.UNCHECKED }; 59 60 enum Warning { 61 UNCHECKED("generic.array.creation"), 62 VARARGS("varargs.non.reifiable.type"); 63 64 String key; 65 66 Warning(String key) { 67 this.key = key; 68 } 69 70 boolean isSuppressed(TrustMe trustMe, SourceLevel source, 71 SuppressLevel suppressLevelClient, 72 SuppressLevel suppressLevelDecl, 73 ModifierKind modKind) { 74 switch(this) { 75 case VARARGS: 76 return source.compareTo(SourceLevel.JDK_7) < 0 || 77 suppressLevelDecl == SuppressLevel.UNCHECKED || 78 trustMe == TrustMe.TRUST; 79 case UNCHECKED: 80 return suppressLevelClient == SuppressLevel.UNCHECKED || 81 (trustMe == TrustMe.TRUST && 82 (((modKind == ModifierKind.FINAL || modKind == ModifierKind.STATIC) && 83 source.compareTo( SourceLevel.JDK_7) >= 0 ) || 84 (modKind == ModifierKind.PRIVATE && source.compareTo( SourceLevel.JDK_9) >= 0 ))); 85 } 86 87 SuppressLevel supLev = this == VARARGS ? 88 suppressLevelDecl : 89 suppressLevelClient; 90 return supLev == SuppressLevel.UNCHECKED || 91 (trustMe == TrustMe.TRUST && modKind != ModifierKind.NONE); 92 } 93 } 94 95 enum SourceLevel { 96 JDK_6("6"), 97 JDK_7("7"), 98 JDK_9("9"); 99 100 String sourceKey; 101 102 SourceLevel(String sourceKey) { 103 this.sourceKey = sourceKey; 104 } 105 } 106 107 enum TrustMe implements ComboParameter { 108 DONT_TRUST(""), 109 TRUST("@java.lang.SafeVarargs"); 110 111 String anno; 112 113 TrustMe(String anno) { 114 this.anno = anno; 115 } 116 117 @Override 118 public String expand(String optParameter) { 119 return anno; 120 } 121 } 122 123 enum ModifierKind implements ComboParameter { 124 NONE(" "), 125 FINAL("final "), 126 STATIC("static "), 127 PRIVATE("private "); 128 129 String mod; 130 131 ModifierKind(String mod) { 132 this.mod = mod; 133 } 134 135 @Override 136 public String expand(String optParameter) { 137 return mod; 138 } 139 } 140 141 enum SuppressLevel implements ComboParameter { 142 NONE(""), 143 UNCHECKED("unchecked"); 144 145 String lint; 146 147 SuppressLevel(String lint) { 148 this.lint = lint; 149 } 150 151 @Override 152 public String expand(String optParameter) { 153 return "@SuppressWarnings(\"" + lint + "\")"; 154 } 155 } 156 157 enum Signature implements ComboParameter { 158 UNBOUND("void #NAME(List<?>#ARITY arg) { #BODY }", 159 new Warning[][] {none, none, none, none, error}), 160 INVARIANT_TVAR("<Z> void #NAME(List<Z>#ARITY arg) { #BODY }", 161 new Warning[][] {both, both, error, both, error}), 162 TVAR("<Z> void #NAME(Z#ARITY arg) { #BODY }", 163 new Warning[][] {both, both, both, both, vararg}), 164 INVARIANT("void #NAME(List<String>#ARITY arg) { #BODY }", 165 new Warning[][] {error, error, error, both, error}), 166 UNPARAMETERIZED("void #NAME(String#ARITY arg) { #BODY }", 167 new Warning[][] {error, error, error, error, none}); 168 169 String template; 170 Warning[][] warnings; 171 172 Signature(String template, Warning[][] warnings) { 173 this.template = template; 174 this.warnings = warnings; 175 } 176 177 boolean isApplicableTo(Signature other) { 178 return warnings[other.ordinal()] != null; 179 } 180 181 boolean giveUnchecked(Signature other) { 182 return warnings[other.ordinal()] == unchecked || 183 warnings[other.ordinal()] == both; 184 } 185 186 boolean giveVarargs(Signature other) { 187 return warnings[other.ordinal()] == vararg || 188 warnings[other.ordinal()] == both; 189 } 190 191 @Override 192 public String expand(String optParameter) { 193 if (optParameter.equals("CLIENT")) { 194 return template.replaceAll("#ARITY", "") 195 .replaceAll("#NAME", "test") 196 .replaceAll("#BODY", "m(arg)"); 197 } else { 198 return template.replaceAll("#ARITY", "...") 199 .replaceAll("#NAME", "m") 200 .replaceAll("#BODY", ""); 201 } 202 } 203 } 204 205 public static void main(String... args) { 206 new ComboTestHelper<Warn4>() 207 .withFilter(Warn4::badTestFilter) 208 .withDimension("SOURCE", (x, level) -> x.sourceLevel = level, SourceLevel.values()) 209 .withDimension("TRUSTME", (x, trustme) -> x.trustMe = trustme, TrustMe.values()) 210 .withArrayDimension("SUPPRESS", (x, suppress, idx) -> x.suppress[idx] = suppress, 2, SuppressLevel.values()) 211 .withDimension("MOD", (x, mod) -> x.modKind = mod, ModifierKind.values()) 212 .withArrayDimension("MTH", (x, sig, idx) -> x.sigs[idx] = sig, 2, Signature.values()) 213 .run(Warn4::new); 214 } 215 216 SourceLevel sourceLevel; 217 TrustMe trustMe; 218 SuppressLevel[] suppress = new SuppressLevel[2]; 219 ModifierKind modKind; 220 Signature[] sigs = new Signature[2]; 221 222 boolean badTestFilter() { 223 return sigs[0].isApplicableTo(sigs[1]); 224 } 225 226 final String template = "import java.util.List;\n" + 227 "class Test {\n" + 228 " #{TRUSTME} #{SUPPRESS[0]} #{MOD} #{MTH[0].VARARG}\n" + 229 " #{SUPPRESS[1]} #{MTH[1].CLIENT}\n" + 230 "}"; 231 232 @Override 233 public void doWork() throws IOException { 234 check(newCompilationTask() 235 .withOption("-Xlint:unchecked") 236 .withOption("-source") 237 .withOption(sourceLevel.sourceKey) 238 .withSourceFromTemplate(template) 239 .analyze()); 240 } 241 242 void check(Result<?> res) { 243 boolean[] warnArr = new boolean[] {sigs[0].giveUnchecked(sigs[1]), 244 sigs[0].giveVarargs(sigs[1])}; 245 246 Set<Warning> warnings = new HashSet<>(); 247 for (Diagnostic<? extends JavaFileObject> d : res.diagnosticsForKind(Kind.MANDATORY_WARNING)) { 248 if (d.getCode().contains(Warning.VARARGS.key)) { 249 warnings.add(Warning.VARARGS); 250 } else if(d.getCode().contains(Warning.UNCHECKED.key)) { 251 warnings.add(Warning.UNCHECKED); 252 } 253 } 254 255 boolean badOutput = false; 256 for (Warning wkind : Warning.values()) { 257 boolean isSuppressed = wkind.isSuppressed(trustMe, sourceLevel, 258 suppress[1], suppress[0], modKind); 259 badOutput |= (warnArr[wkind.ordinal()] && !isSuppressed) != 260 warnings.contains(wkind); 261 } 262 if (badOutput) { 263 fail("invalid diagnostics for source:\n" + 264 res.compilationInfo() + 265 "\nExpected unchecked warning: " + warnArr[0] + 266 "\nExpected unsafe vararg warning: " + warnArr[1] + 267 "\nWarnings: " + warnings + 268 "\nSource level: " + sourceLevel); 269 } 270 } 271} 272