test/tools/javac/processing/TestWarnErrorCount.java

Thu, 21 Feb 2013 15:26:46 +0000

author
mcimadamore
date
Thu, 21 Feb 2013 15:26:46 +0000
changeset 1599
9f0ec00514b6
parent 1466
b52a38d4536c
child 2525
2eb010b6cb22
permissions
-rw-r--r--

8007461: Regression: bad overload resolution when inner class and outer class have method with same name
Summary: Fix regression in varargs method resolution introduced by bad refactoring
Reviewed-by: jjg

     1 /*
     2  * Copyright (c) 2011, 2012, 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  */
    25 /*
    26  * @test
    27  * @bug 7022337
    28  * @summary repeated warnings about bootclasspath not set
    29  * @library /tools/javac/lib
    30  * @build JavacTestingAbstractProcessor TestWarnErrorCount
    31  * @run main TestWarnErrorCount
    32  */
    34 import java.io.*;
    35 import java.util.*;
    36 import javax.annotation.processing.*;
    37 import javax.lang.model.element.*;
    38 import javax.tools.*;
    40 @SupportedOptions({"errKind", "msgrWarnKind", "javaWarnKind"})
    41 public class TestWarnErrorCount extends JavacTestingAbstractProcessor {
    42     public static void main(String... args) throws Exception {
    43         new TestWarnErrorCount().run(args);
    44     }
    46     final int MAX_GEN = 10;
    47     final int ERROR_ROUND = MAX_GEN / 2; // when to generate error
    49     /**
    50      * Type of errors to generate in test case.
    51      */
    52     enum ErrorKind {
    53         /** No errors. */
    54         NONE,
    55         /** Source code errors. */
    56         JAVA,
    57         /** Errors reported to Messager. */
    58         MESSAGER,
    59         /** Error as a result of using -Werror. */
    60         WERROR,
    61     }
    63     /**
    64      * Frequency of warnings in test case.
    65      */
    66     enum WarnKind {
    67         /** No warnings. */
    68         NONE {
    69             boolean warn(int round) { return false; }
    70             int count(int start, int end) { return 0; }
    71         },
    72         /** Generate a warning if round count is a multiple of 2. */
    73         EVERY_TWO {
    74             boolean warn(int round) { return (round % 2) == 0; }
    75             int count(int start, int end) { return (end / 2) - ((start - 1)/ 2); }
    76         },
    77         /** Generate a warning if round count is a multiple of 3. */
    78         EVERY_THREE {
    79             boolean warn(int round) { return (round % 3) == 0; }
    80             int count(int start, int end) { return (end / 3) - ((start - 1)/ 3); }
    81         },
    82         /** Generate a warning every round. */
    83         ALL {
    84             boolean warn(int round) { return true; }
    85             int count(int start, int end) { return (end - start + 1); }
    86         };
    88         /** whether to generate a warning in round 'round'. */
    89         abstract boolean warn(int round);
    91         /** number of warnings generated in a range of rounds, inclusive. */
    92         abstract int count(int start, int end);
    93     }
    96     /**
    97      * Run test.
    98      * @param args provide ability to specify particular test cases for debugging.
    99      */
   100     void run(String... args) throws Exception {
   101         for (String arg: args) {
   102             if (arg.matches("[0-9]+")) {
   103                 if (testCases == null)
   104                     testCases = new HashSet<Integer>();
   105                 testCases.add(Integer.valueOf(arg));
   106             } else if (arg.equals("-stopOnError")) {
   107                 stopOnError = true;
   108             } else
   109                 throw new IllegalArgumentException(arg);
   110         }
   112         run ();
   114         if (errors > 0)
   115             throw new Exception(errors + " errors found");
   116     }
   118     /**
   119      * Run test.
   120      */
   121     void run() throws Exception {
   122         for (ErrorKind ek: ErrorKind.values()) {
   123             for (WarnKind mwk: WarnKind.values()) {
   124                 for (WarnKind jwk: WarnKind.values()) {
   125                     test(ek, mwk, jwk);
   126                     if (stopOnError && errors > 0)
   127                         throw new Exception(errors + " errors found");
   128                 }
   129             }
   130         }
   131     }
   133     boolean stopOnError;
   134     Set<Integer> testCases;
   135     int testNum = 0;
   137     /**
   138      * Run a test case.
   139      * @param ek    The type of errors to generate
   140      * @param mwk   The frequency of Messager warnings to generate
   141      * @param jwk   The frequency of Java warnings to generate
   142      */
   143     void test(ErrorKind ek, WarnKind mwk, WarnKind jwk) {
   144         testNum++;
   146         if (testCases != null && !testCases.contains(testNum))
   147             return;
   149         System.err.println("Test " + testNum + ": ek:" + ek + " mwk:" + mwk + " jwk:" + jwk);
   151         File testDir = new File("test" + testNum);
   152         testDir.mkdirs();
   154         String myName = TestWarnErrorCount.class.getSimpleName();
   155         File testSrc = new File(System.getProperty("test.src"));
   156         File file = new File(testSrc, myName + ".java");
   158         List<String> args = new ArrayList<String>();
   159         args.addAll(Arrays.asList(
   160             "-XDrawDiagnostics",
   161             "-d", testDir.getPath(),
   162             "-processor", myName,
   163 //            "-XprintRounds",
   164             "-Xlint:all,-path",
   165             "-AerrKind=" + ek,
   166             "-AmsgrWarnKind=" + mwk,
   167             "-AjavaWarnKind=" + jwk));
   168         if (ek == ErrorKind.WERROR)
   169             args.add("-Werror");
   170         args.add(file.getPath());
   172         String out = compile(args.toArray(new String[args.size()]));
   174         int errsFound = 0;
   175         int errsReported = 0;
   176         int warnsFound = 0;
   177         int warnsReported = 0;
   179         // Scan the output looking for messages of interest.
   181         for (String line: out.split("[\r\n]+")) {
   182             if (line.contains("compiler.err.")) {
   183                 errsFound++;
   184             } else if (line.contains("compiler.warn.")) {
   185                 warnsFound++;
   186             } else if (line.matches("[0-9]+ error(?:s?)")) {
   187                 errsReported = Integer.valueOf(line.substring(0, line.indexOf("error")).trim());
   188             } else if (line.matches("[0-9]+ warning(?:s?)")) {
   189                 warnsReported = Integer.valueOf(line.substring(0, line.indexOf("warning")).trim());
   190             }
   191         }
   193         // Compute the expected number of errors and warnings, based on
   194         // the test case parameters.
   195         // This is highly specific to the annotation processor below, and to
   196         // the files it generates.
   197         // Generally, the rules are:
   198         // -- errors stop annotation processing, allowing for one extra "last round"
   199         // -- messager warnings are immediate
   200         // -- javac warnings are not shown before the final compilation
   201         //      (FIXME?  -Werror does not stop processing for java warnings)
   202         int errsExpected;
   203         int msgrWarnsExpected;
   204         int javaWarnsExpected;
   205         switch (ek) {
   206             case NONE:
   207                 errsExpected = 0;
   208                 msgrWarnsExpected = mwk.count(1, 1 + MAX_GEN + 1);
   209                 javaWarnsExpected = jwk.count(2, 1 + MAX_GEN);
   210                 break;
   211             case MESSAGER:
   212                 errsExpected = 1;
   213                 msgrWarnsExpected = mwk.count(1, ERROR_ROUND + 1);
   214                 javaWarnsExpected = 0;
   215                 break;
   216             case JAVA:
   217                 errsExpected = 2;
   218                 msgrWarnsExpected = mwk.count(1, ERROR_ROUND + 1);
   219                 javaWarnsExpected = 0;
   220                 break;
   221             case WERROR:
   222                 errsExpected = (mwk != WarnKind.NONE || jwk != WarnKind.NONE) ? 1 : 0;
   223                 switch (mwk) {
   224                     case NONE:
   225                         msgrWarnsExpected = 0;
   226                         javaWarnsExpected = (jwk == WarnKind.NONE)
   227                                 ? 0
   228                                 : 1;  // this is surprising: javac only reports warning in first file
   229                         break;
   230                     case EVERY_TWO:
   231                         msgrWarnsExpected = mwk.count(1, 2 + 1);
   232                         javaWarnsExpected = 0;
   233                         break;
   234                     case EVERY_THREE:
   235                         msgrWarnsExpected = mwk.count(1, 3 + 1);
   236                         javaWarnsExpected = 0;
   237                         break;
   238                     case ALL:
   239                         msgrWarnsExpected = mwk.count(1, 1 + 1);
   240                         javaWarnsExpected = 0;
   241                         break;
   242                     default:
   243                         throw new IllegalStateException();
   244                 }
   245                 break;
   246             default:
   247                 throw new IllegalStateException();
   248         }
   250         int warnsExpected = msgrWarnsExpected + javaWarnsExpected;
   251         System.err.println("mwk: " + msgrWarnsExpected
   252                 + ", jwk: " + javaWarnsExpected
   253                 + ", total: " + warnsExpected);
   255         boolean ok;
   256         ok  = checkEqual("errors", "reported", errsFound, errsReported);
   257         ok &= checkEqual("errors", "expected", errsFound, errsExpected);
   258         ok &= checkEqual("warnings", "reported", warnsFound, warnsReported);
   259         ok &= checkEqual("warnings", "expected", warnsFound, warnsExpected);
   260         if (ok)
   261             System.err.println("OK");
   263         System.err.println();
   264     }
   266     String compile(String... args) {
   267         StringWriter sw = new StringWriter();
   268         PrintWriter pw = new PrintWriter(sw);
   269         int rc = com.sun.tools.javac.Main.compile(args, pw);
   270         pw.close();
   271         String out = sw.toString();
   272         if (!out.isEmpty())
   273             System.err.println(out);
   274         if (rc != 0)
   275             System.err.println("compilation failed: rc=" + rc);
   276         return out;
   277     }
   279     boolean checkEqual(String l1, String l2, int i1, int i2) {
   280         if (i1 != i2)
   281             error("number of " + l1 + " found, " + i1 + ", does not match number " + l2 + ", " + i2);
   282         return (i1 == i2);
   283     }
   285     void error(String msg) {
   286         System.err.println("Error: " + msg);
   287         errors++;
   288     }
   290     int errors = 0;
   292     // ----- Annotation processor -----
   294     int round = 0;
   296     @Override
   297     public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
   298         round++;
   300         ErrorKind ek = ErrorKind.valueOf(options.get("errKind"));
   301         WarnKind mwk = WarnKind.valueOf(options.get("msgrWarnKind"));
   302         WarnKind jwk = WarnKind.valueOf(options.get("javaWarnKind"));
   303         messager.printMessage(Diagnostic.Kind.NOTE,
   304                 "Round " + round
   305                 + " " + roundEnv.getRootElements()
   306                 + ", last round: " + roundEnv.processingOver());
   307         messager.printMessage(Diagnostic.Kind.NOTE,
   308                 "ek: " + ek + ", mwk: " + mwk + ", jwk: " + jwk);
   310         if (round <= MAX_GEN && !roundEnv.processingOver())
   311             generate("Gen" + round,
   312                     (ek == ErrorKind.JAVA) && (round == ERROR_ROUND),
   313                     jwk.warn(round));
   315         if (mwk.warn(round))
   316             messager.printMessage(Diagnostic.Kind.WARNING, "round " + round);
   318         if ((ek == ErrorKind.MESSAGER) && (round == ERROR_ROUND))
   319             messager.printMessage(Diagnostic.Kind.ERROR, "round " + round);
   321         return true;
   322     }
   324     void generate(String name, boolean error, boolean warn) {
   325         try {
   326             JavaFileObject fo = filer.createSourceFile(name);
   327             Writer out = fo.openWriter();
   328             try {
   329                 out.write("class " + name + " {\n"
   330                         + (warn ? "    void m() throws Exception { try (AutoCloseable ac = null) { } }" : "")
   331                         + (error ? "   ERROR\n" : "")
   332                         + "}\n");
   333             } finally {
   334                 out.close();
   335             }
   336         } catch (IOException e) {
   337             throw new Error(e);
   338         }
   339     }
   340 }

mercurial