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

Wed, 06 Apr 2011 20:33:44 -0700

author
ohair
date
Wed, 06 Apr 2011 20:33:44 -0700
changeset 962
0ff2bbd38f10
parent 892
3e30c95da3c6
child 1108
b5d0b8effc85
permissions
-rw-r--r--

7033660: Update copyright year to 2011 on any files changed in 2011
Reviewed-by: dholmes

mcimadamore@795 1 /*
ohair@962 2 * Copyright (c) 2010, 2011, 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;
jjh@892 32 import com.sun.tools.javac.api.JavacTool;
mcimadamore@795 33 import java.net.URI;
mcimadamore@795 34 import java.util.ArrayList;
mcimadamore@795 35 import java.util.Arrays;
mcimadamore@795 36 import javax.tools.Diagnostic;
mcimadamore@795 37 import javax.tools.JavaCompiler;
mcimadamore@795 38 import javax.tools.JavaFileObject;
mcimadamore@795 39 import javax.tools.SimpleJavaFileObject;
jjh@892 40 import javax.tools.StandardJavaFileManager;
mcimadamore@795 41 import javax.tools.ToolProvider;
mcimadamore@795 42
mcimadamore@795 43 public class Warn5 {
mcimadamore@795 44
mcimadamore@795 45 enum XlintOption {
mcimadamore@795 46 NONE("none"),
mcimadamore@795 47 ALL("all");
mcimadamore@795 48
mcimadamore@795 49 String opt;
mcimadamore@795 50
mcimadamore@795 51 XlintOption(String opt) {
mcimadamore@795 52 this.opt = opt;
mcimadamore@795 53 }
mcimadamore@795 54
mcimadamore@795 55 String getXlintOption() {
mcimadamore@795 56 return "-Xlint:" + opt;
mcimadamore@795 57 }
mcimadamore@795 58 }
mcimadamore@795 59
mcimadamore@795 60 enum TrustMe {
mcimadamore@795 61 DONT_TRUST(""),
mcimadamore@795 62 TRUST("@java.lang.SafeVarargs");
mcimadamore@795 63
mcimadamore@795 64 String anno;
mcimadamore@795 65
mcimadamore@795 66 TrustMe(String anno) {
mcimadamore@795 67 this.anno = anno;
mcimadamore@795 68 }
mcimadamore@795 69 }
mcimadamore@795 70
mcimadamore@795 71 enum SuppressLevel {
mcimadamore@795 72 NONE,
mcimadamore@795 73 VARARGS;
mcimadamore@795 74
mcimadamore@795 75 String getSuppressAnno() {
mcimadamore@795 76 return this == VARARGS ?
mcimadamore@795 77 "@SuppressWarnings(\"varargs\")" :
mcimadamore@795 78 "";
mcimadamore@795 79 }
mcimadamore@795 80 }
mcimadamore@795 81
mcimadamore@795 82 enum ModifierKind {
mcimadamore@795 83 NONE(""),
mcimadamore@795 84 FINAL("final"),
mcimadamore@795 85 STATIC("static");
mcimadamore@795 86
mcimadamore@795 87 String mod;
mcimadamore@795 88
mcimadamore@795 89 ModifierKind(String mod) {
mcimadamore@795 90 this.mod = mod;
mcimadamore@795 91 }
mcimadamore@795 92 }
mcimadamore@795 93
mcimadamore@795 94 enum MethodKind {
mcimadamore@795 95 METHOD("void m"),
mcimadamore@795 96 CONSTRUCTOR("Test");
mcimadamore@795 97
mcimadamore@795 98
mcimadamore@795 99 String name;
mcimadamore@795 100
mcimadamore@795 101 MethodKind(String name) {
mcimadamore@795 102 this.name = name;
mcimadamore@795 103 }
mcimadamore@795 104 }
mcimadamore@795 105
mcimadamore@795 106 enum SourceLevel {
mcimadamore@795 107 JDK_6("6"),
mcimadamore@795 108 JDK_7("7");
mcimadamore@795 109
mcimadamore@795 110 String sourceKey;
mcimadamore@795 111
mcimadamore@795 112 SourceLevel(String sourceKey) {
mcimadamore@795 113 this.sourceKey = sourceKey;
mcimadamore@795 114 }
mcimadamore@795 115 }
mcimadamore@795 116
mcimadamore@795 117 enum SignatureKind {
mcimadamore@795 118 VARARGS_X("#K <X>#N(X... x)", false, true),
mcimadamore@795 119 VARARGS_STRING("#K #N(String... x)", true, true),
mcimadamore@795 120 ARRAY_X("#K <X>#N(X[] x)", false, false),
mcimadamore@795 121 ARRAY_STRING("#K #N(String[] x)", true, false);
mcimadamore@795 122
mcimadamore@795 123 String stub;
mcimadamore@795 124 boolean isReifiableArg;
mcimadamore@795 125 boolean isVarargs;
mcimadamore@795 126
mcimadamore@795 127 SignatureKind(String stub, boolean isReifiableArg, boolean isVarargs) {
mcimadamore@795 128 this.stub = stub;
mcimadamore@795 129 this.isReifiableArg = isReifiableArg;
mcimadamore@795 130 this.isVarargs = isVarargs;
mcimadamore@795 131 }
mcimadamore@795 132
mcimadamore@795 133 String getSignature(ModifierKind modKind, MethodKind methKind) {
mcimadamore@795 134 return methKind != MethodKind.CONSTRUCTOR ?
mcimadamore@795 135 stub.replace("#K", modKind.mod).replace("#N", methKind.name) :
mcimadamore@795 136 stub.replace("#K", "").replace("#N", methKind.name);
mcimadamore@795 137 }
mcimadamore@795 138 }
mcimadamore@795 139
mcimadamore@795 140 enum BodyKind {
mcimadamore@795 141 ASSIGN("Object o = x;", true),
mcimadamore@795 142 CAST("Object o = (Object)x;", true),
mcimadamore@795 143 METH("test(x);", true),
mcimadamore@795 144 PRINT("System.out.println(x.toString());", false),
mcimadamore@795 145 ARRAY_ASSIGN("Object[] o = x;", true),
mcimadamore@795 146 ARRAY_CAST("Object[] o = (Object[])x;", true),
mcimadamore@795 147 ARRAY_METH("testArr(x);", true);
mcimadamore@795 148
mcimadamore@795 149 String body;
mcimadamore@795 150 boolean hasAliasing;
mcimadamore@795 151
mcimadamore@795 152 BodyKind(String body, boolean hasAliasing) {
mcimadamore@795 153 this.body = body;
mcimadamore@795 154 this.hasAliasing = hasAliasing;
mcimadamore@795 155 }
mcimadamore@795 156 }
mcimadamore@795 157
mcimadamore@795 158 static class JavaSource extends SimpleJavaFileObject {
mcimadamore@795 159
mcimadamore@795 160 String template = "import com.sun.tools.javac.api.*;\n" +
mcimadamore@795 161 "import java.util.List;\n" +
mcimadamore@795 162 "class Test {\n" +
mcimadamore@795 163 " static void test(Object o) {}\n" +
mcimadamore@795 164 " static void testArr(Object[] o) {}\n" +
mcimadamore@795 165 " #T \n #S #M { #B }\n" +
mcimadamore@795 166 "}\n";
mcimadamore@795 167
mcimadamore@795 168 String source;
mcimadamore@795 169
mcimadamore@795 170 public JavaSource(TrustMe trustMe, SuppressLevel suppressLevel, ModifierKind modKind,
mcimadamore@795 171 MethodKind methKind, SignatureKind meth, BodyKind body) {
mcimadamore@795 172 super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
mcimadamore@795 173 source = template.replace("#T", trustMe.anno).
mcimadamore@795 174 replace("#S", suppressLevel.getSuppressAnno()).
mcimadamore@795 175 replace("#M", meth.getSignature(modKind, methKind)).
mcimadamore@795 176 replace("#B", body.body);
mcimadamore@795 177 }
mcimadamore@795 178
mcimadamore@795 179 @Override
mcimadamore@795 180 public CharSequence getCharContent(boolean ignoreEncodingErrors) {
mcimadamore@795 181 return source;
mcimadamore@795 182 }
mcimadamore@795 183 }
mcimadamore@795 184
mcimadamore@795 185 public static void main(String... args) throws Exception {
mcimadamore@795 186 for (SourceLevel sourceLevel : SourceLevel.values()) {
mcimadamore@795 187 for (XlintOption xlint : XlintOption.values()) {
mcimadamore@795 188 for (TrustMe trustMe : TrustMe.values()) {
mcimadamore@795 189 for (SuppressLevel suppressLevel : SuppressLevel.values()) {
mcimadamore@795 190 for (ModifierKind modKind : ModifierKind.values()) {
mcimadamore@795 191 for (MethodKind methKind : MethodKind.values()) {
mcimadamore@795 192 for (SignatureKind sig : SignatureKind.values()) {
mcimadamore@795 193 for (BodyKind body : BodyKind.values()) {
mcimadamore@795 194 test(sourceLevel,
mcimadamore@795 195 xlint,
mcimadamore@795 196 trustMe,
mcimadamore@795 197 suppressLevel,
mcimadamore@795 198 modKind,
mcimadamore@795 199 methKind,
mcimadamore@795 200 sig,
mcimadamore@795 201 body);
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 }
mcimadamore@795 211
jjh@892 212 // Create a single file manager and reuse it for each compile to save time.
jjh@892 213 static StandardJavaFileManager fm = JavacTool.create().getStandardFileManager(null, null, null);
jjh@892 214
mcimadamore@795 215 static void test(SourceLevel sourceLevel, XlintOption xlint, TrustMe trustMe, SuppressLevel suppressLevel,
mcimadamore@795 216 ModifierKind modKind, MethodKind methKind, SignatureKind sig, BodyKind body) throws Exception {
mcimadamore@795 217 final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
mcimadamore@795 218 JavaSource source = new JavaSource(trustMe, suppressLevel, modKind, methKind, sig, body);
mcimadamore@795 219 DiagnosticChecker dc = new DiagnosticChecker();
jjh@892 220 JavacTask ct = (JavacTask)tool.getTask(null, fm, dc,
mcimadamore@795 221 Arrays.asList(xlint.getXlintOption(), "-source", sourceLevel.sourceKey), null, Arrays.asList(source));
mcimadamore@795 222 ct.analyze();
mcimadamore@795 223 check(sourceLevel, dc, source, xlint, trustMe,
mcimadamore@795 224 suppressLevel, modKind, methKind, sig, body);
mcimadamore@795 225 }
mcimadamore@795 226
mcimadamore@795 227 static void check(SourceLevel sourceLevel, DiagnosticChecker dc, JavaSource source,
mcimadamore@795 228 XlintOption xlint, TrustMe trustMe, SuppressLevel suppressLevel, ModifierKind modKind,
mcimadamore@795 229 MethodKind methKind, SignatureKind meth, BodyKind body) {
mcimadamore@795 230
mcimadamore@795 231 boolean hasPotentiallyUnsafeBody = sourceLevel == SourceLevel.JDK_7 &&
mcimadamore@795 232 trustMe == TrustMe.TRUST &&
mcimadamore@795 233 suppressLevel != SuppressLevel.VARARGS &&
mcimadamore@795 234 xlint != XlintOption.NONE &&
mcimadamore@795 235 meth.isVarargs && !meth.isReifiableArg && body.hasAliasing &&
mcimadamore@795 236 (methKind == MethodKind.CONSTRUCTOR || (methKind == MethodKind.METHOD && modKind != ModifierKind.NONE));
mcimadamore@795 237
mcimadamore@795 238 boolean hasPotentiallyPollutingDecl = sourceLevel == SourceLevel.JDK_7 &&
mcimadamore@795 239 trustMe == TrustMe.DONT_TRUST &&
mcimadamore@795 240 meth.isVarargs &&
mcimadamore@795 241 !meth.isReifiableArg &&
mcimadamore@795 242 xlint == XlintOption.ALL;
mcimadamore@795 243
mcimadamore@795 244 boolean hasMalformedAnnoInDecl = sourceLevel == SourceLevel.JDK_7 &&
mcimadamore@795 245 trustMe == TrustMe.TRUST &&
mcimadamore@795 246 (!meth.isVarargs ||
mcimadamore@795 247 (modKind == ModifierKind.NONE && methKind == MethodKind.METHOD));
mcimadamore@795 248
mcimadamore@795 249 boolean hasRedundantAnnoInDecl = sourceLevel == SourceLevel.JDK_7 &&
mcimadamore@795 250 trustMe == TrustMe.TRUST &&
mcimadamore@795 251 xlint != XlintOption.NONE &&
mcimadamore@795 252 suppressLevel != SuppressLevel.VARARGS &&
mcimadamore@795 253 (modKind != ModifierKind.NONE || methKind == MethodKind.CONSTRUCTOR) &&
mcimadamore@795 254 meth.isVarargs &&
mcimadamore@795 255 meth.isReifiableArg;
mcimadamore@795 256
mcimadamore@795 257 if (hasPotentiallyUnsafeBody != dc.hasPotentiallyUnsafeBody ||
mcimadamore@795 258 hasPotentiallyPollutingDecl != dc.hasPotentiallyPollutingDecl ||
mcimadamore@795 259 hasMalformedAnnoInDecl != dc.hasMalformedAnnoInDecl ||
mcimadamore@795 260 hasRedundantAnnoInDecl != dc.hasRedundantAnnoInDecl) {
mcimadamore@795 261 throw new Error("invalid diagnostics for source:\n" +
mcimadamore@795 262 source.getCharContent(true) +
mcimadamore@795 263 "\nOptions: " + xlint.getXlintOption() +
mcimadamore@795 264 "\nExpected potentially unsafe body warning: " + hasPotentiallyUnsafeBody +
mcimadamore@795 265 "\nExpected potentially polluting decl warning: " + hasPotentiallyPollutingDecl +
mcimadamore@795 266 "\nExpected malformed anno error: " + hasMalformedAnnoInDecl +
mcimadamore@795 267 "\nExpected redundant anno warning: " + hasRedundantAnnoInDecl +
mcimadamore@795 268 "\nFound potentially unsafe body warning: " + dc.hasPotentiallyUnsafeBody +
mcimadamore@795 269 "\nFound potentially polluting decl warning: " + dc.hasPotentiallyPollutingDecl +
mcimadamore@795 270 "\nFound malformed anno error: " + dc.hasMalformedAnnoInDecl +
mcimadamore@795 271 "\nFound redundant anno warning: " + dc.hasRedundantAnnoInDecl);
mcimadamore@795 272 }
mcimadamore@795 273 }
mcimadamore@795 274
mcimadamore@795 275 static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
mcimadamore@795 276
mcimadamore@795 277 boolean hasPotentiallyUnsafeBody = false;
mcimadamore@795 278 boolean hasPotentiallyPollutingDecl = false;
mcimadamore@795 279 boolean hasMalformedAnnoInDecl = false;
mcimadamore@795 280 boolean hasRedundantAnnoInDecl = false;
mcimadamore@795 281
mcimadamore@795 282 public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
mcimadamore@795 283 if (diagnostic.getKind() == Diagnostic.Kind.WARNING) {
mcimadamore@795 284 if (diagnostic.getCode().contains("unsafe.use.varargs.param")) {
mcimadamore@795 285 hasPotentiallyUnsafeBody = true;
mcimadamore@795 286 } else if (diagnostic.getCode().contains("redundant.trustme")) {
mcimadamore@795 287 hasRedundantAnnoInDecl = true;
mcimadamore@795 288 }
mcimadamore@795 289 } else if (diagnostic.getKind() == Diagnostic.Kind.MANDATORY_WARNING &&
mcimadamore@795 290 diagnostic.getCode().contains("varargs.non.reifiable.type")) {
mcimadamore@795 291 hasPotentiallyPollutingDecl = true;
mcimadamore@795 292 } else if (diagnostic.getKind() == Diagnostic.Kind.ERROR &&
mcimadamore@795 293 diagnostic.getCode().contains("invalid.trustme")) {
mcimadamore@795 294 hasMalformedAnnoInDecl = true;
mcimadamore@795 295 }
mcimadamore@795 296 }
mcimadamore@795 297 }
mcimadamore@795 298 }

mercurial