6768932: Add support for multiline diagnostics
Added basic support for multiline/tabular diagnostics Reviewed-by: jjg
This commit is contained in:
parent
6c04fd835e
commit
454f269528
@ -27,13 +27,13 @@ package com.sun.tools.javac.util;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
import java.util.ResourceBundle;
|
|
||||||
|
|
||||||
import com.sun.tools.javac.api.DiagnosticFormatter;
|
import com.sun.tools.javac.api.DiagnosticFormatter;
|
||||||
import com.sun.tools.javac.api.Formattable;
|
import com.sun.tools.javac.api.Formattable;
|
||||||
import com.sun.tools.javac.api.DiagnosticFormatter.PositionKind;
|
import com.sun.tools.javac.api.DiagnosticFormatter.PositionKind;
|
||||||
import com.sun.tools.javac.file.JavacFileManager;
|
import com.sun.tools.javac.file.JavacFileManager;
|
||||||
import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticType.*;
|
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
|
* 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) {
|
public String formatMessage(JCDiagnostic d, Locale l) {
|
||||||
//this code should rely on the locale settings but it's not! See RFE 6443132
|
//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);
|
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) {
|
public String formatKind(JCDiagnostic d, Locale l) {
|
||||||
@ -165,6 +170,23 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
|
|||||||
return sbuf.toString();
|
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.
|
/** Format the faulty source code line and point to the error.
|
||||||
* @param d The diagnostic for which the error line should be printed
|
* @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) {
|
public boolean displaySource(JCDiagnostic d) {
|
||||||
return showSource && d.getType() != FRAGMENT;
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,6 +67,12 @@ public abstract class AbstractLog {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return the underlying diagnostic source
|
||||||
|
*/
|
||||||
|
public DiagnosticSource currentSource() {
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
/** Report an error, unless another error was already reported at same
|
/** Report an error, unless another error was already reported at same
|
||||||
* source position.
|
* source position.
|
||||||
* @param key The key for the localized error message.
|
* @param key The key for the localized error message.
|
||||||
|
@ -289,7 +289,7 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
|
|||||||
this.source = source;
|
this.source = source;
|
||||||
this.position = pos;
|
this.position = pos;
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.args = args;
|
this.args = args;
|
||||||
|
|
||||||
int n = (pos == null ? Position.NOPOS : pos.getPreferredPosition());
|
int n = (pos == null ? Position.NOPOS : pos.getPreferredPosition());
|
||||||
if (n == Position.NOPOS || source == null)
|
if (n == Position.NOPOS || source == null)
|
||||||
@ -308,6 +308,18 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
|
|||||||
return type;
|
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.
|
* Check whether or not this diagnostic is required to be shown.
|
||||||
* @return true if 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) {
|
public String getMessage(Locale locale) {
|
||||||
// RFE 6406133: JCDiagnostic.getMessage ignores locale argument
|
|
||||||
return defaultFormatter.formatMessage(this, locale);
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,10 @@ public interface LayoutCharacters {
|
|||||||
*/
|
*/
|
||||||
final static int TabInc = 8;
|
final static int TabInc = 8;
|
||||||
|
|
||||||
|
/** Diagnostic standard indentation
|
||||||
|
*/
|
||||||
|
final static int DiagInc = 2;
|
||||||
|
|
||||||
/** Tabulator character.
|
/** Tabulator character.
|
||||||
*/
|
*/
|
||||||
final static byte TAB = 0x8;
|
final static byte TAB = 0x8;
|
||||||
|
@ -190,9 +190,9 @@ public class Log extends AbstractLog {
|
|||||||
getSource(name).setEndPosTable(table);
|
getSource(name).setEndPosTable(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return current source name.
|
/** Return current sourcefile.
|
||||||
*/
|
*/
|
||||||
public JavaFileObject currentSource() {
|
public JavaFileObject currentSourceFile() {
|
||||||
return source == null ? null : source.getFile();
|
return source == null ? null : source.getFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -395,7 +395,7 @@ public class Log extends AbstractLog {
|
|||||||
printLines(errWriter, "error: " + msg);
|
printLines(errWriter, "error: " + msg);
|
||||||
} else {
|
} else {
|
||||||
int line = source.getLineNumber(pos);
|
int line = source.getLineNumber(pos);
|
||||||
JavaFileObject file = currentSource();
|
JavaFileObject file = source.getFile();
|
||||||
if (file != null)
|
if (file != null)
|
||||||
printLines(errWriter,
|
printLines(errWriter,
|
||||||
JavacFileManager.getJavacFileName(file) + ":" +
|
JavacFileManager.getJavacFileName(file) + ":" +
|
||||||
@ -408,7 +408,7 @@ public class Log extends AbstractLog {
|
|||||||
/** report an error:
|
/** report an error:
|
||||||
*/
|
*/
|
||||||
public void rawError(int pos, String msg) {
|
public void rawError(int pos, String msg) {
|
||||||
if (nerrors < MaxErrors && shouldReport(currentSource(), pos)) {
|
if (nerrors < MaxErrors && shouldReport(currentSourceFile(), pos)) {
|
||||||
printRawError(pos, msg);
|
printRawError(pos, msg);
|
||||||
prompt();
|
prompt();
|
||||||
nerrors++;
|
nerrors++;
|
||||||
|
@ -118,7 +118,7 @@ public class MandatoryWarningHandler {
|
|||||||
* Report a mandatory warning.
|
* Report a mandatory warning.
|
||||||
*/
|
*/
|
||||||
public void report(DiagnosticPosition pos, String msg, Object... args) {
|
public void report(DiagnosticPosition pos, String msg, Object... args) {
|
||||||
JavaFileObject currentSource = log.currentSource();
|
JavaFileObject currentSource = log.currentSourceFile();
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
if (sourcesWithReportedWarnings == null)
|
if (sourcesWithReportedWarnings == null)
|
||||||
|
@ -84,6 +84,20 @@ public class RawDiagnosticFormatter extends AbstractDiagnosticFormatter {
|
|||||||
return s;
|
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
|
@Override
|
||||||
protected String localize(Locale l, String s, Object... args) {
|
protected String localize(Locale l, String s, Object... args) {
|
||||||
StringBuffer buf = new StringBuffer();
|
StringBuffer buf = new StringBuffer();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user