mcimadamore@83: /* mcimadamore@83: * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. mcimadamore@83: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. mcimadamore@83: * mcimadamore@83: * This code is free software; you can redistribute it and/or modify it mcimadamore@83: * under the terms of the GNU General Public License version 2 only, as mcimadamore@83: * published by the Free Software Foundation. Sun designates this mcimadamore@83: * particular file as subject to the "Classpath" exception as provided mcimadamore@83: * by Sun in the LICENSE file that accompanied this code. mcimadamore@83: * mcimadamore@83: * This code is distributed in the hope that it will be useful, but WITHOUT mcimadamore@83: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or mcimadamore@83: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License mcimadamore@83: * version 2 for more details (a copy is included in the LICENSE file that mcimadamore@83: * accompanied this code). mcimadamore@83: * mcimadamore@83: * You should have received a copy of the GNU General Public License version mcimadamore@83: * 2 along with this work; if not, write to the Free Software Foundation, mcimadamore@83: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. mcimadamore@83: * mcimadamore@83: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, mcimadamore@83: * CA 95054 USA or visit www.sun.com if you need additional information or mcimadamore@83: * have any questions. mcimadamore@83: */ mcimadamore@83: mcimadamore@83: package com.sun.tools.javac.util; mcimadamore@83: mcimadamore@83: import java.util.HashMap; mcimadamore@83: import java.util.Locale; mcimadamore@83: import java.util.Map; mcimadamore@83: import javax.tools.JavaFileObject; mcimadamore@83: mcimadamore@83: import static com.sun.tools.javac.util.BasicDiagnosticFormatter.BasicFormatKind.*; mcimadamore@83: import static com.sun.tools.javac.api.DiagnosticFormatter.PositionKind.*; mcimadamore@83: mcimadamore@83: /** mcimadamore@83: * A basic formatter for diagnostic messages. mcimadamore@83: * The basic formatter will format a diagnostic according to one of three format patterns, depending on whether mcimadamore@83: * or not the source name and position are set. The formatter supports a printf-like string for patterns mcimadamore@83: * with the following special characters: mcimadamore@83: * mcimadamore@83: */ mcimadamore@83: public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter { mcimadamore@83: mcimadamore@83: protected Map availableFormats; mcimadamore@83: mcimadamore@83: /** mcimadamore@83: * Create a basic formatter based on the supplied options. mcimadamore@83: * mcimadamore@83: * @param opts list of command-line options mcimadamore@83: * @param msgs Messages object used for i18n mcimadamore@83: */ mcimadamore@83: BasicDiagnosticFormatter(Options opts, Messages msgs) { mcimadamore@83: this(msgs); //common init mcimadamore@83: String fmt = opts.get("diags"); mcimadamore@83: if (fmt != null) { mcimadamore@83: String[] formats = fmt.split("\\|"); mcimadamore@83: switch (formats.length) { mcimadamore@83: case 3: mcimadamore@83: availableFormats.put(DEFAULT_CLASS_FORMAT, formats[2]); mcimadamore@83: case 2: mcimadamore@83: availableFormats.put(DEFAULT_NO_POS_FORMAT, formats[1]); mcimadamore@83: default: mcimadamore@83: availableFormats.put(DEFAULT_POS_FORMAT, formats[0]); mcimadamore@83: } mcimadamore@83: } mcimadamore@83: } mcimadamore@83: mcimadamore@83: /** mcimadamore@83: * Create a standard basic formatter mcimadamore@83: * mcimadamore@83: * @param msgs Messages object used for i18n mcimadamore@83: */ mcimadamore@83: public BasicDiagnosticFormatter(Messages msgs) { mcimadamore@83: super(msgs); mcimadamore@83: availableFormats = new HashMap(); mcimadamore@83: availableFormats.put(DEFAULT_POS_FORMAT, "%f:%l:%_%t%m"); mcimadamore@83: availableFormats.put(DEFAULT_NO_POS_FORMAT, "%p%m"); mcimadamore@83: availableFormats.put(DEFAULT_CLASS_FORMAT, "%f:%_%t%m"); mcimadamore@83: } mcimadamore@83: mcimadamore@83: public String format(JCDiagnostic d, Locale l) { mcimadamore@83: String format = selectFormat(d); mcimadamore@83: StringBuilder buf = new StringBuilder(); mcimadamore@83: for (int i = 0; i < format.length(); i++) { mcimadamore@83: char c = format.charAt(i); mcimadamore@83: boolean meta = false; mcimadamore@83: if (c == '%' && i < format.length() - 1) { mcimadamore@83: meta = true; mcimadamore@83: c = format.charAt(++i); mcimadamore@83: } mcimadamore@83: buf.append(meta ? formatMeta(c, d, l) : String.valueOf(c)); mcimadamore@83: } mcimadamore@83: return buf.toString(); mcimadamore@83: } mcimadamore@83: mcimadamore@83: protected String formatMeta(char c, JCDiagnostic d, Locale l) { mcimadamore@83: switch (c) { mcimadamore@83: case 'b': mcimadamore@100: return formatSource(d, false, l); mcimadamore@83: case 'e': mcimadamore@83: return formatPosition(d, END, l); mcimadamore@83: case 'f': mcimadamore@100: return formatSource(d, true, l); mcimadamore@83: case 'l': mcimadamore@83: return formatPosition(d, LINE, l); mcimadamore@83: case 'c': mcimadamore@83: return formatPosition(d, COLUMN, l); mcimadamore@83: case 'o': mcimadamore@83: return formatPosition(d, OFFSET, l); mcimadamore@83: case 'p': mcimadamore@83: return formatKind(d, l); mcimadamore@83: case 's': mcimadamore@83: return formatPosition(d, START, l); mcimadamore@83: case 't': { mcimadamore@83: boolean usePrefix; mcimadamore@83: switch (d.getType()) { mcimadamore@83: case FRAGMENT: mcimadamore@83: usePrefix = false; mcimadamore@83: break; mcimadamore@83: case ERROR: mcimadamore@83: usePrefix = (d.getIntPosition() == Position.NOPOS); mcimadamore@83: break; mcimadamore@83: default: mcimadamore@83: usePrefix = true; mcimadamore@83: } mcimadamore@83: if (usePrefix) mcimadamore@83: return formatKind(d, l); mcimadamore@83: else mcimadamore@83: return ""; mcimadamore@83: } mcimadamore@83: case 'm': mcimadamore@83: return formatMessage(d, l); mcimadamore@83: case '_': mcimadamore@83: return " "; mcimadamore@83: case '%': mcimadamore@83: return "%"; mcimadamore@83: default: mcimadamore@83: return String.valueOf(c); mcimadamore@83: } mcimadamore@83: } mcimadamore@83: mcimadamore@83: private String selectFormat(JCDiagnostic d) { mcimadamore@83: DiagnosticSource source = d.getDiagnosticSource(); mcimadamore@83: String format = availableFormats.get(DEFAULT_NO_POS_FORMAT); mcimadamore@83: if (source != null) { mcimadamore@83: if (d.getIntPosition() != Position.NOPOS) { mcimadamore@83: format = availableFormats.get(DEFAULT_POS_FORMAT); mcimadamore@83: } else if (source.getFile() != null && mcimadamore@83: source.getFile().getKind() == JavaFileObject.Kind.CLASS) { mcimadamore@83: format = availableFormats.get(DEFAULT_CLASS_FORMAT); mcimadamore@83: } mcimadamore@83: } mcimadamore@83: return format; mcimadamore@83: } mcimadamore@83: mcimadamore@83: public boolean displaySource(JCDiagnostic d) { mcimadamore@83: return true; mcimadamore@83: } mcimadamore@83: mcimadamore@83: /** mcimadamore@83: * This enum contains all the kinds of formatting patterns supported mcimadamore@83: * by a basic diagnostic formatter. mcimadamore@83: */ mcimadamore@83: public enum BasicFormatKind { mcimadamore@83: /** mcimadamore@83: * A format string to be used for diagnostics with a given position. mcimadamore@83: */ mcimadamore@83: DEFAULT_POS_FORMAT, mcimadamore@83: /** mcimadamore@83: * A format string to be used for diagnostics without a given position. mcimadamore@83: */ mcimadamore@83: DEFAULT_NO_POS_FORMAT, mcimadamore@83: /** mcimadamore@83: * A format string to be used for diagnostics regarding classfiles mcimadamore@83: */ mcimadamore@83: DEFAULT_CLASS_FORMAT; mcimadamore@83: } mcimadamore@83: }