8066843: Messager.printMessage cannot print multiple errors for same source position
authorjlahoda
Tue, 13 Jan 2015 19:13:42 +0100
changeset 28455 41245007c074
parent 28454 63c31d7de8f6
child 28456 b87fdde1404d
8066843: Messager.printMessage cannot print multiple errors for same source position Summary: Using a DiagnosticFlag to mark diagnostics that should be always printed even if multiple of them have the same source position. Reviewed-by: darcy, jjg, mcimadamore
langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/resources/doclint.properties
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacMessager.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JCDiagnostic.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java
langtools/test/tools/doclint/AnchorTest.out
langtools/test/tools/doclint/AnchorTest2.out
langtools/test/tools/doclint/HtmlTagsTest.out
langtools/test/tools/doclint/anchorTests/p/Test.javac.out
langtools/test/tools/doclint/anchorTests/p/Test.out
langtools/test/tools/doclint/anchorTests/p/package-info.javac.out
langtools/test/tools/doclint/anchorTests/p/package-info.out
langtools/test/tools/doclint/tidy/AnchorAlreadyDefined.out
langtools/test/tools/javac/6304921/TestLog.java
langtools/test/tools/javac/processing/TestMultipleErrors.java
langtools/test/tools/javac/processing/TestMultipleErrors.out
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/resources/doclint.properties	Tue Jan 13 10:36:41 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/resources/doclint.properties	Tue Jan 13 19:13:42 2015 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 # questions.
 #
 
-dc.anchor.already.defined = anchor already defined: {0}
+dc.anchor.already.defined = anchor already defined: "{0}"
 dc.anchor.value.missing = no value given for anchor
 dc.attr.lacks.value = attribute lacks value
 dc.attr.not.number = attribute value is not a number
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java	Tue Jan 13 10:36:41 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java	Tue Jan 13 19:13:42 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -98,6 +98,7 @@
 import com.sun.tools.javac.util.DefinedBy;
 import com.sun.tools.javac.util.DefinedBy.Api;
 import com.sun.tools.javac.util.JCDiagnostic;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
 import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.util.ListBuffer;
 import com.sun.tools.javac.util.Log;
