6768932: Add support for multiline diagnostics
Summary: Added basic support for multiline/tabular diagnostics
Reviewed-by: jjg
--- 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);