提交 8689e7bc 编写于 作者: M mcimadamore

6731573: diagnostic output should optionally include source line

Summary: Added an -XD option to optionally prints out source lines in error messages
Reviewed-by: jjg
上级 1599b20b
......@@ -33,6 +33,7 @@ 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.*;
/**
* This abstract class provides a basic implementation of the functionalities that should be provided
......@@ -52,13 +53,21 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
* JavacMessages object used by this formatter for i18n
*/
protected JavacMessages messages;
protected boolean showSource;
/**
* Initialize an AbstractDiagnosticFormatter by setting its JavacMessages object
* @param messages
*/
protected AbstractDiagnosticFormatter(JavacMessages messages) {
protected AbstractDiagnosticFormatter(JavacMessages messages, Options options, boolean showSource) {
this.messages = messages;
this.showSource = options.get("showSource") == null ? showSource :
options.get("showSource").equals("true");
}
protected AbstractDiagnosticFormatter(JavacMessages messages, boolean showSource) {
this.messages = messages;
this.showSource = showSource;
}
public String formatMessage(JCDiagnostic d, Locale l) {
......@@ -156,6 +165,27 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
return sbuf.toString();
}
/** Format the faulty source code line and point to the error.
* @param d The diagnostic for which the error line should be printed
*/
protected String formatSourceLine(JCDiagnostic d) {
StringBuilder buf = new StringBuilder();
DiagnosticSource source = d.getDiagnosticSource();
int pos = d.getIntPosition();
if (d.getIntPosition() != Position.NOPOS) {
String line = (source == null ? null : source.getLine(pos));
if (line == null)
return "";
buf.append(line+"\n");
int col = source.getColumnNumber(pos, false);
for (int i = 0; i < col - 1; i++) {
buf.append((line.charAt(i) == '\t') ? "\t" : " ");
}
buf.append("^");
}
return buf.toString();
}
/**
* Converts a String into a locale-dependent representation accordingly to a given locale
*
......@@ -167,4 +197,8 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
protected String localize(Locale l, String key, Object... args) {
return messages.getLocalizedString(l, key, args);
}
public boolean displaySource(JCDiagnostic d) {
return showSource && d.getType() != FRAGMENT;
}
}
......@@ -62,7 +62,8 @@ public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter {
* @param msgs JavacMessages object used for i18n
*/
BasicDiagnosticFormatter(Options opts, JavacMessages msgs) {
this(msgs); //common init
super(msgs, opts, true);
initAvailableFormats();
String fmt = opts.get("diags");
if (fmt != null) {
String[] formats = fmt.split("\\|");
......@@ -83,7 +84,11 @@ public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter {
* @param msgs JavacMessages object used for i18n
*/
public BasicDiagnosticFormatter(JavacMessages msgs) {
super(msgs);
super(msgs, true);
initAvailableFormats();
}
public void initAvailableFormats() {
availableFormats = new HashMap<BasicFormatKind, String>();
availableFormats.put(DEFAULT_POS_FORMAT, "%f:%l:%_%t%m");
availableFormats.put(DEFAULT_NO_POS_FORMAT, "%p%m");
......@@ -104,6 +109,9 @@ public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter {
}
buf.append(meta ? formatMeta(c, d, l) : String.valueOf(c));
}
if (displaySource(d)) {
buf.append("\n" + formatSourceLine(d));
}
return buf.toString();
}
......@@ -167,10 +175,6 @@ public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter {
return format;
}
public boolean displaySource(JCDiagnostic d) {
return true;
}
/**
* This enum contains all the kinds of formatting patterns supported
* by a basic diagnostic formatter.
......
......@@ -120,7 +120,7 @@ public class Log extends AbstractLog {
boolean rawDiagnostics = options.get("rawDiagnostics") != null;
messages = JavacMessages.instance(context);
this.diagFormatter = rawDiagnostics ? new RawDiagnosticFormatter(messages) :
this.diagFormatter = rawDiagnostics ? new RawDiagnosticFormatter(options) :
new BasicDiagnosticFormatter(options, messages);
@SuppressWarnings("unchecked") // FIXME
DiagnosticListener<? super JavaFileObject> diagListener =
......@@ -340,14 +340,6 @@ public class Log extends AbstractLog {
PrintWriter writer = getWriterForDiagnosticType(diag.getType());
printLines(writer, diagFormatter.format(diag, messages.getCurrentLocale()));
if (diagFormatter.displaySource(diag)) {
int pos = diag.getIntPosition();
if (pos != Position.NOPOS) {
JavaFileObject prev = useSource(diag.getSource());
printErrLine(pos, writer);
useSource(prev);
}
}
if (promptOnError) {
switch (diag.getType()) {
......
......@@ -41,8 +41,8 @@ public class RawDiagnosticFormatter extends AbstractDiagnosticFormatter {
* Create a formatter based on the supplied options.
* @param msgs
*/
public RawDiagnosticFormatter(JavacMessages msgs) {
super(null);
public RawDiagnosticFormatter(Options opts) {
super(null, opts, false);
}
//provide common default formats
......@@ -61,6 +61,8 @@ public class RawDiagnosticFormatter extends AbstractDiagnosticFormatter {
buf.append('-');
buf.append(' ');
buf.append(formatMessage(d, null));
if (displaySource(d))
buf.append("\n" + formatSourceLine(d));
return buf.toString();
}
catch (Exception e) {
......@@ -94,8 +96,4 @@ public class RawDiagnosticFormatter extends AbstractDiagnosticFormatter {
}
return buf.toString();
}
public boolean displaySource(JCDiagnostic d) {
return false;
}
}
class A {
boolean b;
boolean b;
}
\ No newline at end of file
/*
* Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 6731573
* @summary diagnostic output should optionally include source line
* @author Maurizio Cimadamore
* @library ../lib
*/
import java.io.*;
import java.util.*;
import javax.tools.*;
public class T6731573 extends ToolTester {
enum DiagnosticType {
BASIC(null) {
boolean shouldDisplaySource(SourceLine sourceLine) {
return sourceLine != SourceLine.DISABLED;
}
},
RAW("-XDrawDiagnostics") {
boolean shouldDisplaySource(SourceLine sourceLine) {
return sourceLine == SourceLine.ENABLED;
}
};
String optValue;
DiagnosticType(String optValue) {
this.optValue = optValue;
}
abstract boolean shouldDisplaySource(SourceLine sourceLine);
}
enum SourceLine {
STANDARD(null),
ENABLED("-XDshowSource=true"),
DISABLED("-XDshowSource=false");
String optValue;
SourceLine(String optValue) {
this.optValue = optValue;
}
}
void checkErrorLine(String output, boolean expected, List<String> options) {
System.err.println("\noptions = "+options);
System.err.println(output);
boolean errLinePresent = output.contains("^");
if (errLinePresent != expected) {
throw new AssertionError("Error in diagnostic: error line" +
(expected ? "" : " not") + " expected but" +
(errLinePresent ? "" : " not") + " found");
}
}
void exec(DiagnosticType diagType, SourceLine sourceLine) {
final Iterable<? extends JavaFileObject> compilationUnits =
fm.getJavaFileObjects(new File(test_src, "Erroneous.java"));
StringWriter pw = new StringWriter();
ArrayList<String> options = new ArrayList<String>();
if (diagType.optValue != null)
options.add(diagType.optValue);
if (sourceLine.optValue != null)
options.add(sourceLine.optValue);
task = tool.getTask(pw, fm, null, options, null, compilationUnits);
task.call();
checkErrorLine(pw.toString(),
diagType.shouldDisplaySource(sourceLine),
options);
}
void test() {
for (DiagnosticType dt : DiagnosticType.values()) {
for (SourceLine sl : SourceLine.values()) {
exec(dt, sl);
}
}
}
public static void main(String... args) throws Exception {
new T6731573().test();
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册