@@ -924,12 +925,7 @@
         try {
             switch (kind) {
             case ERROR:
-                boolean prev = log.multipleErrors;
-                try {
-                    log.error(pos, "proc.messager", msg.toString());
-                } finally {
-                    log.multipleErrors = prev;
-                }
+                log.error(DiagnosticFlag.MULTIPLE, pos, "proc.messager", msg.toString());
                 break;
 
             case WARNING:
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacMessager.java	Tue Jan 13 10:36:41 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacMessager.java	Tue Jan 13 19:13:42 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
 import com.sun.tools.javac.model.JavacElements;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.DefinedBy.Api;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
 import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.tree.JCTree.*;
 import javax.lang.model.element.*;
@@ -113,13 +114,7 @@
             switch (kind) {
             case ERROR:
                 errorCount++;
-                boolean prev = log.multipleErrors;
-                log.multipleErrors = true;
-                try {
-                    log.error(pos, "proc.messager", msg.toString());
-                } finally {
-                    log.multipleErrors = prev;
-                }
+                log.error(DiagnosticFlag.MULTIPLE, pos, "proc.messager", msg.toString());
                 break;
 
             case WARNING:
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JCDiagnostic.java	Tue Jan 13 10:36:41 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JCDiagnostic.java	Tue Jan 13 19:13:42 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -112,7 +112,7 @@
          */
         public JCDiagnostic error(
                 DiagnosticFlag flag, DiagnosticSource source, DiagnosticPosition pos, Error errorKey) {
-            JCDiagnostic diag = create(null, defaultErrorFlags, source, pos, errorKey);
+            JCDiagnostic diag = create(null, EnumSet.copyOf(defaultErrorFlags), source, pos, errorKey);
             if (flag != null) {
                 diag.setFlag(flag);
             }
@@ -432,7 +432,10 @@
         SYNTAX,
         RECOVERABLE,
         NON_DEFERRABLE,
-        COMPRESSED
+        COMPRESSED,
+        /** Print multiple errors for same source locations.
+         */
+        MULTIPLE;
     }
 
     private final DiagnosticSource source;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java	Tue Jan 13 10:36:41 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java	Tue Jan 13 19:13:42 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -38,6 +38,7 @@
 import com.sun.tools.javac.main.Main;
 import com.sun.tools.javac.main.Option;
 import com.sun.tools.javac.tree.EndPosTable;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
 
@@ -191,10 +192,6 @@
      */
     public boolean dumpOnError;
 
-    /** Print multiple errors for same source locations.
-     */
-    public boolean multipleErrors;
-
     /**
      * Diagnostic listener, if provided through programmatic
      * interface to javac (JSR 199).
@@ -417,7 +414,7 @@
      * source name and pos.
      */
     protected boolean shouldReport(JavaFileObject file, int pos) {
-        if (multipleErrors || file == null)
+        if (file == null)
             return true;
 
         Pair<JavaFileObject,Integer> coords = new Pair<>(file, pos);
@@ -580,8 +577,9 @@
                 break;
 
             case ERROR:
-                if (nerrors < MaxErrors
-                    && shouldReport(diagnostic.getSource(), diagnostic.getIntPosition())) {
+                if (nerrors < MaxErrors &&
+                    (diagnostic.isFlagSet(DiagnosticFlag.MULTIPLE) ||
+                     shouldReport(diagnostic.getSource(), diagnostic.getIntPosition()))) {
                     writeDiagnostic(diagnostic);
                     nerrors++;
                 }
--- a/langtools/test/tools/doclint/AnchorTest.out	Tue Jan 13 10:36:41 2015 +0100
+++ b/langtools/test/tools/doclint/AnchorTest.out	Tue Jan 13 19:13:42 2015 +0100
@@ -1,4 +1,4 @@
-AnchorTest.java:19: error: anchor already defined: foo
+AnchorTest.java:19: error: anchor already defined: "foo"
      * <a name=foo></a>
           ^
 AnchorTest.java:24: error: invalid name for anchor: ""
@@ -10,28 +10,40 @@
 AnchorTest.java:34: error: no value given for anchor
      * <a name ></a>
           ^
-AnchorTest.java:46: error: anchor already defined: foo
+AnchorTest.java:46: error: anchor already defined: "foo"
      * <a id=foo></a>
           ^
 AnchorTest.java:51: error: invalid name for anchor: ""
      * <a id=></a>
           ^
+AnchorTest.java:51: error: anchor already defined: ""
+     * <a id=></a>
+          ^
 AnchorTest.java:56: error: invalid name for anchor: "123"
      * <a id=123 ></a>
           ^
+AnchorTest.java:56: error: anchor already defined: "123"
+     * <a id=123 ></a>
+          ^
 AnchorTest.java:61: error: no value given for anchor
      * <a id ></a>
           ^
-AnchorTest.java:73: error: anchor already defined: foo
+AnchorTest.java:73: error: anchor already defined: "foo"
      * <p id=foo>text</p>
           ^
 AnchorTest.java:78: error: invalid name for anchor: ""
      * <p id=>text</p>
           ^
+AnchorTest.java:78: error: anchor already defined: ""
+     * <p id=>text</p>
+          ^
 AnchorTest.java:83: error: invalid name for anchor: "123"
      * <p id=123 >text</p>
           ^
+AnchorTest.java:83: error: anchor already defined: "123"
+     * <p id=123 >text</p>
+          ^
 AnchorTest.java:88: error: no value given for anchor
      * <p id >text</p>
           ^
-12 errors
+16 errors
--- a/langtools/test/tools/doclint/AnchorTest2.out	Tue Jan 13 10:36:41 2015 +0100
+++ b/langtools/test/tools/doclint/AnchorTest2.out	Tue Jan 13 19:13:42 2015 +0100
@@ -1,4 +1,4 @@
-AnchorTest2.java:15: error: anchor already defined: AnchorTest2
+AnchorTest2.java:15: error: anchor already defined: "AnchorTest2"
     /** <a name="AnchorTest2"> </a> */
            ^
 1 error
--- a/langtools/test/tools/doclint/HtmlTagsTest.out	Tue Jan 13 10:36:41 2015 +0100
+++ b/langtools/test/tools/doclint/HtmlTagsTest.out	Tue Jan 13 19:13:42 2015 +0100
@@ -13,6 +13,9 @@
 HtmlTagsTest.java:28: error: element not allowed in documentation comments: <html>
      * <html>
        ^
+HtmlTagsTest.java:28: error: element not closed: html
+     * <html>
+       ^
 HtmlTagsTest.java:33: error: block element not allowed within inline element <span>: p
      * <span> <p> </span>
               ^
@@ -40,5 +43,5 @@
 HtmlTagsTest.java:64: error: tag not allowed here: <b>
      * <ul> <b>text</b> <li> ... </li> </ul>
             ^
-13 errors
-1 warning
+14 errors
+1 warning
\ No newline at end of file
--- a/langtools/test/tools/doclint/anchorTests/p/Test.javac.out	Tue Jan 13 10:36:41 2015 +0100
+++ b/langtools/test/tools/doclint/anchorTests/p/Test.javac.out	Tue Jan 13 19:13:42 2015 +0100
@@ -1,7 +1,7 @@
-Test.java:14:7: compiler.err.proc.messager: anchor already defined: dupTest
-Test.java:24:12: compiler.err.proc.messager: anchor already defined: dupTestField
-Test.java:27:12: compiler.err.proc.messager: anchor already defined: dupTestMethod
-Test.java:32:11: compiler.err.proc.messager: anchor already defined: dupNested
-Test.java:40:15: compiler.err.proc.messager: anchor already defined: dupNestedField
-Test.java:47:15: compiler.err.proc.messager: anchor already defined: dupNestedMethod
+Test.java:14:7: compiler.err.proc.messager: anchor already defined: "dupTest"
+Test.java:24:12: compiler.err.proc.messager: anchor already defined: "dupTestField"
+Test.java:27:12: compiler.err.proc.messager: anchor already defined: "dupTestMethod"
+Test.java:32:11: compiler.err.proc.messager: anchor already defined: "dupNested"
+Test.java:40:15: compiler.err.proc.messager: anchor already defined: "dupNestedField"
+Test.java:47:15: compiler.err.proc.messager: anchor already defined: "dupNestedMethod"
 6 errors
--- a/langtools/test/tools/doclint/anchorTests/p/Test.out	Tue Jan 13 10:36:41 2015 +0100
+++ b/langtools/test/tools/doclint/anchorTests/p/Test.out	Tue Jan 13 19:13:42 2015 +0100
@@ -1,19 +1,19 @@
-Test.java:14: error: anchor already defined: dupTest
+Test.java:14: error: anchor already defined: "dupTest"
  * <a name="dupTest">dupTest again</a>
       ^
-Test.java:24: error: anchor already defined: dupTestField
+Test.java:24: error: anchor already defined: "dupTestField"
     /** <a name="dupTestField">dupTestField again</a> */
            ^
-Test.java:27: error: anchor already defined: dupTestMethod
+Test.java:27: error: anchor already defined: "dupTestMethod"
     /** <a name="dupTestMethod">dupTestMethod again</a> */
            ^
-Test.java:32: error: anchor already defined: dupNested
+Test.java:32: error: anchor already defined: "dupNested"
      * <a name="dupNested">dupNested again</a>
           ^
-Test.java:40: error: anchor already defined: dupNestedField
+Test.java:40: error: anchor already defined: "dupNestedField"
          * <a name="dupNestedField">dupNestedField</a>
               ^
-Test.java:47: error: anchor already defined: dupNestedMethod
+Test.java:47: error: anchor already defined: "dupNestedMethod"
          * <a name="dupNestedMethod">dupNestedMethod</a>
               ^
 6 errors
--- a/langtools/test/tools/doclint/anchorTests/p/package-info.javac.out	Tue Jan 13 10:36:41 2015 +0100
+++ b/langtools/test/tools/doclint/anchorTests/p/package-info.javac.out	Tue Jan 13 19:13:42 2015 +0100
@@ -1,2 +1,2 @@
-package-info.java:12:7: compiler.err.proc.messager: anchor already defined: here
+package-info.java:12:7: compiler.err.proc.messager: anchor already defined: "here"
 1 error
--- a/langtools/test/tools/doclint/anchorTests/p/package-info.out	Tue Jan 13 10:36:41 2015 +0100
+++ b/langtools/test/tools/doclint/anchorTests/p/package-info.out	Tue Jan 13 19:13:42 2015 +0100
@@ -1,4 +1,4 @@
-package-info.java:12: error: anchor already defined: here
+package-info.java:12: error: anchor already defined: "here"
  * <a name=here>here again</a>
       ^
 1 error
--- a/langtools/test/tools/doclint/tidy/AnchorAlreadyDefined.out	Tue Jan 13 10:36:41 2015 +0100
+++ b/langtools/test/tools/doclint/tidy/AnchorAlreadyDefined.out	Tue Jan 13 19:13:42 2015 +0100
@@ -1,7 +1,7 @@
-AnchorAlreadyDefined.java:14: error: anchor already defined: here
+AnchorAlreadyDefined.java:14: error: anchor already defined: "here"
  * <a name="here">duplicate</a>
       ^
-AnchorAlreadyDefined.java:15: error: anchor already defined: here
+AnchorAlreadyDefined.java:15: error: anchor already defined: "here"
  * <h1 id="here">duplicate</h1>
        ^
 2 errors
--- a/langtools/test/tools/javac/6304921/TestLog.java	Tue Jan 13 10:36:41 2015 +0100
+++ b/langtools/test/tools/javac/6304921/TestLog.java	Tue Jan 13 19:13:42 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,10 +26,11 @@
  * @bug 6304912
  * @summary unit test for Log
  */
+import java.lang.reflect.Field;
 import java.io.InputStream;
-import java.io.IOException;
 import java.io.OutputStream;
 import java.net.URI;
+import java.util.Set;
 import javax.tools.JavaFileObject;
 import javax.tools.SimpleJavaFileObject;
 import com.sun.tools.javac.file.JavacFileManager;
@@ -41,23 +42,34 @@
 import com.sun.tools.javac.util.Context;
 import com.sun.tools.javac.util.Log;
 import com.sun.tools.javac.util.JCDiagnostic;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
+import com.sun.tools.javac.util.JCDiagnostic.Factory;
 import com.sun.tools.javac.util.Options;
 
 public class TestLog
 {
-    public static void main(String... args) throws IOException {
+    public static void main(String... args) throws Exception {
         test(false);
         test(true);
     }
 
-    static void test(boolean genEndPos) throws IOException {
+    static void test(boolean genEndPos) throws Exception {
         Context context = new Context();
 
         Options options = Options.instance(context);
         options.put("diags", "%b:%s/%o/%e:%_%t%m|%p%m");
 
         Log log = Log.instance(context);
-        log.multipleErrors = true;
+        Factory diagnosticFactory = JCDiagnostic.Factory.instance(context);
+        Field defaultErrorFlagsField =
+                JCDiagnostic.Factory.class.getDeclaredField("defaultErrorFlags");
+
+        defaultErrorFlagsField.setAccessible(true);
+
+        Set<DiagnosticFlag> defaultErrorFlags =
+                (Set<DiagnosticFlag>) defaultErrorFlagsField.get(diagnosticFactory);
+
+        defaultErrorFlags.add(DiagnosticFlag.MULTIPLE);
 
         JavacFileManager.preRegister(context);
         ParserFactory pfac = ParserFactory.instance(context);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/TestMultipleErrors.java	Tue Jan 13 19:13:42 2015 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ * @test
+ * @bug 8066843
+ * @summary Annotation processors should be able to print multiple errors at the same location.
+ * @library /tools/javac/lib
+ * @build JavacTestingAbstractProcessor TestMultipleErrors
+ * @compile/fail/ref=TestMultipleErrors.out -XDrawDiagnostics -processor TestMultipleErrors TestMultipleErrors.java
+ */
+
+import java.util.*;
+import javax.annotation.processing.*;
+import javax.lang.model.element.*;
+import javax.tools.Diagnostic.Kind;
+import com.sun.source.util.TreePath;
+import com.sun.source.util.Trees;
+
+public class TestMultipleErrors extends JavacTestingAbstractProcessor {
+    @Override
+    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        for (Element root : roundEnv.getRootElements()) {
+            processingEnv.getMessager().printMessage(Kind.ERROR, "error1", root);
+            processingEnv.getMessager().printMessage(Kind.ERROR, "error2", root);
+
+            Trees trees = Trees.instance(processingEnv);
+            TreePath path = trees.getPath(root);
+
+            trees.printMessage(Kind.ERROR, "error3", path.getLeaf(), path.getCompilationUnit());
+            trees.printMessage(Kind.ERROR, "error4", path.getLeaf(), path.getCompilationUnit());
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/TestMultipleErrors.out	Tue Jan 13 19:13:42 2015 +0100
@@ -0,0 +1,5 @@
+TestMultipleErrors.java:41:8: compiler.err.proc.messager: error1
+TestMultipleErrors.java:41:8: compiler.err.proc.messager: error2
+TestMultipleErrors.java:41:8: compiler.err.proc.messager: error3
+TestMultipleErrors.java:41:8: compiler.err.proc.messager: error4
+4 errors