6720185: DiagnosticFormatter refactoring

Mon, 28 Jul 2008 10:22:10 +0100

author
mcimadamore
date
Mon, 28 Jul 2008 10:22:10 +0100
changeset 83
37470f5ea179
parent 82
dc4744d13247
child 84
0a5f04fb7282
child 86
3437676858e3

6720185: DiagnosticFormatter refactoring
Summary: Brand new hierarchy of diagnostic formatters for achieving better reusability
Reviewed-by: jjg

src/share/classes/com/sun/tools/javac/api/DiagnosticFormatter.java file | annotate | diff | comparison | revisions
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/DiagnosticFormatter.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/util/JCDiagnostic.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
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/classes/com/sun/tools/javac/api/DiagnosticFormatter.java	Mon Jul 28 10:22:10 2008 +0100
     1.3 @@ -0,0 +1,117 @@
     1.4 +/*
     1.5 + * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.  Sun designates this
    1.11 + * particular file as subject to the "Classpath" exception as provided
    1.12 + * by Sun in the LICENSE file that accompanied this code.
    1.13 + *
    1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.17 + * version 2 for more details (a copy is included in the LICENSE file that
    1.18 + * accompanied this code).
    1.19 + *
    1.20 + * You should have received a copy of the GNU General Public License version
    1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.23 + *
    1.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    1.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
    1.26 + * have any questions.
    1.27 + */
    1.28 +package com.sun.tools.javac.api;
    1.29 +
    1.30 +import java.util.Locale;
    1.31 +import javax.tools.Diagnostic;
    1.32 +
    1.33 +/**
    1.34 + * Provides simple functionalities for javac diagnostic formatting
    1.35 + * @param <D> type of diagnostic handled by this formatter
    1.36 + */
    1.37 +public interface DiagnosticFormatter<D extends Diagnostic<?>> {
    1.38 +
    1.39 +    /**
    1.40 +     * Whether the source code output for this diagnostic is to be displayed
    1.41 +     *
    1.42 +     * @param diag diagnostic to be formatted
    1.43 +     * @return true if the source line this diagnostic refers to is to be displayed
    1.44 +     */
    1.45 +    boolean displaySource(D diag);
    1.46 +
    1.47 +    /**
    1.48 +     * Format the contents of a diagnostics
    1.49 +     *
    1.50 +     * @param diag the diagnostic to be formatted
    1.51 +     * @param l locale object to be used for i18n
    1.52 +     * @return a string representing the diagnostic
    1.53 +     */
    1.54 +    public String format(D diag, Locale l);
    1.55 +
    1.56 +    /**
    1.57 +     * Controls the way in which a diagnostic message is displayed.
    1.58 +     *
    1.59 +     * @param diag diagnostic to be formatted
    1.60 +     * @param l locale object to be used for i18n
    1.61 +     * @return string representation of the diagnostic message
    1.62 +     */
    1.63 +    public String formatMessage(D diag,Locale l);
    1.64 +
    1.65 +    /**
    1.66 +     * Controls the way in which a diagnostic kind is displayed.
    1.67 +     *
    1.68 +     * @param diag diagnostic to be formatted
    1.69 +     * @param l locale object to be used for i18n
    1.70 +     * @return string representation of the diagnostic prefix
    1.71 +     */
    1.72 +    public String formatKind(D diag, Locale l);
    1.73 +
    1.74 +    /**
    1.75 +     * Controls the way in which a diagnostic source is displayed.
    1.76 +     *
    1.77 +     * @param diag diagnostic to be formatted
    1.78 +     * @param l locale object to be used for i18n
    1.79 +     * @return string representation of the diagnostic source
    1.80 +     */
    1.81 +    public String formatSource(D diag, Locale l);
    1.82 +
    1.83 +    /**
    1.84 +     * Controls the way in which a diagnostic position is displayed.
    1.85 +     *
    1.86 +     * @param diag diagnostic to be formatted
    1.87 +     * @param pk enum constant representing the position kind
    1.88 +     * @param l locale object to be used for i18n
    1.89 +     * @return string representation of the diagnostic position
    1.90 +     */
    1.91 +    public String formatPosition(D diag, PositionKind pk, Locale l);
    1.92 +    //where
    1.93 +    /**
    1.94 +     * This enum defines a set of constants for all the kinds of position
    1.95 +     * that a diagnostic can be asked for. All positions are intended to be
    1.96 +     * relative to a given diagnostic source.
    1.97 +     */
    1.98 +    public enum PositionKind {
    1.99 +        /**
   1.100 +         * Start position
   1.101 +         */
   1.102 +        START,
   1.103 +        /**
   1.104 +         * End position
   1.105 +         */
   1.106 +        END,
   1.107 +        /**
   1.108 +         * Line number
   1.109 +         */
   1.110 +        LINE,
   1.111 +        /**
   1.112 +         * Column number
   1.113 +         */
   1.114 +        COLUMN,
   1.115 +        /**
   1.116 +         * Offset position
   1.117 +         */
   1.118 +        OFFSET
   1.119 +    }
   1.120 +}
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java	Mon Jul 28 10:22:10 2008 +0100
     2.3 @@ -0,0 +1,169 @@
     2.4 +/*
     2.5 + * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
     2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.7 + *
     2.8 + * This code is free software; you can redistribute it and/or modify it
     2.9 + * under the terms of the GNU General Public License version 2 only, as
    2.10 + * published by the Free Software Foundation.  Sun designates this
    2.11 + * particular file as subject to the "Classpath" exception as provided
    2.12 + * by Sun in the LICENSE file that accompanied this code.
    2.13 + *
    2.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    2.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    2.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    2.17 + * version 2 for more details (a copy is included in the LICENSE file that
    2.18 + * accompanied this code).
    2.19 + *
    2.20 + * You should have received a copy of the GNU General Public License version
    2.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    2.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    2.23 + *
    2.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    2.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
    2.26 + * have any questions.
    2.27 + */
    2.28 +package com.sun.tools.javac.util;
    2.29 +
    2.30 +import java.util.Collection;
    2.31 +import java.util.Locale;
    2.32 +import javax.tools.JavaFileObject;
    2.33 +
    2.34 +import com.sun.tools.javac.api.DiagnosticFormatter;
    2.35 +import com.sun.tools.javac.api.Formattable;
    2.36 +import com.sun.tools.javac.api.DiagnosticFormatter.PositionKind;
    2.37 +import com.sun.tools.javac.file.JavacFileManager;
    2.38 +
    2.39 +/**
    2.40 + * This abstract class provides a basic implementation of the functionalities that should be provided
    2.41 + * by any formatter used by javac. Among the main features provided by AbstractDiagnosticFormatter are:
    2.42 + *
    2.43 + * <ul>
    2.44 + *  <li> Provides a standard implementation of the visitor-like methods defined in the interface DiagnisticFormatter.
    2.45 + *  Those implementations are specifically targeting JCDiagnostic objects.
    2.46 + *  <li> Provides basic support for i18n and a method for executing all locale-dependent conversions
    2.47 + *  <li> Provides the formatting logic for rendering the arguments of a JCDiagnostic object.
    2.48 + * <ul>
    2.49 + *
    2.50 + */
    2.51 +public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter<JCDiagnostic> {
    2.52 +
    2.53 +    /**
    2.54 +     * Messages object used by this formatter for i18n
    2.55 +     */
    2.56 +    protected Messages messages;
    2.57 +
    2.58 +    /**
    2.59 +     * Initialize an AbstractDiagnosticFormatter by setting its Messages object
    2.60 +     * @param messages
    2.61 +     */
    2.62 +    protected AbstractDiagnosticFormatter(Messages messages) {
    2.63 +        this.messages = messages;
    2.64 +    }
    2.65 +
    2.66 +    public String formatMessage(JCDiagnostic d, Locale l) {
    2.67 +        //this code should rely on the locale settings but it's not! See RFE 6443132
    2.68 +        Collection<String> args = formatArguments(d, l);
    2.69 +        return localize(l, d.getCode(), args.toArray());
    2.70 +    }
    2.71 +
    2.72 +    public String formatKind(JCDiagnostic d, Locale l) {
    2.73 +        switch (d.getType()) {
    2.74 +            case FRAGMENT: return "";
    2.75 +            case NOTE:     return localize(l, "compiler.note.note");
    2.76 +            case WARNING:  return localize(l, "compiler.warn.warning");
    2.77 +            case ERROR:    return localize(l, "compiler.err.error");
    2.78 +            default:
    2.79 +                throw new AssertionError("Unknown diagnostic type: " + d.getType());
    2.80 +        }
    2.81 +    }
    2.82 +
    2.83 +    public String formatPosition(JCDiagnostic d, PositionKind pk,Locale l) {
    2.84 +        assert (d.getPosition() != Position.NOPOS);
    2.85 +        return String.valueOf(getPosition(d, pk));
    2.86 +    }
    2.87 +    //WHERE
    2.88 +    public long getPosition(JCDiagnostic d, PositionKind pk) {
    2.89 +        switch (pk) {
    2.90 +            case START: return d.getIntStartPosition();
    2.91 +            case END: return d.getIntEndPosition();
    2.92 +            case LINE: return d.getLineNumber();
    2.93 +            case COLUMN: return d.getColumnNumber();
    2.94 +            case OFFSET: return d.getIntPosition();
    2.95 +            default:
    2.96 +                throw new AssertionError("Unknown diagnostic position: " + pk);
    2.97 +        }
    2.98 +    }
    2.99 +
   2.100 +    public String formatSource(JCDiagnostic d,Locale l) {
   2.101 +        assert (d.getSource() != null);
   2.102 +        return d.getSource().getName();
   2.103 +    }
   2.104 +
   2.105 +    /**
   2.106 +     * Format the arguments of a given diagnostic.
   2.107 +     *
   2.108 +     * @param d diagnostic whose arguments are to be formatted
   2.109 +     * @param l locale object to be used for i18n
   2.110 +     * @return a Collection whose elements are the formatted arguments of the diagnostic
   2.111 +     */
   2.112 +    protected Collection<String> formatArguments(JCDiagnostic d, Locale l) {
   2.113 +        ListBuffer<String> buf = new ListBuffer<String>();
   2.114 +        for (Object o : d.getArgs()) {
   2.115 +           buf.append(formatArgument(d, o, l));
   2.116 +        }
   2.117 +        return buf.toList();
   2.118 +    }
   2.119 +
   2.120 +    /**
   2.121 +     * Format a single argument of a given diagnostic.
   2.122 +     *
   2.123 +     * @param d diagnostic whose argument is to be formatted
   2.124 +     * @param arg argument to be formatted
   2.125 +     * @param l locale object to be used for i18n
   2.126 +     * @return string representation of the diagnostic argument
   2.127 +     */
   2.128 +    protected String formatArgument(JCDiagnostic d, Object arg, Locale l) {
   2.129 +        if (arg instanceof JCDiagnostic)
   2.130 +            return format((JCDiagnostic)arg, l);
   2.131 +        else if (arg instanceof Iterable<?>) {
   2.132 +            return formatIterable(d, (Iterable<?>)arg, l);
   2.133 +        }
   2.134 +        else if (arg instanceof JavaFileObject)
   2.135 +            return JavacFileManager.getJavacBaseFileName((JavaFileObject)arg);
   2.136 +        else if (arg instanceof Formattable)
   2.137 +            return ((Formattable)arg).toString(Messages.getDefaultBundle());
   2.138 +        else
   2.139 +            return String.valueOf(arg);
   2.140 +    }
   2.141 +
   2.142 +    /**
   2.143 +     * Format an iterable argument of a given diagnostic.
   2.144 +     *
   2.145 +     * @param d diagnostic whose argument is to be formatted
   2.146 +     * @param it iterable argument to be formatted
   2.147 +     * @param l locale object to be used for i18n
   2.148 +     * @return string representation of the diagnostic iterable argument
   2.149 +     */
   2.150 +    protected String formatIterable(JCDiagnostic d, Iterable<?> it, Locale l) {
   2.151 +        StringBuilder sbuf = new StringBuilder();
   2.152 +        String sep = "";
   2.153 +        for (Object o : it) {
   2.154 +            sbuf.append(sep);
   2.155 +            sbuf.append(formatArgument(d, o, l));
   2.156 +            sep = ",";
   2.157 +        }
   2.158 +        return sbuf.toString();
   2.159 +    }
   2.160 +
   2.161 +    /**
   2.162 +     * Converts a String into a locale-dependent representation accordingly to a given locale
   2.163 +     *
   2.164 +     * @param l locale object to be used for i18n
   2.165 +     * @param key locale-independent key used for looking up in a resource file
   2.166 +     * @param args localization arguments
   2.167 +     * @return a locale-dependent string
   2.168 +     */
   2.169 +    protected String localize(Locale l, String key, Object... args) {
   2.170 +        return messages.getLocalizedString(key, args);
   2.171 +    }
   2.172 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java	Mon Jul 28 10:22:10 2008 +0100
     3.3 @@ -0,0 +1,190 @@
     3.4 +/*
     3.5 + * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
     3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.7 + *
     3.8 + * This code is free software; you can redistribute it and/or modify it
     3.9 + * under the terms of the GNU General Public License version 2 only, as
    3.10 + * published by the Free Software Foundation.  Sun designates this
    3.11 + * particular file as subject to the "Classpath" exception as provided
    3.12 + * by Sun in the LICENSE file that accompanied this code.
    3.13 + *
    3.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    3.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    3.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    3.17 + * version 2 for more details (a copy is included in the LICENSE file that
    3.18 + * accompanied this code).
    3.19 + *
    3.20 + * You should have received a copy of the GNU General Public License version
    3.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    3.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    3.23 + *
    3.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    3.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
    3.26 + * have any questions.
    3.27 + */
    3.28 +
    3.29 +package com.sun.tools.javac.util;
    3.30 +
    3.31 +import java.util.HashMap;
    3.32 +import java.util.Locale;
    3.33 +import java.util.Map;
    3.34 +import javax.tools.JavaFileObject;
    3.35 +
    3.36 +import static com.sun.tools.javac.util.BasicDiagnosticFormatter.BasicFormatKind.*;
    3.37 +import static com.sun.tools.javac.api.DiagnosticFormatter.PositionKind.*;
    3.38 +
    3.39 +/**
    3.40 + * A basic formatter for diagnostic messages.
    3.41 + * The basic formatter will format a diagnostic according to one of three format patterns, depending on whether
    3.42 + * or not the source name and position are set. The formatter supports a printf-like string for patterns
    3.43 + * with the following special characters:
    3.44 + * <ul>
    3.45 + * <li>%b: the base of the source name
    3.46 + * <li>%f: the source name (full absolute path)
    3.47 + * <li>%l: the line number of the diagnostic, derived from the character offset
    3.48 + * <li>%c: the column number of the diagnostic, derived from the character offset
    3.49 + * <li>%o: the character offset of the diagnostic if set
    3.50 + * <li>%p: the prefix for the diagnostic, derived from the diagnostic type
    3.51 + * <li>%t: the prefix as it normally appears in standard diagnostics. In this case, no prefix is
    3.52 + *        shown if the type is ERROR and if a source name is set
    3.53 + * <li>%m: the text or the diagnostic, including any appropriate arguments
    3.54 + * <li>%_: space delimiter, useful for formatting purposes
    3.55 + * </ul>
    3.56 + */
    3.57 +public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter {
    3.58 +
    3.59 +    protected Map<BasicFormatKind, String> availableFormats;
    3.60 +
    3.61 +    /**
    3.62 +     * Create a basic formatter based on the supplied options.
    3.63 +     *
    3.64 +     * @param opts list of command-line options
    3.65 +     * @param msgs Messages object used for i18n
    3.66 +     */
    3.67 +    BasicDiagnosticFormatter(Options opts, Messages msgs) {
    3.68 +        this(msgs); //common init
    3.69 +        String fmt = opts.get("diags");
    3.70 +        if (fmt != null) {
    3.71 +            String[] formats = fmt.split("\\|");
    3.72 +            switch (formats.length) {
    3.73 +                case 3:
    3.74 +                    availableFormats.put(DEFAULT_CLASS_FORMAT, formats[2]);
    3.75 +                case 2:
    3.76 +                    availableFormats.put(DEFAULT_NO_POS_FORMAT, formats[1]);
    3.77 +                default:
    3.78 +                    availableFormats.put(DEFAULT_POS_FORMAT, formats[0]);
    3.79 +            }
    3.80 +        }
    3.81 +    }
    3.82 +
    3.83 +    /**
    3.84 +     * Create a standard basic formatter
    3.85 +     *
    3.86 +     * @param msgs Messages object used for i18n
    3.87 +     */
    3.88 +    public BasicDiagnosticFormatter(Messages msgs) {
    3.89 +        super(msgs);
    3.90 +        availableFormats = new HashMap<BasicFormatKind, String>();
    3.91 +        availableFormats.put(DEFAULT_POS_FORMAT, "%f:%l:%_%t%m");
    3.92 +        availableFormats.put(DEFAULT_NO_POS_FORMAT, "%p%m");
    3.93 +        availableFormats.put(DEFAULT_CLASS_FORMAT, "%f:%_%t%m");
    3.94 +    }
    3.95 +
    3.96 +    public String format(JCDiagnostic d, Locale l) {
    3.97 +        String format = selectFormat(d);
    3.98 +        StringBuilder buf = new StringBuilder();
    3.99 +        for (int i = 0; i < format.length(); i++) {
   3.100 +            char c = format.charAt(i);
   3.101 +            boolean meta = false;
   3.102 +            if (c == '%' && i < format.length() - 1) {
   3.103 +                meta = true;
   3.104 +                c = format.charAt(++i);
   3.105 +            }
   3.106 +            buf.append(meta ? formatMeta(c, d, l) : String.valueOf(c));
   3.107 +        }
   3.108 +        return buf.toString();
   3.109 +    }
   3.110 +
   3.111 +    protected String formatMeta(char c, JCDiagnostic d, Locale l) {
   3.112 +        switch (c) {
   3.113 +            case 'b':
   3.114 +                return formatSource(d, l);
   3.115 +            case 'e':
   3.116 +                return formatPosition(d, END, l);
   3.117 +            case 'f':
   3.118 +                return formatSource(d, l);
   3.119 +            case 'l':
   3.120 +                return formatPosition(d, LINE, l);
   3.121 +            case 'c':
   3.122 +                return formatPosition(d, COLUMN, l);
   3.123 +            case 'o':
   3.124 +                return formatPosition(d, OFFSET, l);
   3.125 +            case 'p':
   3.126 +                return formatKind(d, l);
   3.127 +            case 's':
   3.128 +                return formatPosition(d, START, l);
   3.129 +            case 't': {
   3.130 +                boolean usePrefix;
   3.131 +                switch (d.getType()) {
   3.132 +                case FRAGMENT:
   3.133 +                    usePrefix = false;
   3.134 +                    break;
   3.135 +                case ERROR:
   3.136 +                    usePrefix = (d.getIntPosition() == Position.NOPOS);
   3.137 +                    break;
   3.138 +                default:
   3.139 +                    usePrefix = true;
   3.140 +                }
   3.141 +                if (usePrefix)
   3.142 +                    return formatKind(d, l);
   3.143 +                else
   3.144 +                    return "";
   3.145 +            }
   3.146 +            case 'm':
   3.147 +                return formatMessage(d, l);
   3.148 +            case '_':
   3.149 +                return " ";
   3.150 +            case '%':
   3.151 +                return "%";
   3.152 +            default:
   3.153 +                return String.valueOf(c);
   3.154 +        }
   3.155 +    }
   3.156 +
   3.157 +    private String selectFormat(JCDiagnostic d) {
   3.158 +        DiagnosticSource source = d.getDiagnosticSource();
   3.159 +        String format = availableFormats.get(DEFAULT_NO_POS_FORMAT);
   3.160 +        if (source != null) {
   3.161 +            if (d.getIntPosition() != Position.NOPOS) {
   3.162 +                format = availableFormats.get(DEFAULT_POS_FORMAT);
   3.163 +            } else if (source.getFile() != null &&
   3.164 +                       source.getFile().getKind() == JavaFileObject.Kind.CLASS) {
   3.165 +                format = availableFormats.get(DEFAULT_CLASS_FORMAT);
   3.166 +            }
   3.167 +        }
   3.168 +        return format;
   3.169 +    }
   3.170 +
   3.171 +    public boolean displaySource(JCDiagnostic d) {
   3.172 +        return true;
   3.173 +    }
   3.174 +
   3.175 +    /**
   3.176 +     * This enum contains all the kinds of formatting patterns supported
   3.177 +     * by a basic diagnostic formatter.
   3.178 +     */
   3.179 +    public enum BasicFormatKind {
   3.180 +        /**
   3.181 +        * A format string to be used for diagnostics with a given position.
   3.182 +        */
   3.183 +        DEFAULT_POS_FORMAT,
   3.184 +        /**
   3.185 +        * A format string to be used for diagnostics without a given position.
   3.186 +        */
   3.187 +        DEFAULT_NO_POS_FORMAT,
   3.188 +        /**
   3.189 +        * A format string to be used for diagnostics regarding classfiles
   3.190 +        */
   3.191 +        DEFAULT_CLASS_FORMAT;
   3.192 +    }
   3.193 +}
     4.1 --- a/src/share/classes/com/sun/tools/javac/util/DiagnosticFormatter.java	Fri Jul 25 12:22:09 2008 +0100
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,267 +0,0 @@
     4.4 -/*
     4.5 - * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
     4.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.7 - *
     4.8 - * This code is free software; you can redistribute it and/or modify it
     4.9 - * under the terms of the GNU General Public License version 2 only, as
    4.10 - * published by the Free Software Foundation.  Sun designates this
    4.11 - * particular file as subject to the "Classpath" exception as provided
    4.12 - * by Sun in the LICENSE file that accompanied this code.
    4.13 - *
    4.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
    4.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    4.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    4.17 - * version 2 for more details (a copy is included in the LICENSE file that
    4.18 - * accompanied this code).
    4.19 - *
    4.20 - * You should have received a copy of the GNU General Public License version
    4.21 - * 2 along with this work; if not, write to the Free Software Foundation,
    4.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    4.23 - *
    4.24 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    4.25 - * CA 95054 USA or visit www.sun.com if you need additional information or
    4.26 - * have any questions.
    4.27 - */
    4.28 -
    4.29 -package com.sun.tools.javac.util;
    4.30 -
    4.31 -import java.util.Collection;
    4.32 -import javax.tools.JavaFileObject;
    4.33 -
    4.34 -import com.sun.tools.javac.file.JavacFileManager;
    4.35 -import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
    4.36 -
    4.37 -/**
    4.38 - * A formatter for diagnostic messages.
    4.39 - * The formatter will format a diagnostic according to one of two format strings, depending on whether
    4.40 - * or not the source name and position are set. The format is a printf-like string,
    4.41 - * with the following special characters:
    4.42 - * <ul>
    4.43 - * <li>%b: the base of the source name, or "-" if not set
    4.44 - * <li>%f: the source name, or "-" if not set
    4.45 - * <li>%l: the line number of the diagnostic, derived from the character offset if set, or "-" otherwise
    4.46 - * <li>%c: the column number of the diagnostic, derived from the character offset if set, or "-" otherwise
    4.47 - * <li>%o: the character offset of the diagnostic if set, or "-" otherwise
    4.48 - * <li>%p: the prefix for the diagnostic, derived from the diagnostic type
    4.49 - * <li>%t: the prefix as it normally appears in standard diagnostics. In this case, no prefix is
    4.50 - *        shown if the type is ERROR and if a source name is set
    4.51 - * <li>%m: the text or the diagnostic, including any appropriate arguments
    4.52 - * </ul>
    4.53 - */
    4.54 -public class DiagnosticFormatter {
    4.55 -    /**
    4.56 -     * A format string to be used for diagnostics with a given position.
    4.57 -     */
    4.58 -    protected String posFormat;
    4.59 -
    4.60 -    /**
    4.61 -     * A format string to be used for diagnostics regarding classfiles
    4.62 -     */
    4.63 -    protected String classFormat = DEFAULT_CLASS_FORMAT;
    4.64 -
    4.65 -    /**
    4.66 -     * A format string to be used for diagnostics without a given position.
    4.67 -     */
    4.68 -    protected String noPosFormat;
    4.69 -
    4.70 -    /**
    4.71 -     * A value to indicate whether to output the i18n key and args, instead of
    4.72 -     * the derived l10n message.
    4.73 -     */
    4.74 -    protected boolean raw;
    4.75 -
    4.76 -    /** The context key for the formatter. */
    4.77 -    protected static final Context.Key<DiagnosticFormatter> formatterKey =
    4.78 -        new Context.Key<DiagnosticFormatter>();
    4.79 -
    4.80 -    /** Get the DiagnosticFormatter instance for this context. */
    4.81 -    public static DiagnosticFormatter instance(Context context) {
    4.82 -        DiagnosticFormatter instance = context.get(formatterKey);
    4.83 -        if (instance == null)
    4.84 -            instance = new DiagnosticFormatter(context);
    4.85 -        return instance;
    4.86 -    }
    4.87 -
    4.88 -    /**
    4.89 -     * Create a formatter based on the supplied options.
    4.90 -     */
    4.91 -    protected DiagnosticFormatter(Context context) {
    4.92 -        Options options = Options.instance(context);
    4.93 -        raw = options.get("rawDiagnostics") != null;
    4.94 -        String fmt = options.get("diags");
    4.95 -        if (fmt != null) {
    4.96 -            int sep = fmt.indexOf('|');
    4.97 -            if (sep == -1)
    4.98 -                posFormat = noPosFormat = fmt;
    4.99 -            else {
   4.100 -                posFormat = fmt.substring(0, sep);
   4.101 -                noPosFormat = fmt.substring(sep + 1);
   4.102 -            }
   4.103 -        }
   4.104 -        else {
   4.105 -            posFormat = DEFAULT_POS_FORMAT;
   4.106 -            noPosFormat = DEFAULT_NO_POS_FORMAT;
   4.107 -        }
   4.108 -    }
   4.109 -
   4.110 -    public static final String DEFAULT_POS_FORMAT = "%f:%l: %t%m";
   4.111 -    public static final String DEFAULT_CLASS_FORMAT = "%f: %t%m";
   4.112 -    public static final String DEFAULT_NO_POS_FORMAT = "%p%m";
   4.113 -
   4.114 -    public DiagnosticFormatter() {
   4.115 -        posFormat = DEFAULT_POS_FORMAT;
   4.116 -        noPosFormat = DEFAULT_NO_POS_FORMAT;
   4.117 -        raw = false;
   4.118 -    }
   4.119 -
   4.120 -    public DiagnosticFormatter(String pos, String noPos) {
   4.121 -        posFormat = pos;
   4.122 -        noPosFormat = noPos;
   4.123 -        raw = false;
   4.124 -    }
   4.125 -
   4.126 -    String format(JCDiagnostic d) {
   4.127 -        return (raw ? format_raw(d) : format_std(d));
   4.128 -    }
   4.129 -
   4.130 -    private String format_raw(JCDiagnostic d) {
   4.131 -        DiagnosticSource source = d.getDiagnosticSource();
   4.132 -        int position = d.getIntPosition();
   4.133 -
   4.134 -        StringBuilder sb = new StringBuilder();
   4.135 -        if (position == Position.NOPOS)
   4.136 -            sb.append("-");
   4.137 -        else {
   4.138 -            sb.append(source.getName() + ":" + source.getLineNumber(position) + ":" + source.getColumnNumber(position) + ":");
   4.139 -        }
   4.140 -        sb.append(" ");
   4.141 -        sb.append(d.getCode());
   4.142 -        String sep = ": ";
   4.143 -        for (Object arg: d.getArgs()) {
   4.144 -            sb.append(sep);
   4.145 -            if (arg instanceof JCDiagnostic) {
   4.146 -                sb.append('(');
   4.147 -                sb.append(format_raw((JCDiagnostic) arg));
   4.148 -                sb.append(')');
   4.149 -            }
   4.150 -            else if (arg instanceof JavaFileObject)
   4.151 -                sb.append(JavacFileManager.getJavacBaseFileName((JavaFileObject) arg));
   4.152 -            else if (arg instanceof Collection<?>)
   4.153 -                sb.append(convert((Collection<?>)arg));
   4.154 -            else
   4.155 -                sb.append(arg);
   4.156 -            sep = ", ";
   4.157 -        }
   4.158 -        return sb.toString();
   4.159 -    }
   4.160 -
   4.161 -    static <T> List<T> convert(Collection<T> c) {
   4.162 -        if (c instanceof List<?>)
   4.163 -            return (List<T>)c;
   4.164 -        else {
   4.165 -            List<T> l = List.<T>nil();
   4.166 -            for (T t : c) {
   4.167 -                l = l.prepend(t);
   4.168 -            }
   4.169 -            return l.reverse();
   4.170 -        }
   4.171 -    }
   4.172 -
   4.173 -    private String format_std(JCDiagnostic d) {
   4.174 -        DiagnosticSource source = d.getDiagnosticSource();
   4.175 -        DiagnosticType type = d.getType();
   4.176 -        int position = d.getIntPosition();
   4.177 -
   4.178 -
   4.179 -        String format = noPosFormat;
   4.180 -        if (source != null) {
   4.181 -            if (position != Position.NOPOS) {
   4.182 -                format = posFormat;
   4.183 -            } else if (source.getFile() != null &&
   4.184 -                       source.getFile().getKind() == JavaFileObject.Kind.CLASS) {
   4.185 -                format = classFormat;
   4.186 -            }
   4.187 -        }
   4.188 -
   4.189 -        StringBuilder sb = new StringBuilder();
   4.190 -
   4.191 -        for (int i = 0; i < format.length(); i++) {
   4.192 -            char c = format.charAt(i);
   4.193 -            if (c == '%' && i < format.length() - 1) {
   4.194 -                c = format.charAt(++i);
   4.195 -                switch (c) {
   4.196 -                case 'b':
   4.197 -                    sb.append(source == null ? "-" : source.getName());
   4.198 -                    break;
   4.199 -
   4.200 -                case 'e':
   4.201 -                    sb.append(position == Position.NOPOS ? "-" : String.valueOf(d.getEndPosition()));
   4.202 -                    break;
   4.203 -
   4.204 -                case 'f':
   4.205 -                    sb.append(source == null ? "-" : d.getSourceName());
   4.206 -                    break;
   4.207 -
   4.208 -                case 'l':
   4.209 -                    sb.append(position == Position.NOPOS ? "-" : String.valueOf(d.getLineNumber()));
   4.210 -                    break;
   4.211 -
   4.212 -                case 'c':
   4.213 -                    sb.append(position == Position.NOPOS ? "-" : String.valueOf(d.getColumnNumber()));
   4.214 -                    break;
   4.215 -
   4.216 -                case 'o':
   4.217 -                    sb.append(position == Position.NOPOS ? "-" : String.valueOf(position));
   4.218 -                    break;
   4.219 -
   4.220 -                case 'p':
   4.221 -                    sb.append(d.getPrefix());
   4.222 -                    break;
   4.223 -
   4.224 -                case 's':
   4.225 -                    sb.append(position == Position.NOPOS ? "-" : String.valueOf(d.getStartPosition()));
   4.226 -                    break;
   4.227 -
   4.228 -                case 't': {
   4.229 -                    boolean usePrefix;
   4.230 -                    switch (type) {
   4.231 -                    case FRAGMENT:
   4.232 -                        usePrefix = false;
   4.233 -                        break;
   4.234 -
   4.235 -                    case ERROR:
   4.236 -                        usePrefix = (position == Position.NOPOS);
   4.237 -                        break;
   4.238 -
   4.239 -                    default:
   4.240 -                        usePrefix = true;
   4.241 -                    }
   4.242 -
   4.243 -                    if (usePrefix)
   4.244 -                        sb.append(d.getPrefix());
   4.245 -                    break;
   4.246 -                }
   4.247 -
   4.248 -                case 'm':
   4.249 -                    sb.append(d.getMessage(null));
   4.250 -                    break;
   4.251 -
   4.252 -                case '_':
   4.253 -                    sb.append(' ');
   4.254 -                    break;
   4.255 -
   4.256 -                case '%':
   4.257 -                    sb.append('%');
   4.258 -                    break;
   4.259 -
   4.260 -                default:
   4.261 -                    sb.append(c);
   4.262 -                    break;
   4.263 -                }
   4.264 -            }
   4.265 -            else
   4.266 -                sb.append(c);
   4.267 -        }
   4.268 -        return sb.toString();
   4.269 -    }
   4.270 -}
     5.1 --- a/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java	Fri Jul 25 12:22:09 2008 +0100
     5.2 +++ b/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java	Mon Jul 28 10:22:10 2008 +0100
     5.3 @@ -25,15 +25,13 @@
     5.4  
     5.5  package com.sun.tools.javac.util;
     5.6  
     5.7 -import java.util.ResourceBundle;
     5.8 -import java.util.Collection;
     5.9  import java.util.Locale;
    5.10  import java.util.Map;
    5.11  
    5.12  import javax.tools.Diagnostic;
    5.13  import javax.tools.JavaFileObject;
    5.14  
    5.15 -import com.sun.tools.javac.api.Formattable;
    5.16 +import com.sun.tools.javac.api.DiagnosticFormatter;
    5.17  import com.sun.tools.javac.file.JavacFileManager;
    5.18  import com.sun.tools.javac.tree.JCTree;
    5.19  
    5.20 @@ -256,7 +254,7 @@
    5.21      private final int line;
    5.22      private final int column;
    5.23      private final String key;
    5.24 -    private final Object[] args;
    5.25 +    protected Object[] args;
    5.26      private boolean mandatory;
    5.27  
    5.28      /**
    5.29 @@ -400,52 +398,25 @@
    5.30       * @return the prefix string associated with a particular type of diagnostic
    5.31       */
    5.32      public String getPrefix(DiagnosticType dt) {
    5.33 -        switch (dt) {
    5.34 -        case FRAGMENT: return "";
    5.35 -        case NOTE:     return getLocalizedString("compiler.note.note");
    5.36 -        case WARNING:  return getLocalizedString("compiler.warn.warning");
    5.37 -        case ERROR:    return getLocalizedString("compiler.err.error");
    5.38 -        default:
    5.39 -            throw new AssertionError("Unknown diagnostic type: " + dt);
    5.40 +        return getFormatter().formatKind(this, Locale.getDefault());
    5.41 +    }
    5.42 +
    5.43 +     private DiagnosticFormatter<JCDiagnostic> getFormatter() {
    5.44 +        if (defaultFormatter == null) {
    5.45 +            defaultFormatter = new BasicDiagnosticFormatter(messages);
    5.46          }
    5.47 +        return defaultFormatter;
    5.48      }
    5.49  
    5.50 +
    5.51      /**
    5.52       * Return the standard presentation of this diagnostic.
    5.53       */
    5.54      public String toString() {
    5.55 -        if (defaultFormatter == null) {
    5.56 -            defaultFormatter =
    5.57 -                new DiagnosticFormatter();
    5.58 -        }
    5.59 -        return defaultFormatter.format(this);
    5.60 +        return getFormatter().format(this,Locale.getDefault());
    5.61      }
    5.62  
    5.63 -    private static DiagnosticFormatter defaultFormatter;
    5.64 -
    5.65 -    private static final String messageBundleName =
    5.66 -        "com.sun.tools.javac.resources.compiler";
    5.67 -
    5.68 -    private String getLocalizedString(String key, Object... args) {
    5.69 -        String[] strings = new String[args.length];
    5.70 -        for (int i = 0; i < strings.length; i++) {
    5.71 -            Object arg = args[i];
    5.72 -            if (arg == null)
    5.73 -                strings[i] = null;
    5.74 -            else if (arg instanceof JCDiagnostic)
    5.75 -                strings[i] = ((JCDiagnostic) arg).getMessage(null);
    5.76 -            else if (arg instanceof Collection<?>)
    5.77 -                strings[i] = DiagnosticFormatter.convert((Collection<?>)arg).toString();
    5.78 -            else if (arg instanceof Formattable) {
    5.79 -                ResourceBundle rb = ResourceBundle.getBundle(messageBundleName);
    5.80 -                strings[i] = ((Formattable)arg).toString(rb);
    5.81 -            }
    5.82 -            else
    5.83 -                strings[i] = arg.toString();
    5.84 -        }
    5.85 -
    5.86 -        return messages.getLocalizedString(key, (Object[]) strings);
    5.87 -    }
    5.88 +    private static DiagnosticFormatter<JCDiagnostic> defaultFormatter;
    5.89  
    5.90      // Methods for javax.tools.Diagnostic
    5.91  
    5.92 @@ -469,7 +440,6 @@
    5.93  
    5.94      public String getMessage(Locale locale) {
    5.95          // RFE 6406133: JCDiagnostic.getMessage ignores locale argument
    5.96 -        return getLocalizedString(key, args);
    5.97 +        return getFormatter().formatMessage(this, locale);
    5.98      }
    5.99 -
   5.100  }
     6.1 --- a/src/share/classes/com/sun/tools/javac/util/Log.java	Fri Jul 25 12:22:09 2008 +0100
     6.2 +++ b/src/share/classes/com/sun/tools/javac/util/Log.java	Mon Jul 28 10:22:10 2008 +0100
     6.3 @@ -29,11 +29,13 @@
     6.4  import java.util.HashSet;
     6.5  import java.util.Map;
     6.6  import java.util.Set;
     6.7 +import java.util.Locale;
     6.8  import javax.tools.DiagnosticListener;
     6.9  import javax.tools.JavaFileObject;
    6.10  
    6.11  import com.sun.tools.javac.file.JavacFileManager;
    6.12  import com.sun.tools.javac.tree.JCTree;
    6.13 +import com.sun.tools.javac.api.DiagnosticFormatter;
    6.14  import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    6.15  import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
    6.16  
    6.17 @@ -68,10 +70,6 @@
    6.18      public final int MaxErrors;
    6.19      public final int MaxWarnings;
    6.20  
    6.21 -    /** Whether or not to display the line of source containing a diagnostic.
    6.22 -     */
    6.23 -    private final boolean showSourceLine;
    6.24 -
    6.25      /** Switch: prompt user on each error.
    6.26       */
    6.27      public boolean promptOnError;
    6.28 @@ -97,7 +95,7 @@
    6.29      /**
    6.30       * Formatter for diagnostics
    6.31       */
    6.32 -    private DiagnosticFormatter diagFormatter;
    6.33 +    private DiagnosticFormatter<JCDiagnostic> diagFormatter;
    6.34  
    6.35      /** Construct a log with given I/O redirections.
    6.36       */
    6.37 @@ -115,9 +113,11 @@
    6.38          this.emitWarnings = options.get("-Xlint:none") == null;
    6.39          this.MaxErrors = getIntOption(options, "-Xmaxerrs", 100);
    6.40          this.MaxWarnings = getIntOption(options, "-Xmaxwarns", 100);
    6.41 -        this.showSourceLine = options.get("rawDiagnostics") == null;
    6.42  
    6.43 -        this.diagFormatter = DiagnosticFormatter.instance(context);
    6.44 +        boolean rawDiagnostics = options.get("rawDiagnostics") != null;
    6.45 +        Messages msgs = Messages.instance(context);
    6.46 +        this.diagFormatter = rawDiagnostics ? new RawDiagnosticFormatter(msgs) :
    6.47 +                                              new BasicDiagnosticFormatter(options, msgs);
    6.48          @SuppressWarnings("unchecked") // FIXME
    6.49          DiagnosticListener<? super JavaFileObject> diagListener =
    6.50              context.get(DiagnosticListener.class);
    6.51 @@ -335,8 +335,8 @@
    6.52  
    6.53          PrintWriter writer = getWriterForDiagnosticType(diag.getType());
    6.54  
    6.55 -        printLines(writer, diagFormatter.format(diag));
    6.56 -        if (showSourceLine) {
    6.57 +        printLines(writer, diagFormatter.format(diag, Locale.getDefault()));
    6.58 +        if (diagFormatter.displaySource(diag)) {
    6.59              int pos = diag.getIntPosition();
    6.60              if (pos != Position.NOPOS) {
    6.61                  JavaFileObject prev = useSource(diag.getSource());
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java	Mon Jul 28 10:22:10 2008 +0100
     7.3 @@ -0,0 +1,107 @@
     7.4 +/*
     7.5 + * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
     7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     7.7 + *
     7.8 + * This code is free software; you can redistribute it and/or modify it
     7.9 + * under the terms of the GNU General Public License version 2 only, as
    7.10 + * published by the Free Software Foundation.  Sun designates this
    7.11 + * particular file as subject to the "Classpath" exception as provided
    7.12 + * by Sun in the LICENSE file that accompanied this code.
    7.13 + *
    7.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    7.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    7.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    7.17 + * version 2 for more details (a copy is included in the LICENSE file that
    7.18 + * accompanied this code).
    7.19 + *
    7.20 + * You should have received a copy of the GNU General Public License version
    7.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    7.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    7.23 + *
    7.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    7.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
    7.26 + * have any questions.
    7.27 + */
    7.28 +package com.sun.tools.javac.util;
    7.29 +
    7.30 +import java.util.Locale;
    7.31 +
    7.32 +import com.sun.tools.javac.api.Formattable;
    7.33 +import static com.sun.tools.javac.api.DiagnosticFormatter.PositionKind.*;
    7.34 +
    7.35 +/**
    7.36 + * A raw formatter for diagnostic messages.
    7.37 + * The raw formatter will format a diagnostic according to one of two format patterns, depending on whether
    7.38 + * or not the source name and position are set. This formatter provides a standardized, localize-independent
    7.39 + * implementation of a diagnostic formatter; as such, this formatter is best suited for testing purposes.
    7.40 + */
    7.41 +public class RawDiagnosticFormatter extends AbstractDiagnosticFormatter {
    7.42 +
    7.43 +    /**
    7.44 +     * Create a formatter based on the supplied options.
    7.45 +     * @param msgs
    7.46 +     */
    7.47 +    public RawDiagnosticFormatter(Messages msgs) {
    7.48 +        super(null);
    7.49 +    }
    7.50 +
    7.51 +    //provide common default formats
    7.52 +    public String format(JCDiagnostic d, Locale l) {
    7.53 +        try {
    7.54 +            StringBuffer buf = new StringBuffer();
    7.55 +            if (d.getPosition() != Position.NOPOS) {
    7.56 +                buf.append(formatSource(d, null));
    7.57 +                buf.append(':');
    7.58 +                buf.append(formatPosition(d, LINE, null));
    7.59 +                buf.append(':');
    7.60 +                buf.append(formatPosition(d, COLUMN, null));
    7.61 +                buf.append(':');
    7.62 +            }
    7.63 +            else
    7.64 +                buf.append('-');
    7.65 +            buf.append(' ');
    7.66 +            buf.append(formatMessage(d, null));
    7.67 +            return buf.toString();
    7.68 +        }
    7.69 +        catch (Exception e) {
    7.70 +            e.printStackTrace();
    7.71 +            return null;
    7.72 +        }
    7.73 +    }
    7.74 +
    7.75 +    @Override
    7.76 +    public String formatSource(JCDiagnostic d,Locale l) {
    7.77 +        assert(d.getSource() != null);
    7.78 +        return d.getSource().getName();
    7.79 +    }
    7.80 +
    7.81 +    @Override
    7.82 +    protected String formatArgument(JCDiagnostic diag, Object arg, Locale l) {
    7.83 +        String s;
    7.84 +        if (arg instanceof Formattable)
    7.85 +            s = arg.toString();
    7.86 +        else
    7.87 +            s = super.formatArgument(diag, arg, null);
    7.88 +        if (arg instanceof JCDiagnostic)
    7.89 +            return "(" + s + ")";
    7.90 +        else
    7.91 +            return s;
    7.92 +    }
    7.93 +
    7.94 +    @Override
    7.95 +    protected String localize(Locale l, String s, Object... args) {
    7.96 +        StringBuffer buf = new StringBuffer();
    7.97 +        buf.append(s);
    7.98 +        String sep = ": ";
    7.99 +        for (Object o : args) {
   7.100 +            buf.append(sep);
   7.101 +            buf.append(o);
   7.102 +            sep = ", ";
   7.103 +        }
   7.104 +        return buf.toString();
   7.105 +    }
   7.106 +
   7.107 +    public boolean displaySource(JCDiagnostic d) {
   7.108 +        return false;
   7.109 +    }
   7.110 +}

mercurial