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

Mon, 13 Dec 2010 15:11:00 -0800

author
mcimadamore
date
Mon, 13 Dec 2010 15:11:00 -0800
changeset 795
7b99f98b3035
child 892
3e30c95da3c6
permissions
-rw-r--r--

6993978: Project Coin: Compiler support of annotation to reduce varargs warnings
Reviewed-by: jjg, darcy

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

mercurial