6768932: Add support for multiline diagnostics

Added basic support for multiline/tabular diagnostics

Reviewed-by: jjg
This commit is contained in:
Maurizio Cimadamore 2008-11-12 14:17:03 +00:00
parent 6c04fd835e
commit 454f269528
7 changed files with 132 additions and 9 deletions

View File

@ -27,13 +27,13 @@ package com.sun.tools.javac.util;
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 abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
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 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
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 abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
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();
}
}

View File

@ -67,6 +67,12 @@ public abstract class AbstractLog {
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.

View File

@ -289,7 +289,7 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
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)
@ -308,6 +308,18 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
return type;
}
/**
* 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 class JCDiagnostic implements Diagnostic<JavaFileObject> {
}
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;
}
}
}

View File

@ -39,6 +39,10 @@ public interface LayoutCharacters {
*/
final static int TabInc = 8;
/** Diagnostic standard indentation
*/
final static int DiagInc = 2;
/** Tabulator character.
*/
final static byte TAB = 0x8;

View File

@ -190,9 +190,9 @@ public class Log extends AbstractLog {
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 @@ public class Log extends AbstractLog {
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 @@ public class Log extends AbstractLog {
/** 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++;

View File

@ -118,7 +118,7 @@ public class MandatoryWarningHandler {
* 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)

View File

@ -84,6 +84,20 @@ public class RawDiagnosticFormatter extends AbstractDiagnosticFormatter {
return s;
}
@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();