6731573: diagnostic output should optionally include source line

Thu, 09 Oct 2008 16:19:13 +0100

author
mcimadamore
date
Thu, 09 Oct 2008 16:19:13 +0100
changeset 137
e4eaddca54b7
parent 136
8eafba4f61be
child 138
d766e40e49d6

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

src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/util/Log.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java file | annotate | diff | comparison | revisions
test/tools/javac/api/6731573/Erroneous.java file | annotate | diff | comparison | revisions
test/tools/javac/api/6731573/T6731573.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java	Thu Oct 09 16:07:38 2008 +0100
     1.2 +++ b/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java	Thu Oct 09 16:19:13 2008 +0100
     1.3 @@ -33,6 +33,7 @@
     1.4  import com.sun.tools.javac.api.Formattable;
     1.5  import com.sun.tools.javac.api.DiagnosticFormatter.PositionKind;
     1.6  import com.sun.tools.javac.file.JavacFileManager;
     1.7 +import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticType.*;
     1.8  
     1.9  /**
    1.10   * This abstract class provides a basic implementation of the functionalities that should be provided
    1.11 @@ -52,13 +53,21 @@
    1.12       * JavacMessages object used by this formatter for i18n
    1.13       */
    1.14      protected JavacMessages messages;
    1.15 +    protected boolean showSource;
    1.16  
    1.17      /**
    1.18       * Initialize an AbstractDiagnosticFormatter by setting its JavacMessages object
    1.19       * @param messages
    1.20       */
    1.21 -    protected AbstractDiagnosticFormatter(JavacMessages messages) {
    1.22 +    protected AbstractDiagnosticFormatter(JavacMessages messages, Options options, boolean showSource) {
    1.23          this.messages = messages;
    1.24 +        this.showSource = options.get("showSource") == null ? showSource :
    1.25 +                          options.get("showSource").equals("true");
    1.26 +    }
    1.27 +
    1.28 +    protected AbstractDiagnosticFormatter(JavacMessages messages, boolean showSource) {
    1.29 +        this.messages = messages;
    1.30 +        this.showSource = showSource;
    1.31      }
    1.32  
    1.33      public String formatMessage(JCDiagnostic d, Locale l) {
    1.34 @@ -156,6 +165,27 @@
    1.35          return sbuf.toString();
    1.36      }
    1.37  
    1.38 +    /** Format the faulty source code line and point to the error.
    1.39 +     *  @param d The diagnostic for which the error line should be printed
    1.40 +     */
    1.41 +    protected String formatSourceLine(JCDiagnostic d) {
    1.42 +        StringBuilder buf = new StringBuilder();
    1.43 +        DiagnosticSource source = d.getDiagnosticSource();
    1.44 +        int pos = d.getIntPosition();
    1.45 +        if (d.getIntPosition() != Position.NOPOS) {
    1.46 +            String line = (source == null ? null : source.getLine(pos));
    1.47 +            if (line == null)
    1.48 +                return "";
    1.49 +            buf.append(line+"\n");
    1.50 +            int col = source.getColumnNumber(pos, false);
    1.51 +            for (int i = 0; i < col - 1; i++)  {
    1.52 +                buf.append((line.charAt(i) == '\t') ? "\t" : " ");
    1.53 +            }
    1.54 +            buf.append("^");
    1.55 +         }
    1.56 +         return buf.toString();
    1.57 +    }
    1.58 +
    1.59      /**
    1.60       * Converts a String into a locale-dependent representation accordingly to a given locale
    1.61       *
    1.62 @@ -167,4 +197,8 @@
    1.63      protected String localize(Locale l, String key, Object... args) {
    1.64          return messages.getLocalizedString(l, key, args);
    1.65      }
    1.66 +
    1.67 +    public boolean displaySource(JCDiagnostic d) {
    1.68 +        return showSource && d.getType() != FRAGMENT;
    1.69 +    }
    1.70  }
     2.1 --- a/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java	Thu Oct 09 16:07:38 2008 +0100
     2.2 +++ b/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java	Thu Oct 09 16:19:13 2008 +0100
     2.3 @@ -62,7 +62,8 @@
     2.4       * @param msgs JavacMessages object used for i18n
     2.5       */
     2.6      BasicDiagnosticFormatter(Options opts, JavacMessages msgs) {
     2.7 -        this(msgs); //common init
     2.8 +        super(msgs, opts, true);
     2.9 +        initAvailableFormats();
    2.10          String fmt = opts.get("diags");
    2.11          if (fmt != null) {
    2.12              String[] formats = fmt.split("\\|");
    2.13 @@ -83,7 +84,11 @@
    2.14       * @param msgs JavacMessages object used for i18n
    2.15       */
    2.16      public BasicDiagnosticFormatter(JavacMessages msgs) {
    2.17 -        super(msgs);
    2.18 +        super(msgs, true);
    2.19 +        initAvailableFormats();
    2.20 +    }
    2.21 +
    2.22 +    public void initAvailableFormats() {
    2.23          availableFormats = new HashMap<BasicFormatKind, String>();
    2.24          availableFormats.put(DEFAULT_POS_FORMAT, "%f:%l:%_%t%m");
    2.25          availableFormats.put(DEFAULT_NO_POS_FORMAT, "%p%m");
    2.26 @@ -104,6 +109,9 @@
    2.27              }
    2.28              buf.append(meta ? formatMeta(c, d, l) : String.valueOf(c));
    2.29          }
    2.30 +        if (displaySource(d)) {
    2.31 +            buf.append("\n" + formatSourceLine(d));
    2.32 +        }
    2.33          return buf.toString();
    2.34      }
    2.35  
    2.36 @@ -167,10 +175,6 @@
    2.37          return format;
    2.38      }
    2.39  
    2.40 -    public boolean displaySource(JCDiagnostic d) {
    2.41 -        return true;
    2.42 -    }
    2.43 -
    2.44      /**
    2.45       * This enum contains all the kinds of formatting patterns supported
    2.46       * by a basic diagnostic formatter.
     3.1 --- a/src/share/classes/com/sun/tools/javac/util/Log.java	Thu Oct 09 16:07:38 2008 +0100
     3.2 +++ b/src/share/classes/com/sun/tools/javac/util/Log.java	Thu Oct 09 16:19:13 2008 +0100
     3.3 @@ -120,7 +120,7 @@
     3.4  
     3.5          boolean rawDiagnostics = options.get("rawDiagnostics") != null;
     3.6          messages = JavacMessages.instance(context);
     3.7 -        this.diagFormatter = rawDiagnostics ? new RawDiagnosticFormatter(messages) :
     3.8 +        this.diagFormatter = rawDiagnostics ? new RawDiagnosticFormatter(options) :
     3.9                                                new BasicDiagnosticFormatter(options, messages);
    3.10          @SuppressWarnings("unchecked") // FIXME
    3.11          DiagnosticListener<? super JavaFileObject> diagListener =
    3.12 @@ -340,14 +340,6 @@
    3.13          PrintWriter writer = getWriterForDiagnosticType(diag.getType());
    3.14  
    3.15          printLines(writer, diagFormatter.format(diag, messages.getCurrentLocale()));
    3.16 -        if (diagFormatter.displaySource(diag)) {
    3.17 -            int pos = diag.getIntPosition();
    3.18 -            if (pos != Position.NOPOS) {
    3.19 -                JavaFileObject prev = useSource(diag.getSource());
    3.20 -                printErrLine(pos, writer);
    3.21 -                useSource(prev);
    3.22 -            }
    3.23 -        }
    3.24  
    3.25          if (promptOnError) {
    3.26              switch (diag.getType()) {
     4.1 --- a/src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java	Thu Oct 09 16:07:38 2008 +0100
     4.2 +++ b/src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java	Thu Oct 09 16:19:13 2008 +0100
     4.3 @@ -41,8 +41,8 @@
     4.4       * Create a formatter based on the supplied options.
     4.5       * @param msgs
     4.6       */
     4.7 -    public RawDiagnosticFormatter(JavacMessages msgs) {
     4.8 -        super(null);
     4.9 +    public RawDiagnosticFormatter(Options opts) {
    4.10 +        super(null, opts, false);
    4.11      }
    4.12  
    4.13      //provide common default formats
    4.14 @@ -61,6 +61,8 @@
    4.15                  buf.append('-');
    4.16              buf.append(' ');
    4.17              buf.append(formatMessage(d, null));
    4.18 +            if (displaySource(d))
    4.19 +                buf.append("\n" + formatSourceLine(d));
    4.20              return buf.toString();
    4.21          }
    4.22          catch (Exception e) {
    4.23 @@ -94,8 +96,4 @@
    4.24          }
    4.25          return buf.toString();
    4.26      }
    4.27 -
    4.28 -    public boolean displaySource(JCDiagnostic d) {
    4.29 -        return false;
    4.30 -    }
    4.31  }
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/test/tools/javac/api/6731573/Erroneous.java	Thu Oct 09 16:19:13 2008 +0100
     5.3 @@ -0,0 +1,4 @@
     5.4 +class A {
     5.5 +    boolean b;
     5.6 +    boolean b;
     5.7 +}
     5.8 \ No newline at end of file
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/test/tools/javac/api/6731573/T6731573.java	Thu Oct 09 16:19:13 2008 +0100
     6.3 @@ -0,0 +1,109 @@
     6.4 +/*
     6.5 + * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
     6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     6.7 + *
     6.8 + * This code is free software; you can redistribute it and/or modify it
     6.9 + * under the terms of the GNU General Public License version 2 only, as
    6.10 + * published by the Free Software Foundation.
    6.11 + *
    6.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    6.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    6.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    6.15 + * version 2 for more details (a copy is included in the LICENSE file that
    6.16 + * accompanied this code).
    6.17 + *
    6.18 + * You should have received a copy of the GNU General Public License version
    6.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    6.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    6.21 + *
    6.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    6.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
    6.24 + * have any questions.
    6.25 + */
    6.26 +
    6.27 +/*
    6.28 + * @test
    6.29 + * @bug     6731573
    6.30 + * @summary diagnostic output should optionally include source line
    6.31 + * @author  Maurizio Cimadamore
    6.32 + * @library ../lib
    6.33 + */
    6.34 +
    6.35 +import java.io.*;
    6.36 +import java.util.*;
    6.37 +import javax.tools.*;
    6.38 +
    6.39 +public class T6731573 extends ToolTester {
    6.40 +
    6.41 +    enum DiagnosticType {
    6.42 +        BASIC(null) {
    6.43 +            boolean shouldDisplaySource(SourceLine sourceLine) {
    6.44 +                return sourceLine != SourceLine.DISABLED;
    6.45 +            }
    6.46 +        },
    6.47 +        RAW("-XDrawDiagnostics") {
    6.48 +            boolean shouldDisplaySource(SourceLine sourceLine) {
    6.49 +                return sourceLine == SourceLine.ENABLED;
    6.50 +            }
    6.51 +        };
    6.52 +
    6.53 +        String optValue;
    6.54 +
    6.55 +        DiagnosticType(String optValue) {
    6.56 +            this.optValue = optValue;
    6.57 +        }
    6.58 +
    6.59 +        abstract boolean shouldDisplaySource(SourceLine sourceLine);
    6.60 +    }
    6.61 +
    6.62 +    enum SourceLine {
    6.63 +        STANDARD(null),
    6.64 +        ENABLED("-XDshowSource=true"),
    6.65 +        DISABLED("-XDshowSource=false");
    6.66 +
    6.67 +        String optValue;
    6.68 +
    6.69 +        SourceLine(String optValue) {
    6.70 +            this.optValue = optValue;
    6.71 +        }
    6.72 +    }
    6.73 +
    6.74 +    void checkErrorLine(String output, boolean expected, List<String> options) {
    6.75 +        System.err.println("\noptions = "+options);
    6.76 +        System.err.println(output);
    6.77 +        boolean errLinePresent = output.contains("^");
    6.78 +        if (errLinePresent != expected) {
    6.79 +            throw new AssertionError("Error in diagnostic: error line" +
    6.80 +                    (expected ? "" : " not") + " expected but" +
    6.81 +                    (errLinePresent ? "" : " not") + " found");
    6.82 +        }
    6.83 +    }
    6.84 +
    6.85 +    void exec(DiagnosticType diagType, SourceLine sourceLine) {
    6.86 +        final Iterable<? extends JavaFileObject> compilationUnits =
    6.87 +            fm.getJavaFileObjects(new File(test_src, "Erroneous.java"));
    6.88 +        StringWriter pw = new StringWriter();
    6.89 +        ArrayList<String> options = new ArrayList<String>();
    6.90 +        if (diagType.optValue != null)
    6.91 +            options.add(diagType.optValue);
    6.92 +        if (sourceLine.optValue != null)
    6.93 +            options.add(sourceLine.optValue);
    6.94 +        task = tool.getTask(pw, fm, null, options, null, compilationUnits);
    6.95 +        task.call();
    6.96 +        checkErrorLine(pw.toString(),
    6.97 +                diagType.shouldDisplaySource(sourceLine),
    6.98 +                options);
    6.99 +    }
   6.100 +
   6.101 +    void test() {
   6.102 +        for (DiagnosticType dt : DiagnosticType.values()) {
   6.103 +            for (SourceLine sl : SourceLine.values()) {
   6.104 +                exec(dt, sl);
   6.105 +            }
   6.106 +        }
   6.107 +    }
   6.108 +
   6.109 +    public static void main(String... args) throws Exception {
   6.110 +        new T6731573().test();
   6.111 +    }
   6.112 +}
   6.113 \ No newline at end of file

mercurial