7022741: warning counts are wrong after anno processing

Mon, 28 Feb 2011 13:37:48 -0800

author
jjg
date
Mon, 28 Feb 2011 13:37:48 -0800
changeset 898
bf9f162c7104
parent 897
9029f694e5df
child 899
67d6b2df47ba

7022741: warning counts are wrong after anno processing
Reviewed-by: mcimadamore

src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java file | annotate | diff | comparison | revisions
test/tools/javac/processing/TestWarnErrorCount.java file | annotate | diff | comparison | revisions
test/tools/javac/processing/warnings/gold_0.out file | annotate | diff | comparison | revisions
test/tools/javac/processing/warnings/gold_sv_warn_0_2.out file | annotate | diff | comparison | revisions
test/tools/javac/processing/warnings/gold_sv_warn_2_3.out file | annotate | diff | comparison | revisions
test/tools/javac/processing/warnings/gold_sv_warn_5_6.out file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Mon Feb 28 12:19:18 2011 -0800
     1.2 +++ b/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Mon Feb 28 13:37:48 2011 -0800
     1.3 @@ -807,8 +807,6 @@
     1.4          final JavaCompiler compiler;
     1.5          /** The log for the round. */
     1.6          final Log log;
     1.7 -        /** The number of warnings in the previous round. */
     1.8 -        final int priorWarnings;
     1.9  
    1.10          /** The ASTs to be compiled. */
    1.11          List<JCCompilationUnit> roots;
    1.12 @@ -826,10 +824,10 @@
    1.13          private Round(Context context, int number, int priorWarnings) {
    1.14              this.context = context;
    1.15              this.number = number;
    1.16 -            this.priorWarnings = priorWarnings;
    1.17  
    1.18              compiler = JavaCompiler.instance(context);
    1.19              log = Log.instance(context);
    1.20 +            log.nwarnings += priorWarnings;
    1.21              log.deferDiagnostics = true;
    1.22  
    1.23              // the following is for the benefit of JavacProcessingEnvironment.getContext()
    1.24 @@ -904,8 +902,8 @@
    1.25          JavaCompiler finalCompiler(boolean errorStatus) {
    1.26              try {
    1.27                  JavaCompiler c = JavaCompiler.instance(nextContext());
    1.28 +                c.log.nwarnings += compiler.log.nwarnings;
    1.29                  if (errorStatus) {
    1.30 -                    c.log.nwarnings += priorWarnings + compiler.log.nwarnings;
    1.31                      c.log.nerrors += compiler.log.nerrors;
    1.32                  }
    1.33                  return c;
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/test/tools/javac/processing/TestWarnErrorCount.java	Mon Feb 28 13:37:48 2011 -0800
     2.3 @@ -0,0 +1,340 @@
     2.4 +/*
     2.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
     2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.7 + *
     2.8 + * This code is free software; you can redistribute it and/or modify it
     2.9 + * under the terms of the GNU General Public License version 2 only, as
    2.10 + * published by the Free Software Foundation.
    2.11 + *
    2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    2.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    2.15 + * version 2 for more details (a copy is included in the LICENSE file that
    2.16 + * accompanied this code).
    2.17 + *
    2.18 + * You should have received a copy of the GNU General Public License version
    2.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    2.21 + *
    2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    2.23 + * or visit www.oracle.com if you need additional information or have any
    2.24 + * questions.
    2.25 + */
    2.26 +
    2.27 +
    2.28 +/*
    2.29 + * @test
    2.30 + * @bug 7022337
    2.31 + * @summary repeated warnings about bootclasspath not set
    2.32 + * @library ../lib
    2.33 + * @build JavacTestingAbstractProcessor TestWarnErrorCount
    2.34 + * @run main TestWarnErrorCount
    2.35 + */
    2.36 +
    2.37 +import java.io.*;
    2.38 +import java.util.*;
    2.39 +import javax.annotation.processing.*;
    2.40 +import javax.lang.model.element.*;
    2.41 +import javax.tools.*;
    2.42 +
    2.43 +@SupportedOptions({"errKind", "msgrWarnKind", "javaWarnKind"})
    2.44 +public class TestWarnErrorCount extends JavacTestingAbstractProcessor {
    2.45 +    public static void main(String... args) throws Exception {
    2.46 +        new TestWarnErrorCount().run(args);
    2.47 +    }
    2.48 +
    2.49 +    final int MAX_GEN = 10;
    2.50 +    final int ERROR_ROUND = MAX_GEN / 2; // when to generate error
    2.51 +
    2.52 +    /**
    2.53 +     * Type of errors to generate in test case.
    2.54 +     */
    2.55 +    enum ErrorKind {
    2.56 +        /** No errors. */
    2.57 +        NONE,
    2.58 +        /** Source code errors. */
    2.59 +        JAVA,
    2.60 +        /** Errors reported to Messager. */
    2.61 +        MESSAGER,
    2.62 +        /** Error as a result of using -Werror. */
    2.63 +        WERROR,
    2.64 +    }
    2.65 +
    2.66 +    /**
    2.67 +     * Frequency of warnings in test case.
    2.68 +     */
    2.69 +    enum WarnKind {
    2.70 +        /** No warnings. */
    2.71 +        NONE {
    2.72 +            boolean warn(int round) { return false; }
    2.73 +            int count(int start, int end) { return 0; }
    2.74 +        },
    2.75 +        /** Generate a warning if round count is a multiple of 2. */
    2.76 +        EVERY_TWO {
    2.77 +            boolean warn(int round) { return (round % 2) == 0; }
    2.78 +            int count(int start, int end) { return (end / 2) - ((start - 1)/ 2); }
    2.79 +        },
    2.80 +        /** Generate a warning if round count is a multiple of 3. */
    2.81 +        EVERY_THREE {
    2.82 +            boolean warn(int round) { return (round % 3) == 0; }
    2.83 +            int count(int start, int end) { return (end / 3) - ((start - 1)/ 3); }
    2.84 +        },
    2.85 +        /** Generate a warning every round. */
    2.86 +        ALL {
    2.87 +            boolean warn(int round) { return true; }
    2.88 +            int count(int start, int end) { return (end - start + 1); }
    2.89 +        };
    2.90 +
    2.91 +        /** whether to generate a warning in round 'round'. */
    2.92 +        abstract boolean warn(int round);
    2.93 +
    2.94 +        /** number of warnings generated in a range of rounds, inclusive. */
    2.95 +        abstract int count(int start, int end);
    2.96 +    }
    2.97 +
    2.98 +
    2.99 +    /**
   2.100 +     * Run test.
   2.101 +     * @param args provide ability to specify particular test cases for debugging.
   2.102 +     */
   2.103 +    void run(String... args) throws Exception {
   2.104 +        for (String arg: args) {
   2.105 +            if (arg.matches("[0-9]+")) {
   2.106 +                if (testCases == null)
   2.107 +                    testCases = new HashSet<Integer>();
   2.108 +                testCases.add(Integer.valueOf(arg));
   2.109 +            } else if (arg.equals("-stopOnError")) {
   2.110 +                stopOnError = true;
   2.111 +            } else
   2.112 +                throw new IllegalArgumentException(arg);
   2.113 +        }
   2.114 +
   2.115 +        run ();
   2.116 +
   2.117 +        if (errors > 0)
   2.118 +            throw new Exception(errors + " errors found");
   2.119 +    }
   2.120 +
   2.121 +    /**
   2.122 +     * Run test.
   2.123 +     */
   2.124 +    void run() throws Exception {
   2.125 +        for (ErrorKind ek: ErrorKind.values()) {
   2.126 +            for (WarnKind mwk: WarnKind.values()) {
   2.127 +                for (WarnKind jwk: WarnKind.values()) {
   2.128 +                    test(ek, mwk, jwk);
   2.129 +                    if (stopOnError && errors > 0)
   2.130 +                        throw new Exception(errors + " errors found");
   2.131 +                }
   2.132 +            }
   2.133 +        }
   2.134 +    }
   2.135 +
   2.136 +    boolean stopOnError;
   2.137 +    Set<Integer> testCases;
   2.138 +    int testNum = 0;
   2.139 +
   2.140 +    /**
   2.141 +     * Run a test case.
   2.142 +     * @param ek    The type of errors to generate
   2.143 +     * @param mwk   The frequency of Messager warnings to generate
   2.144 +     * @param jwk   The frequency of Java warnings to generate
   2.145 +     */
   2.146 +    void test(ErrorKind ek, WarnKind mwk, WarnKind jwk) {
   2.147 +        testNum++;
   2.148 +
   2.149 +        if (testCases != null && !testCases.contains(testNum))
   2.150 +            return;
   2.151 +
   2.152 +        System.err.println("Test " + testNum + ": ek:" + ek + " mwk:" + mwk + " jwk:" + jwk);
   2.153 +
   2.154 +        File testDir = new File("test" + testNum);
   2.155 +        testDir.mkdirs();
   2.156 +
   2.157 +        String myName = TestWarnErrorCount.class.getSimpleName();
   2.158 +        File testSrc = new File(System.getProperty("test.src"));
   2.159 +        File file = new File(testSrc, myName + ".java");
   2.160 +
   2.161 +        List<String> args = new ArrayList<String>();
   2.162 +        args.addAll(Arrays.asList(
   2.163 +            "-XDrawDiagnostics",
   2.164 +            "-d", testDir.getPath(),
   2.165 +            "-processor", myName,
   2.166 +//            "-XprintRounds",
   2.167 +            "-Xlint",
   2.168 +            "-AerrKind=" + ek,
   2.169 +            "-AmsgrWarnKind=" + mwk,
   2.170 +            "-AjavaWarnKind=" + jwk));
   2.171 +        if (ek == ErrorKind.WERROR)
   2.172 +            args.add("-Werror");
   2.173 +        args.add(file.getPath());
   2.174 +
   2.175 +        String out = compile(args.toArray(new String[args.size()]));
   2.176 +
   2.177 +        int errsFound = 0;
   2.178 +        int errsReported = 0;
   2.179 +        int warnsFound = 0;
   2.180 +        int warnsReported = 0;
   2.181 +
   2.182 +        // Scan the output looking for messages of interest.
   2.183 +
   2.184 +        for (String line: out.split("[\r\n]+")) {
   2.185 +            if (line.contains("compiler.err.")) {
   2.186 +                errsFound++;
   2.187 +            } else if (line.contains("compiler.warn.")) {
   2.188 +                warnsFound++;
   2.189 +            } else if (line.matches("[0-9]+ error(?:s?)")) {
   2.190 +                errsReported = Integer.valueOf(line.substring(0, line.indexOf("error")).trim());
   2.191 +            } else if (line.matches("[0-9]+ warning(?:s?)")) {
   2.192 +                warnsReported = Integer.valueOf(line.substring(0, line.indexOf("warning")).trim());
   2.193 +            }
   2.194 +        }
   2.195 +
   2.196 +        // Compute the expected number of errors and warnings, based on
   2.197 +        // the test case parameters.
   2.198 +        // This is highly specific to the annotation processor below, and to
   2.199 +        // the files it generates.
   2.200 +        // Generally, the rules are:
   2.201 +        // -- errors stop annotation processing, allowing for one extra "last round"
   2.202 +        // -- messager warnings are immediate
   2.203 +        // -- javac warnings are not shown before the final compilation
   2.204 +        //      (FIXME?  -Werror does not stop processing for java warnings)
   2.205 +        int errsExpected;
   2.206 +        int msgrWarnsExpected;
   2.207 +        int javaWarnsExpected;
   2.208 +        switch (ek) {
   2.209 +            case NONE:
   2.210 +                errsExpected = 0;
   2.211 +                msgrWarnsExpected = mwk.count(1, 1 + MAX_GEN + 1);
   2.212 +                javaWarnsExpected = jwk.count(2, 1 + MAX_GEN);
   2.213 +                break;
   2.214 +            case MESSAGER:
   2.215 +                errsExpected = 1;
   2.216 +                msgrWarnsExpected = mwk.count(1, ERROR_ROUND + 1);
   2.217 +                javaWarnsExpected = 0;
   2.218 +                break;
   2.219 +            case JAVA:
   2.220 +                errsExpected = 2;
   2.221 +                msgrWarnsExpected = mwk.count(1, ERROR_ROUND + 1);
   2.222 +                javaWarnsExpected = 0;
   2.223 +                break;
   2.224 +            case WERROR:
   2.225 +                errsExpected = (mwk != WarnKind.NONE || jwk != WarnKind.NONE) ? 1 : 0;
   2.226 +                switch (mwk) {
   2.227 +                    case NONE:
   2.228 +                        msgrWarnsExpected = 0;
   2.229 +                        javaWarnsExpected = (jwk == WarnKind.NONE)
   2.230 +                                ? 0
   2.231 +                                : 1;  // this is surprising: javac only reports warning in first file
   2.232 +                        break;
   2.233 +                    case EVERY_TWO:
   2.234 +                        msgrWarnsExpected = mwk.count(1, 2 + 1);
   2.235 +                        javaWarnsExpected = 0;
   2.236 +                        break;
   2.237 +                    case EVERY_THREE:
   2.238 +                        msgrWarnsExpected = mwk.count(1, 3 + 1);
   2.239 +                        javaWarnsExpected = 0;
   2.240 +                        break;
   2.241 +                    case ALL:
   2.242 +                        msgrWarnsExpected = mwk.count(1, 1 + 1);
   2.243 +                        javaWarnsExpected = 0;
   2.244 +                        break;
   2.245 +                    default:
   2.246 +                        throw new IllegalStateException();
   2.247 +                }
   2.248 +                break;
   2.249 +            default:
   2.250 +                throw new IllegalStateException();
   2.251 +        }
   2.252 +
   2.253 +        int warnsExpected = msgrWarnsExpected + javaWarnsExpected;
   2.254 +        System.err.println("mwk: " + msgrWarnsExpected
   2.255 +                + ", jwk: " + javaWarnsExpected
   2.256 +                + ", total: " + warnsExpected);
   2.257 +
   2.258 +        boolean ok;
   2.259 +        ok  = checkEqual("errors", "reported", errsFound, errsReported);
   2.260 +        ok &= checkEqual("errors", "expected", errsFound, errsExpected);
   2.261 +        ok &= checkEqual("warnings", "reported", warnsFound, warnsReported);
   2.262 +        ok &= checkEqual("warnings", "expected", warnsFound, warnsExpected);
   2.263 +        if (ok)
   2.264 +            System.err.println("OK");
   2.265 +
   2.266 +        System.err.println();
   2.267 +    }
   2.268 +
   2.269 +    String compile(String... args) {
   2.270 +        StringWriter sw = new StringWriter();
   2.271 +        PrintWriter pw = new PrintWriter(sw);
   2.272 +        int rc = com.sun.tools.javac.Main.compile(args, pw);
   2.273 +        pw.close();
   2.274 +        String out = sw.toString();
   2.275 +        if (!out.isEmpty())
   2.276 +            System.err.println(out);
   2.277 +        if (rc != 0)
   2.278 +            System.err.println("compilation failed: rc=" + rc);
   2.279 +        return out;
   2.280 +    }
   2.281 +
   2.282 +    boolean checkEqual(String l1, String l2, int i1, int i2) {
   2.283 +        if (i1 != i2)
   2.284 +            error("number of " + l1 + " found, " + i1 + ", does not match number " + l2 + ", " + i2);
   2.285 +        return (i1 == i2);
   2.286 +    }
   2.287 +
   2.288 +    void error(String msg) {
   2.289 +        System.err.println("Error: " + msg);
   2.290 +        errors++;
   2.291 +    }
   2.292 +
   2.293 +    int errors = 0;
   2.294 +
   2.295 +    // ----- Annotation processor -----
   2.296 +
   2.297 +    int round = 0;
   2.298 +
   2.299 +    @Override
   2.300 +    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
   2.301 +        round++;
   2.302 +
   2.303 +        ErrorKind ek = ErrorKind.valueOf(options.get("errKind"));
   2.304 +        WarnKind mwk = WarnKind.valueOf(options.get("msgrWarnKind"));
   2.305 +        WarnKind jwk = WarnKind.valueOf(options.get("javaWarnKind"));
   2.306 +        messager.printMessage(Diagnostic.Kind.NOTE,
   2.307 +                "Round " + round
   2.308 +                + " " + roundEnv.getRootElements()
   2.309 +                + ", last round: " + roundEnv.processingOver());
   2.310 +        messager.printMessage(Diagnostic.Kind.NOTE,
   2.311 +                "ek: " + ek + ", mwk: " + mwk + ", jwk: " + jwk);
   2.312 +
   2.313 +        if (round <= MAX_GEN && !roundEnv.processingOver())
   2.314 +            generate("Gen" + round,
   2.315 +                    (ek == ErrorKind.JAVA) && (round == ERROR_ROUND),
   2.316 +                    jwk.warn(round));
   2.317 +
   2.318 +        if (mwk.warn(round))
   2.319 +            messager.printMessage(Diagnostic.Kind.WARNING, "round " + round);
   2.320 +
   2.321 +        if ((ek == ErrorKind.MESSAGER) && (round == ERROR_ROUND))
   2.322 +            messager.printMessage(Diagnostic.Kind.ERROR, "round " + round);
   2.323 +
   2.324 +        return true;
   2.325 +    }
   2.326 +
   2.327 +    void generate(String name, boolean error, boolean warn) {
   2.328 +        try {
   2.329 +            JavaFileObject fo = filer.createSourceFile(name);
   2.330 +            Writer out = fo.openWriter();
   2.331 +            try {
   2.332 +                out.write("class " + name + " {\n"
   2.333 +                        + (warn ? "    int i = (int) 0;\n" : "")
   2.334 +                        + (error ? "   ERROR\n" : "")
   2.335 +                        + "}\n");
   2.336 +            } finally {
   2.337 +                out.close();
   2.338 +            }
   2.339 +        } catch (IOException e) {
   2.340 +            throw new Error(e);
   2.341 +        }
   2.342 +    }
   2.343 +}
     3.1 --- a/test/tools/javac/processing/warnings/gold_0.out	Mon Feb 28 12:19:18 2011 -0800
     3.2 +++ b/test/tools/javac/processing/warnings/gold_0.out	Mon Feb 28 13:37:48 2011 -0800
     3.3 @@ -1,1 +1,2 @@
     3.4  - compiler.warn.proc.messager: No SourceVersion option given
     3.5 +1 warning
     4.1 --- a/test/tools/javac/processing/warnings/gold_sv_warn_0_2.out	Mon Feb 28 12:19:18 2011 -0800
     4.2 +++ b/test/tools/javac/processing/warnings/gold_sv_warn_0_2.out	Mon Feb 28 13:37:48 2011 -0800
     4.3 @@ -1,1 +1,2 @@
     4.4  - compiler.warn.proc.processor.incompatible.source.version: RELEASE_0, TestSourceVersionWarnings, 1.2
     4.5 +1 warning
     5.1 --- a/test/tools/javac/processing/warnings/gold_sv_warn_2_3.out	Mon Feb 28 12:19:18 2011 -0800
     5.2 +++ b/test/tools/javac/processing/warnings/gold_sv_warn_2_3.out	Mon Feb 28 13:37:48 2011 -0800
     5.3 @@ -1,1 +1,2 @@
     5.4  - compiler.warn.proc.processor.incompatible.source.version: RELEASE_2, TestSourceVersionWarnings, 1.3
     5.5 +1 warning
     6.1 --- a/test/tools/javac/processing/warnings/gold_sv_warn_5_6.out	Mon Feb 28 12:19:18 2011 -0800
     6.2 +++ b/test/tools/javac/processing/warnings/gold_sv_warn_5_6.out	Mon Feb 28 13:37:48 2011 -0800
     6.3 @@ -1,1 +1,2 @@
     6.4  - compiler.warn.proc.processor.incompatible.source.version: RELEASE_5, TestSourceVersionWarnings, 1.6
     6.5 +1 warning

mercurial