6768932: Add support for multiline diagnostics
authormcimadamore
Wed, 12 Nov 2008 14:17:03 +0000
changeset 1591 e5a618442f5f
parent 1541 3c53424bbe3b
child 1592 6471e8a4578f
6768932: Add support for multiline diagnostics Summary: Added basic support for multiline/tabular diagnostics Reviewed-by: jjg
langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java
langtools/src/share/classes/com/sun/tools/javac/util/AbstractLog.java
langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java
langtools/src/share/classes/com/sun/tools/javac/util/LayoutCharacters.java
langtools/src/share/classes/com/sun/tools/javac/util/Log.java
langtools/src/share/classes/com/sun/tools/javac/util/MandatoryWarningHandler.java
langtools/src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java
--- a/langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java	Wed Jul 05 16:43:43 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java	Wed Nov 12 14:17:03 2008 +0000
@@ -27,13 +27,13 @@
 import java.util.Collection;
 import java.util.Locale;
 import javax.tools.JavaFileObject;
-import java.util.ResourceBundle;
 
 import com.sun.tools.javac.api.DiagnosticFormatter;
 import com.sun.tools.javac.api.Formattable;
 import com.sun.tools.javac.api.DiagnosticFormatter.PositionKind;
 import com.sun.tools.javac.file.JavacFileManager;
 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticType.*;
+import static com.sun.tools.javac.util.LayoutCharacters.*;
 
 /**
  * This abstract class provides a basic implementation of the functionalities that should be provided
@@ -72,8 +72,13 @@
 
     public String formatMessage(JCDiagnostic d, Locale l) {
         //this code should rely on the locale settings but it's not! See RFE 6443132
+        StringBuilder buf = new StringBuilder();
         Collection<String> args = formatArguments(d, l);
-        return localize(l, d.getCode(), args.toArray());
+        buf.append(localize(l, d.getCode(), args.toArray()));
+        if (d.isMultiline()) {
+            buf.append(formatSubdiagnostics(d, l));
+        }
+        return buf.toString();
     }
 
     public String formatKind(JCDiagnostic d, Locale l) {
@@ -165,6 +170,23 @@
         return sbuf.toString();
     }
 
+    /**
+     * Format all the subdiagnostics attached to a given diagnostic
+     *
+     * @param d diagnostic whose subdiagnostics are to be formatted
+     * @param l locale object to be used for i18n
+     * @return string representation of the subdiagnostics
+     */
+    protected String formatSubdiagnostics(JCDiagnostic d, Locale l) {
+        StringBuilder buf = new StringBuilder();
+        for (JCDiagnostic d2 : d.getSubdiagnostics()) {
+            buf.append('\n');
+            String subdiagMsg = format(d2, l);
+            buf.append(indent(subdiagMsg, DiagInc));
+        }
+        return buf.toString();
+    }
+
     /** Format the faulty source code line and point to the error.
      *  @param d The diagnostic for which the error line should be printed
      */
@@ -201,4 +223,44 @@
     public boolean displaySource(JCDiagnostic d) {
         return showSource && d.getType() != FRAGMENT;
     }
+
+    /**
+     * Creates a string with a given amount of empty spaces. Useful for
+     * indenting the text of a diagnostic message.
+     *
+     * @param nSpaces the amount of spaces to be added to the result string
+     * @return the indentation string
+     */
+    protected String indentString(int nSpaces) {
+        String spaces = "                        ";
+        if (nSpaces <= spaces.length())
+            return spaces.substring(0, nSpaces);
+        else {
+            StringBuilder buf = new StringBuilder();
+            for (int i = 0 ; i < nSpaces ; i++)
+                buf.append(" ");
+            return buf.toString();
+        }
+    }
+
+    /**
+     * Indent a string by prepending a given amount of empty spaces to each line
+     * of the string
+     *
+     * @param s the string to be indented
+     * @param nSpaces the amount of spaces that should be prepended to each line
+     * of the string
+     * @return an indented string
+     */
+    protected String indent(String s, int nSpaces) {
+        String indent = indentString(nSpaces);
+        StringBuilder buf = new StringBuilder();
+        String nl = "";
+        for (String line : s.split("\n")) {
+            buf.append(nl);
+            buf.append(indent + line);
+            nl = "\n";
+        }
+        return buf.toString();
+    }
 }
--- a/langtools/src/share/classes/com/sun/tools/javac/util/AbstractLog.java	Wed Jul 05 16:43:43 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/AbstractLog.java	Wed Nov 12 14:17:03 2008 +0000
@@ -67,6 +67,12 @@
         return s;
     }
 
