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

Thu, 31 Aug 2017 15:17:03 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:17:03 +0800
changeset 2525
2eb010b6cb22
parent 1520
5c956be64b9e
parent 0
959103a6100f
permissions
-rw-r--r--

merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 */
aoqi@0 23
aoqi@0 24 /**
aoqi@0 25 * @test
aoqi@0 26 * @bug 6993978 7097436 8006694
aoqi@0 27 * @summary Project Coin: Annotation to reduce varargs warnings
aoqi@0 28 * temporarily workaround combo tests are causing time out in several platforms
aoqi@0 29 * @author mcimadamore
aoqi@0 30 * @library ../../lib
aoqi@0 31 * @build JavacTestingAbstractThreadedTest
aoqi@0 32 * @run main/othervm Warn5
aoqi@0 33 */
aoqi@0 34
aoqi@0 35 // use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
aoqi@0 36 // see JDK-8006746
aoqi@0 37
aoqi@0 38 import java.net.URI;
aoqi@0 39 import java.util.Arrays;
aoqi@0 40 import java.util.EnumSet;
aoqi@0 41 import javax.tools.Diagnostic;
aoqi@0 42 import javax.tools.JavaCompiler;
aoqi@0 43 import javax.tools.JavaFileObject;
aoqi@0 44 import javax.tools.SimpleJavaFileObject;
aoqi@0 45 import javax.tools.ToolProvider;
aoqi@0 46 import com.sun.source.util.JavacTask;
aoqi@0 47
aoqi@0 48 public class Warn5
aoqi@0 49 extends JavacTestingAbstractThreadedTest
aoqi@0 50 implements Runnable {
aoqi@0 51
aoqi@0 52 enum XlintOption {
aoqi@0 53 NONE("none"),
aoqi@0 54 ALL("all");
aoqi@0 55
aoqi@0 56 String opt;
aoqi@0 57
aoqi@0 58 XlintOption(String opt) {
aoqi@0 59 this.opt = opt;
aoqi@0 60 }
aoqi@0 61
aoqi@0 62 String getXlintOption() {
aoqi@0 63 return "-Xlint:" + opt;
aoqi@0 64 }
aoqi@0 65 }
aoqi@0 66
aoqi@0 67 enum TrustMe {
aoqi@0 68 DONT_TRUST(""),
aoqi@0 69 TRUST("@java.lang.SafeVarargs");
aoqi@0 70
aoqi@0 71 String anno;
aoqi@0 72
aoqi@0 73 TrustMe(String anno) {
aoqi@0 74 this.anno = anno;
aoqi@0 75 }
aoqi@0 76 }
aoqi@0 77
aoqi@0 78 enum SuppressLevel {
aoqi@0 79 NONE,
aoqi@0 80 VARARGS;
aoqi@0 81
aoqi@0 82 String getSuppressAnno() {
aoqi@0 83 return this == VARARGS ?
aoqi@0 84 "@SuppressWarnings(\"varargs\")" :
aoqi@0 85 "";
aoqi@0 86 }
aoqi@0 87 }
aoqi@0 88
aoqi@0 89 enum ModifierKind {
aoqi@0 90 NONE(""),
aoqi@0 91 FINAL("final"),
aoqi@0 92 STATIC("static");
aoqi@0 93
aoqi@0 94 String mod;
aoqi@0 95
aoqi@0 96 ModifierKind(String mod) {
aoqi@0 97 this.mod = mod;
aoqi@0 98 }
aoqi@0 99 }
aoqi@0 100
aoqi@0 101 enum MethodKind {
aoqi@0 102 METHOD("void m"),
aoqi@0 103 CONSTRUCTOR("Test");
aoqi@0 104
aoqi@0 105 String name;
aoqi@0 106
aoqi@0 107 MethodKind(String name) {
aoqi@0 108 this.name = name;
aoqi@0 109 }
aoqi@0 110 }
aoqi@0 111
aoqi@0 112 enum SourceLevel {
aoqi@0 113 JDK_6("6"),
aoqi@0 114 JDK_7("7");
aoqi@0 115
aoqi@0 116 String sourceKey;
aoqi@0 117
aoqi@0 118 SourceLevel(String sourceKey) {
aoqi@0 119 this.sourceKey = sourceKey;
aoqi@0 120 }
aoqi@0 121 }
aoqi@0 122
aoqi@0 123 enum SignatureKind {
aoqi@0 124 VARARGS_X("#K <X>#N(X... x)", false, true),
aoqi@0 125 VARARGS_STRING("#K #N(String... x)", true, true),
aoqi@0 126 ARRAY_X("#K <X>#N(X[] x)", false, false),
aoqi@0 127 ARRAY_STRING("#K #N(String[] x)", true, false);
aoqi@0 128
aoqi@0 129 String stub;
aoqi@0 130 boolean isReifiableArg;
aoqi@0 131 boolean isVarargs;
aoqi@0 132
aoqi@0 133 SignatureKind(String stub, boolean isReifiableArg, boolean isVarargs) {
aoqi@0 134 this.stub = stub;
aoqi@0 135 this.isReifiableArg = isReifiableArg;
aoqi@0 136 this.isVarargs = isVarargs;
aoqi@0 137 }
aoqi@0 138
aoqi@0 139 String getSignature(ModifierKind modKind, MethodKind methKind) {
aoqi@0 140 return methKind != MethodKind.CONSTRUCTOR ?
aoqi@0 141 stub.replace("#K", modKind.mod).replace("#N", methKind.name) :
aoqi@0 142 stub.replace("#K", "").replace("#N", methKind.name);
aoqi@0 143 }
aoqi@0 144 }
aoqi@0 145
aoqi@0 146 enum BodyKind {
aoqi@0 147 ASSIGN("Object o = x;", true),
aoqi@0 148 CAST("Object o = (Object)x;", true),
aoqi@0 149 METH("test(x);", true),
aoqi@0 150 PRINT("System.out.println(x.toString());", false),
aoqi@0 151 ARRAY_ASSIGN("Object[] o = x;", true),
aoqi@0 152 ARRAY_CAST("Object[] o = (Object[])x;", true),
aoqi@0 153 ARRAY_METH("testArr(x);", true);
aoqi@0 154
aoqi@0 155 String body;
aoqi@0 156 boolean hasAliasing;
aoqi@0 157
aoqi@0 158 BodyKind(String body, boolean hasAliasing) {
aoqi@0 159 this.body = body;
aoqi@0 160 this.hasAliasing = hasAliasing;
aoqi@0 161 }
aoqi@0 162 }
aoqi@0 163
aoqi@0 164 enum WarningKind {
aoqi@0 165 UNSAFE_BODY,
aoqi@0 166 UNSAFE_DECL,
aoqi@0 167 MALFORMED_SAFEVARARGS,
aoqi@0 168 REDUNDANT_SAFEVARARGS;
aoqi@0 169 }
aoqi@0 170
aoqi@0 171 public static void main(String... args) throws Exception {
aoqi@0 172 for (SourceLevel sourceLevel : SourceLevel.values()) {
aoqi@0 173 for (XlintOption xlint : XlintOption.values()) {
aoqi@0 174 for (TrustMe trustMe : TrustMe.values()) {
aoqi@0 175 for (SuppressLevel suppressLevel : SuppressLevel.values()) {
aoqi@0 176 for (ModifierKind modKind : ModifierKind.values()) {
aoqi@0 177 for (MethodKind methKind : MethodKind.values()) {
aoqi@0 178 for (SignatureKind sig : SignatureKind.values()) {
aoqi@0 179 for (BodyKind body : BodyKind.values()) {
aoqi@0 180 pool.execute(new Warn5(sourceLevel,
aoqi@0 181 xlint, trustMe, suppressLevel,
aoqi@0 182 modKind, methKind, sig, body));
aoqi@0 183 }
aoqi@0 184 }
aoqi@0 185 }
aoqi@0 186 }
aoqi@0 187 }
aoqi@0 188 }
aoqi@0 189 }
aoqi@0 190 }
aoqi@0 191
aoqi@0 192 checkAfterExec(false);
aoqi@0 193 }
aoqi@0 194
aoqi@0 195 final SourceLevel sourceLevel;
aoqi@0 196 final XlintOption xlint;
aoqi@0 197 final TrustMe trustMe;
aoqi@0 198 final SuppressLevel suppressLevel;
aoqi@0 199 final ModifierKind modKind;
aoqi@0 200 final MethodKind methKind;
aoqi@0 201 final SignatureKind sig;
aoqi@0 202 final BodyKind body;
aoqi@0 203 final JavaSource source;
aoqi@0 204 final DiagnosticChecker dc;
aoqi@0 205
aoqi@0 206 public Warn5(SourceLevel sourceLevel, XlintOption xlint, TrustMe trustMe,
aoqi@0 207 SuppressLevel suppressLevel, ModifierKind modKind,
aoqi@0 208 MethodKind methKind, SignatureKind sig, BodyKind body) {
aoqi@0 209 this.sourceLevel = sourceLevel;
aoqi@0 210 this.xlint = xlint;
aoqi@0 211 this.trustMe = trustMe;
aoqi@0 212 this.suppressLevel = suppressLevel;
aoqi@0 213 this.modKind = modKind;
aoqi@0 214 this.methKind = methKind;
aoqi@0 215 this.sig = sig;
aoqi@0 216 this.body = body;
aoqi@0 217 this.source = new JavaSource();
aoqi@0 218 this.dc = new DiagnosticChecker();
aoqi@0 219 }
aoqi@0 220
aoqi@0 221 @Override
aoqi@0 222 public void run() {
aoqi@0 223 final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
aoqi@0 224 JavacTask ct = (JavacTask)tool.getTask(null, fm.get(), dc,
aoqi@0 225 Arrays.asList(xlint.getXlintOption(),
aoqi@0 226 "-source", sourceLevel.sourceKey),
aoqi@0 227 null, Arrays.asList(source));
aoqi@0 228 try {
aoqi@0 229 ct.analyze();
aoqi@0 230 } catch (Throwable t) {
aoqi@0 231 processException(t);
aoqi@0 232 }
aoqi@0 233 check();
aoqi@0 234 }
aoqi@0 235
aoqi@0 236 void check() {
aoqi@0 237
aoqi@0 238 EnumSet<WarningKind> expectedWarnings =
aoqi@0 239 EnumSet.noneOf(WarningKind.class);
aoqi@0 240
aoqi@0 241 if (sourceLevel == SourceLevel.JDK_7 &&
aoqi@0 242 trustMe == TrustMe.TRUST &&
aoqi@0 243 suppressLevel != SuppressLevel.VARARGS &&
aoqi@0 244 xlint != XlintOption.NONE &&
aoqi@0 245 sig.isVarargs &&
aoqi@0 246 !sig.isReifiableArg &&
aoqi@0 247 body.hasAliasing &&
aoqi@0 248 (methKind == MethodKind.CONSTRUCTOR ||
aoqi@0 249 (methKind == MethodKind.METHOD &&
aoqi@0 250 modKind != ModifierKind.NONE))) {
aoqi@0 251 expectedWarnings.add(WarningKind.UNSAFE_BODY);
aoqi@0 252 }
aoqi@0 253
aoqi@0 254 if (sourceLevel == SourceLevel.JDK_7 &&
aoqi@0 255 trustMe == TrustMe.DONT_TRUST &&
aoqi@0 256 sig.isVarargs &&
aoqi@0 257 !sig.isReifiableArg &&
aoqi@0 258 xlint == XlintOption.ALL) {
aoqi@0 259 expectedWarnings.add(WarningKind.UNSAFE_DECL);
aoqi@0 260 }
aoqi@0 261
aoqi@0 262 if (sourceLevel == SourceLevel.JDK_7 &&
aoqi@0 263 trustMe == TrustMe.TRUST &&
aoqi@0 264 (!sig.isVarargs ||
aoqi@0 265 (modKind == ModifierKind.NONE &&
aoqi@0 266 methKind == MethodKind.METHOD))) {
aoqi@0 267 expectedWarnings.add(WarningKind.MALFORMED_SAFEVARARGS);
aoqi@0 268 }
aoqi@0 269
aoqi@0 270 if (sourceLevel == SourceLevel.JDK_7 &&
aoqi@0 271 trustMe == TrustMe.TRUST &&
aoqi@0 272 xlint != XlintOption.NONE &&
aoqi@0 273 suppressLevel != SuppressLevel.VARARGS &&
aoqi@0 274 (modKind != ModifierKind.NONE ||
aoqi@0 275 methKind == MethodKind.CONSTRUCTOR) &&
aoqi@0 276 sig.isVarargs &&
aoqi@0 277 sig.isReifiableArg) {
aoqi@0 278 expectedWarnings.add(WarningKind.REDUNDANT_SAFEVARARGS);
aoqi@0 279 }
aoqi@0 280
aoqi@0 281 if (!expectedWarnings.containsAll(dc.warnings) ||
aoqi@0 282 !dc.warnings.containsAll(expectedWarnings)) {
aoqi@0 283 throw new Error("invalid diagnostics for source:\n" +
aoqi@0 284 source.getCharContent(true) +
aoqi@0 285 "\nOptions: " + xlint.getXlintOption() +
aoqi@0 286 "\nExpected warnings: " + expectedWarnings +
aoqi@0 287 "\nFound warnings: " + dc.warnings);
aoqi@0 288 }
aoqi@0 289 }
aoqi@0 290
aoqi@0 291 class JavaSource extends SimpleJavaFileObject {
aoqi@0 292
aoqi@0 293 String template = "import com.sun.tools.javac.api.*;\n" +
aoqi@0 294 "import java.util.List;\n" +
aoqi@0 295 "class Test {\n" +
aoqi@0 296 " static void test(Object o) {}\n" +
aoqi@0 297 " static void testArr(Object[] o) {}\n" +
aoqi@0 298 " #T \n #S #M { #B }\n" +
aoqi@0 299 "}\n";
aoqi@0 300
aoqi@0 301 String source;
aoqi@0 302
aoqi@0 303 public JavaSource() {
aoqi@0 304 super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
aoqi@0 305 source = template.replace("#T", trustMe.anno).
aoqi@0 306 replace("#S", suppressLevel.getSuppressAnno()).
aoqi@0 307 replace("#M", sig.getSignature(modKind, methKind)).
aoqi@0 308 replace("#B", body.body);
aoqi@0 309 }
aoqi@0 310
aoqi@0 311 @Override
aoqi@0 312 public CharSequence getCharContent(boolean ignoreEncodingErrors) {
aoqi@0 313 return source;
aoqi@0 314 }
aoqi@0 315 }
aoqi@0 316
aoqi@0 317 class DiagnosticChecker
aoqi@0 318 implements javax.tools.DiagnosticListener<JavaFileObject> {
aoqi@0 319
aoqi@0 320 EnumSet<WarningKind> warnings = EnumSet.noneOf(WarningKind.class);
aoqi@0 321
aoqi@0 322 public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
aoqi@0 323 if (diagnostic.getKind() == Diagnostic.Kind.WARNING) {
aoqi@0 324 if (diagnostic.getCode().
aoqi@0 325 contains("unsafe.use.varargs.param")) {
aoqi@0 326 setWarning(WarningKind.UNSAFE_BODY);
aoqi@0 327 } else if (diagnostic.getCode().
aoqi@0 328 contains("redundant.trustme")) {
aoqi@0 329 setWarning(WarningKind.REDUNDANT_SAFEVARARGS);
aoqi@0 330 }
aoqi@0 331 } else if (diagnostic.getKind() == Diagnostic.Kind.MANDATORY_WARNING &&
aoqi@0 332 diagnostic.getCode().
aoqi@0 333 contains("varargs.non.reifiable.type")) {
aoqi@0 334 setWarning(WarningKind.UNSAFE_DECL);
aoqi@0 335 } else if (diagnostic.getKind() == Diagnostic.Kind.ERROR &&
aoqi@0 336 diagnostic.getCode().contains("invalid.trustme")) {
aoqi@0 337 setWarning(WarningKind.MALFORMED_SAFEVARARGS);
aoqi@0 338 }
aoqi@0 339 }
aoqi@0 340
aoqi@0 341 void setWarning(WarningKind wk) {
aoqi@0 342 if (!warnings.add(wk)) {
aoqi@0 343 throw new AssertionError("Duplicate warning of kind " +
aoqi@0 344 wk + " in source:\n" + source);
aoqi@0 345 }
aoqi@0 346 }
aoqi@0 347
aoqi@0 348 boolean hasWarning(WarningKind wk) {
aoqi@0 349 return warnings.contains(wk);
aoqi@0 350 }
aoqi@0 351 }
aoqi@0 352
aoqi@0 353 }

mercurial