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

changeset 1108
b5d0b8effc85
parent 962
0ff2bbd38f10
child 1482
954541f13717
     1.1 --- a/test/tools/javac/varargs/warning/Warn5.java	Thu Oct 06 18:39:31 2011 +0100
     1.2 +++ b/test/tools/javac/varargs/warning/Warn5.java	Mon Oct 17 12:54:33 2011 +0100
     1.3 @@ -23,7 +23,7 @@
     1.4  
     1.5  /**
     1.6   * @test
     1.7 - * @bug     6993978
     1.8 + * @bug     6993978 7097436
     1.9   * @summary Project Coin: Annotation to reduce varargs warnings
    1.10   * @author  mcimadamore
    1.11   * @run main Warn5
    1.12 @@ -31,8 +31,8 @@
    1.13  import com.sun.source.util.JavacTask;
    1.14  import com.sun.tools.javac.api.JavacTool;
    1.15  import java.net.URI;
    1.16 -import java.util.ArrayList;
    1.17  import java.util.Arrays;
    1.18 +import java.util.EnumSet;
    1.19  import javax.tools.Diagnostic;
    1.20  import javax.tools.JavaCompiler;
    1.21  import javax.tools.JavaFileObject;
    1.22 @@ -95,7 +95,6 @@
    1.23          METHOD("void m"),
    1.24          CONSTRUCTOR("Test");
    1.25  
    1.26 -
    1.27          String name;
    1.28  
    1.29          MethodKind(String name) {
    1.30 @@ -155,7 +154,124 @@
    1.31          }
    1.32      }
    1.33  
    1.34 -    static class JavaSource extends SimpleJavaFileObject {
    1.35 +    enum WarningKind {
    1.36 +        UNSAFE_BODY,
    1.37 +        UNSAFE_DECL,
    1.38 +        MALFORMED_SAFEVARARGS,
    1.39 +        REDUNDANT_SAFEVARARGS;
    1.40 +    }
    1.41 +
    1.42 +    // Create a single file manager and reuse it for each compile to save time.
    1.43 +    static StandardJavaFileManager fm = JavacTool.create().getStandardFileManager(null, null, null);
    1.44 +
    1.45 +    public static void main(String... args) throws Exception {
    1.46 +        for (SourceLevel sourceLevel : SourceLevel.values()) {
    1.47 +            for (XlintOption xlint : XlintOption.values()) {
    1.48 +                for (TrustMe trustMe : TrustMe.values()) {
    1.49 +                    for (SuppressLevel suppressLevel : SuppressLevel.values()) {
    1.50 +                        for (ModifierKind modKind : ModifierKind.values()) {
    1.51 +                            for (MethodKind methKind : MethodKind.values()) {
    1.52 +                                for (SignatureKind sig : SignatureKind.values()) {
    1.53 +                                    for (BodyKind body : BodyKind.values()) {
    1.54 +                                        new Warn5(sourceLevel,
    1.55 +                                                xlint,
    1.56 +                                                trustMe,
    1.57 +                                                suppressLevel,
    1.58 +                                                modKind,
    1.59 +                                                methKind,
    1.60 +                                                sig,
    1.61 +                                                body).test();
    1.62 +                                    }
    1.63 +                                }
    1.64 +                            }
    1.65 +                        }
    1.66 +                    }
    1.67 +                }
    1.68 +            }
    1.69 +        }
    1.70 +    }
    1.71 +
    1.72 +    final SourceLevel sourceLevel;
    1.73 +    final XlintOption xlint;
    1.74 +    final TrustMe trustMe;
    1.75 +    final SuppressLevel suppressLevel;
    1.76 +    final ModifierKind modKind;
    1.77 +    final MethodKind methKind;
    1.78 +    final SignatureKind sig;
    1.79 +    final BodyKind body;
    1.80 +    final JavaSource source;
    1.81 +    final DiagnosticChecker dc;
    1.82 +
    1.83 +    public Warn5(SourceLevel sourceLevel, XlintOption xlint, TrustMe trustMe, SuppressLevel suppressLevel, ModifierKind modKind, MethodKind methKind, SignatureKind sig, BodyKind body) {
    1.84 +        this.sourceLevel = sourceLevel;
    1.85 +        this.xlint = xlint;
    1.86 +        this.trustMe = trustMe;
    1.87 +        this.suppressLevel = suppressLevel;
    1.88 +        this.modKind = modKind;
    1.89 +        this.methKind = methKind;
    1.90 +        this.sig = sig;
    1.91 +        this.body = body;
    1.92 +        this.source = new JavaSource();
    1.93 +        this.dc = new DiagnosticChecker();
    1.94 +    }
    1.95 +
    1.96 +    void test() throws Exception {
    1.97 +        final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
    1.98 +        JavacTask ct = (JavacTask)tool.getTask(null, fm, dc,
    1.99 +                Arrays.asList(xlint.getXlintOption(), "-source", sourceLevel.sourceKey), null, Arrays.asList(source));
   1.100 +        ct.analyze();
   1.101 +        check();
   1.102 +    }
   1.103 +
   1.104 +    void check() {
   1.105 +
   1.106 +        EnumSet<WarningKind> expectedWarnings = EnumSet.noneOf(WarningKind.class);
   1.107 +
   1.108 +        if (sourceLevel == SourceLevel.JDK_7 &&
   1.109 +                trustMe == TrustMe.TRUST &&
   1.110 +                suppressLevel != SuppressLevel.VARARGS &&
   1.111 +                xlint != XlintOption.NONE &&
   1.112 +                sig.isVarargs && !sig.isReifiableArg && body.hasAliasing &&
   1.113 +                (methKind == MethodKind.CONSTRUCTOR || (methKind == MethodKind.METHOD && modKind != ModifierKind.NONE))) {
   1.114 +            expectedWarnings.add(WarningKind.UNSAFE_BODY);
   1.115 +        }
   1.116 +
   1.117 +        if (sourceLevel == SourceLevel.JDK_7 &&
   1.118 +                trustMe == TrustMe.DONT_TRUST &&
   1.119 +                sig.isVarargs &&
   1.120 +                !sig.isReifiableArg &&
   1.121 +                xlint == XlintOption.ALL) {
   1.122 +            expectedWarnings.add(WarningKind.UNSAFE_DECL);
   1.123 +        }
   1.124 +
   1.125 +        if (sourceLevel == SourceLevel.JDK_7 &&
   1.126 +                trustMe == TrustMe.TRUST &&
   1.127 +                (!sig.isVarargs ||
   1.128 +                (modKind == ModifierKind.NONE && methKind == MethodKind.METHOD))) {
   1.129 +            expectedWarnings.add(WarningKind.MALFORMED_SAFEVARARGS);
   1.130 +        }
   1.131 +
   1.132 +        if (sourceLevel == SourceLevel.JDK_7 &&
   1.133 +                trustMe == TrustMe.TRUST &&
   1.134 +                xlint != XlintOption.NONE &&
   1.135 +                suppressLevel != SuppressLevel.VARARGS &&
   1.136 +                (modKind != ModifierKind.NONE || methKind == MethodKind.CONSTRUCTOR) &&
   1.137 +                sig.isVarargs &&
   1.138 +                sig.isReifiableArg) {
   1.139 +            expectedWarnings.add(WarningKind.REDUNDANT_SAFEVARARGS);
   1.140 +        }
   1.141 +
   1.142 +        if (!expectedWarnings.containsAll(dc.warnings) ||
   1.143 +                !dc.warnings.containsAll(expectedWarnings)) {
   1.144 +            throw new Error("invalid diagnostics for source:\n" +
   1.145 +                    source.getCharContent(true) +
   1.146 +                    "\nOptions: " + xlint.getXlintOption() +
   1.147 +                    "\nExpected warnings: " + expectedWarnings +
   1.148 +                    "\nFound warnings: " + dc.warnings);
   1.149 +        }
   1.150 +    }
   1.151 +
   1.152 +    class JavaSource extends SimpleJavaFileObject {
   1.153  
   1.154          String template = "import com.sun.tools.javac.api.*;\n" +
   1.155                            "import java.util.List;\n" +
   1.156 @@ -167,12 +283,11 @@
   1.157  
   1.158          String source;
   1.159  
   1.160 -        public JavaSource(TrustMe trustMe, SuppressLevel suppressLevel, ModifierKind modKind,
   1.161 -                MethodKind methKind, SignatureKind meth, BodyKind body) {
   1.162 +        public JavaSource() {
   1.163              super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
   1.164              source = template.replace("#T", trustMe.anno).
   1.165                      replace("#S", suppressLevel.getSuppressAnno()).
   1.166 -                    replace("#M", meth.getSignature(modKind, methKind)).
   1.167 +                    replace("#M", sig.getSignature(modKind, methKind)).
   1.168                      replace("#B", body.body);
   1.169          }
   1.170  
   1.171 @@ -182,117 +297,34 @@
   1.172          }
   1.173      }
   1.174  
   1.175 -    public static void main(String... args) throws Exception {
   1.176 -        for (SourceLevel sourceLevel : SourceLevel.values()) {
   1.177 -            for (XlintOption xlint : XlintOption.values()) {
   1.178 -                for (TrustMe trustMe : TrustMe.values()) {
   1.179 -                    for (SuppressLevel suppressLevel : SuppressLevel.values()) {
   1.180 -                        for (ModifierKind modKind : ModifierKind.values()) {
   1.181 -                            for (MethodKind methKind : MethodKind.values()) {
   1.182 -                                for (SignatureKind sig : SignatureKind.values()) {
   1.183 -                                    for (BodyKind body : BodyKind.values()) {
   1.184 -                                        test(sourceLevel,
   1.185 -                                                xlint,
   1.186 -                                                trustMe,
   1.187 -                                                suppressLevel,
   1.188 -                                                modKind,
   1.189 -                                                methKind,
   1.190 -                                                sig,
   1.191 -                                                body);
   1.192 -                                    }
   1.193 -                                }
   1.194 -                            }
   1.195 -                        }
   1.196 -                    }
   1.197 -                }
   1.198 -            }
   1.199 -        }
   1.200 -    }
   1.201 +    class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
   1.202  
   1.203 -    // Create a single file manager and reuse it for each compile to save time.
   1.204 -    static StandardJavaFileManager fm = JavacTool.create().getStandardFileManager(null, null, null);
   1.205 -
   1.206 -    static void test(SourceLevel sourceLevel, XlintOption xlint, TrustMe trustMe, SuppressLevel suppressLevel,
   1.207 -            ModifierKind modKind, MethodKind methKind, SignatureKind sig, BodyKind body) throws Exception {
   1.208 -        final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
   1.209 -        JavaSource source = new JavaSource(trustMe, suppressLevel, modKind, methKind, sig, body);
   1.210 -        DiagnosticChecker dc = new DiagnosticChecker();
   1.211 -        JavacTask ct = (JavacTask)tool.getTask(null, fm, dc,
   1.212 -                Arrays.asList(xlint.getXlintOption(), "-source", sourceLevel.sourceKey), null, Arrays.asList(source));
   1.213 -        ct.analyze();
   1.214 -        check(sourceLevel, dc, source, xlint, trustMe,
   1.215 -                suppressLevel, modKind, methKind, sig, body);
   1.216 -    }
   1.217 -
   1.218 -    static void check(SourceLevel sourceLevel, DiagnosticChecker dc, JavaSource source,
   1.219 -            XlintOption xlint, TrustMe trustMe, SuppressLevel suppressLevel, ModifierKind modKind,
   1.220 -            MethodKind methKind, SignatureKind meth, BodyKind body) {
   1.221 -
   1.222 -        boolean hasPotentiallyUnsafeBody = sourceLevel == SourceLevel.JDK_7 &&
   1.223 -                trustMe == TrustMe.TRUST &&
   1.224 -                suppressLevel != SuppressLevel.VARARGS &&
   1.225 -                xlint != XlintOption.NONE &&
   1.226 -                meth.isVarargs && !meth.isReifiableArg && body.hasAliasing &&
   1.227 -                (methKind == MethodKind.CONSTRUCTOR || (methKind == MethodKind.METHOD && modKind != ModifierKind.NONE));
   1.228 -
   1.229 -        boolean hasPotentiallyPollutingDecl = sourceLevel == SourceLevel.JDK_7 &&
   1.230 -                trustMe == TrustMe.DONT_TRUST &&
   1.231 -                meth.isVarargs &&
   1.232 -                !meth.isReifiableArg &&
   1.233 -                xlint == XlintOption.ALL;
   1.234 -
   1.235 -        boolean hasMalformedAnnoInDecl = sourceLevel == SourceLevel.JDK_7 &&
   1.236 -                trustMe == TrustMe.TRUST &&
   1.237 -                (!meth.isVarargs ||
   1.238 -                (modKind == ModifierKind.NONE && methKind == MethodKind.METHOD));
   1.239 -
   1.240 -        boolean hasRedundantAnnoInDecl = sourceLevel == SourceLevel.JDK_7 &&
   1.241 -                trustMe == TrustMe.TRUST &&
   1.242 -                xlint != XlintOption.NONE &&
   1.243 -                suppressLevel != SuppressLevel.VARARGS &&
   1.244 -                (modKind != ModifierKind.NONE || methKind == MethodKind.CONSTRUCTOR) &&
   1.245 -                meth.isVarargs &&
   1.246 -                meth.isReifiableArg;
   1.247 -
   1.248 -        if (hasPotentiallyUnsafeBody != dc.hasPotentiallyUnsafeBody ||
   1.249 -                hasPotentiallyPollutingDecl != dc.hasPotentiallyPollutingDecl ||
   1.250 -                hasMalformedAnnoInDecl != dc.hasMalformedAnnoInDecl ||
   1.251 -                hasRedundantAnnoInDecl != dc.hasRedundantAnnoInDecl) {
   1.252 -            throw new Error("invalid diagnostics for source:\n" +
   1.253 -                    source.getCharContent(true) +
   1.254 -                    "\nOptions: " + xlint.getXlintOption() +
   1.255 -                    "\nExpected potentially unsafe body warning: " + hasPotentiallyUnsafeBody +
   1.256 -                    "\nExpected potentially polluting decl warning: " + hasPotentiallyPollutingDecl +
   1.257 -                    "\nExpected malformed anno error: " + hasMalformedAnnoInDecl +
   1.258 -                    "\nExpected redundant anno warning: " + hasRedundantAnnoInDecl +
   1.259 -                    "\nFound potentially unsafe body warning: " + dc.hasPotentiallyUnsafeBody +
   1.260 -                    "\nFound potentially polluting decl warning: " + dc.hasPotentiallyPollutingDecl +
   1.261 -                    "\nFound malformed anno error: " + dc.hasMalformedAnnoInDecl +
   1.262 -                    "\nFound redundant anno warning: " + dc.hasRedundantAnnoInDecl);
   1.263 -        }
   1.264 -    }
   1.265 -
   1.266 -    static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
   1.267 -
   1.268 -        boolean hasPotentiallyUnsafeBody = false;
   1.269 -        boolean hasPotentiallyPollutingDecl = false;
   1.270 -        boolean hasMalformedAnnoInDecl = false;
   1.271 -        boolean hasRedundantAnnoInDecl = false;
   1.272 +        EnumSet<WarningKind> warnings = EnumSet.noneOf(WarningKind.class);
   1.273  
   1.274          public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
   1.275              if (diagnostic.getKind() == Diagnostic.Kind.WARNING) {
   1.276                      if (diagnostic.getCode().contains("unsafe.use.varargs.param")) {
   1.277 -                        hasPotentiallyUnsafeBody = true;
   1.278 +                        setWarning(WarningKind.UNSAFE_BODY);
   1.279                      } else if (diagnostic.getCode().contains("redundant.trustme")) {
   1.280 -                        hasRedundantAnnoInDecl = true;
   1.281 +                        setWarning(WarningKind.REDUNDANT_SAFEVARARGS);
   1.282                      }
   1.283              } else if (diagnostic.getKind() == Diagnostic.Kind.MANDATORY_WARNING &&
   1.284                      diagnostic.getCode().contains("varargs.non.reifiable.type")) {
   1.285 -                hasPotentiallyPollutingDecl = true;
   1.286 +                setWarning(WarningKind.UNSAFE_DECL);
   1.287              } else if (diagnostic.getKind() == Diagnostic.Kind.ERROR &&
   1.288                      diagnostic.getCode().contains("invalid.trustme")) {
   1.289 -                hasMalformedAnnoInDecl = true;
   1.290 +                setWarning(WarningKind.MALFORMED_SAFEVARARGS);
   1.291              }
   1.292          }
   1.293 +
   1.294 +        void setWarning(WarningKind wk) {
   1.295 +            if (!warnings.add(wk)) {
   1.296 +                throw new AssertionError("Duplicate warning of kind " + wk + " in source:\n" + source);
   1.297 +            }
   1.298 +        }
   1.299 +
   1.300 +        boolean hasWarning(WarningKind wk) {
   1.301 +            return warnings.contains(wk);
   1.302 +        }
   1.303      }
   1.304  }

mercurial