+    /** Return the underlying diagnostic source
+     */
+    public DiagnosticSource currentSource() {
+        return source;
+    }
+
     /** Report an error, unless another error was already reported at same
      *  source position.
      *  @param key    The key for the localized error message.
--- a/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java	Wed Jul 05 16:43:43 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java	Wed Nov 12 14:17:03 2008 +0000
@@ -289,7 +289,7 @@
         this.source = source;
         this.position = pos;
         this.key = key;
-        this.args = args;
+            this.args = args;
 
         int n = (pos == null ? Position.NOPOS : pos.getPreferredPosition());
         if (n == Position.NOPOS || source == null)
@@ -309,6 +309,18 @@
     }
 
     /**
+     * Get the subdiagnostic list
+     * @return subdiagnostic list
+     */
+    public List<JCDiagnostic> getSubdiagnostics() {
+        return List.nil();
+    }
+
+    public boolean isMultiline() {
+        return false;
+    }
+
+    /**
      * Check whether or not this diagnostic is required to be shown.
      * @return true if this diagnostic is required to be shown.
      */
@@ -440,7 +452,32 @@
     }
 
     public String getMessage(Locale locale) {
-        // RFE 6406133: JCDiagnostic.getMessage ignores locale argument
         return defaultFormatter.formatMessage(this, locale);
     }
+
+    public static class MultilineDiagnostic extends JCDiagnostic {
+
+        private final List<JCDiagnostic> subdiagnostics;
+
+        public MultilineDiagnostic(JCDiagnostic other, List<JCDiagnostic> subdiagnostics) {
+            super(other.defaultFormatter,
+                  other.getType(),
+                  other.isMandatory(),
+                  other.getDiagnosticSource(),
+                  other.position,
+                  other.getCode(),
+                  other.getArgs());
+            this.subdiagnostics = subdiagnostics;
+        }
+
+        @Override
+        public List<JCDiagnostic> getSubdiagnostics() {
+            return subdiagnostics;
+        }
+
+        @Override
+        public boolean isMultiline() {
+            return true;
+        }
+    }
 }
--- a/langtools/src/share/classes/com/sun/tools/javac/util/LayoutCharacters.java	Wed Jul 05 16:43:43 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/LayoutCharacters.java	Wed Nov 12 14:17:03 2008 +0000
@@ -39,6 +39,10 @@
      */
     final static int TabInc = 8;
 
+    /** Diagnostic standard indentation
+     */
+    final static int DiagInc = 2;
+
     /** Tabulator character.
      */
     final static byte TAB   = 0x8;
--- a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java	Wed Jul 05 16:43:43 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java	Wed Nov 12 14:17:03 2008 +0000
@@ -190,9 +190,9 @@
         getSource(name).setEndPosTable(table);
     }
 
-    /** Return current source name.
+    /** Return current sourcefile.
      */
-    public JavaFileObject currentSource() {
+    public JavaFileObject currentSourceFile() {
         return source == null ? null : source.getFile();
     }
 
@@ -395,7 +395,7 @@
             printLines(errWriter, "error: " + msg);
         } else {
             int line = source.getLineNumber(pos);
-            JavaFileObject file = currentSource();
+            JavaFileObject file = source.getFile();
             if (file != null)
                 printLines(errWriter,
                            JavacFileManager.getJavacFileName(file) + ":" +
@@ -408,7 +408,7 @@
     /** report an error:
      */
     public void rawError(int pos, String msg) {
-        if (nerrors < MaxErrors && shouldReport(currentSource(), pos)) {
+        if (nerrors < MaxErrors && shouldReport(currentSourceFile(), pos)) {
             printRawError(pos, msg);
             prompt();
             nerrors++;
--- a/langtools/src/share/classes/com/sun/tools/javac/util/MandatoryWarningHandler.java	Wed Jul 05 16:43:43 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/MandatoryWarningHandler.java	Wed Nov 12 14:17:03 2008 +0000
@@ -118,7 +118,7 @@
      * Report a mandatory warning.
      */
     public void report(DiagnosticPosition pos, String msg, Object... args) {
-        JavaFileObject currentSource = log.currentSource();
+        JavaFileObject currentSource = log.currentSourceFile();
 
         if (verbose) {
             if (sourcesWithReportedWarnings == null)
--- a/langtools/src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java	Wed Jul 05 16:43:43 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java	Wed Nov 12 14:17:03 2008 +0000
@@ -85,6 +85,20 @@
     }
 
     @Override
+    protected String formatSubdiagnostics(JCDiagnostic d, Locale l) {
+        StringBuilder buf = new StringBuilder();
+        String sep = "";
+        buf.append(",{");
+        for (JCDiagnostic d2 : d.getSubdiagnostics()) {
+            buf.append(sep);
+            buf.append("(" + format(d2, l) + ")");
+            sep = ",";
+        }
+        buf.append('}');
+        return buf.toString();
+    }
+
+    @Override
     protected String localize(Locale l, String s, Object... args) {
         StringBuffer buf = new StringBuffer();
         buf.append(s);