Mon, 28 Jul 2008 10:22:10 +0100
6720185: DiagnosticFormatter refactoring
Summary: Brand new hierarchy of diagnostic formatters for achieving better reusability
Reviewed-by: jjg
mcimadamore@83 | 1 | /* |
mcimadamore@83 | 2 | * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. |
mcimadamore@83 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
mcimadamore@83 | 4 | * |
mcimadamore@83 | 5 | * This code is free software; you can redistribute it and/or modify it |
mcimadamore@83 | 6 | * under the terms of the GNU General Public License version 2 only, as |
mcimadamore@83 | 7 | * published by the Free Software Foundation. Sun designates this |
mcimadamore@83 | 8 | * particular file as subject to the "Classpath" exception as provided |
mcimadamore@83 | 9 | * by Sun in the LICENSE file that accompanied this code. |
mcimadamore@83 | 10 | * |
mcimadamore@83 | 11 | * This code is distributed in the hope that it will be useful, but WITHOUT |
mcimadamore@83 | 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
mcimadamore@83 | 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
mcimadamore@83 | 14 | * version 2 for more details (a copy is included in the LICENSE file that |
mcimadamore@83 | 15 | * accompanied this code). |
mcimadamore@83 | 16 | * |
mcimadamore@83 | 17 | * You should have received a copy of the GNU General Public License version |
mcimadamore@83 | 18 | * 2 along with this work; if not, write to the Free Software Foundation, |
mcimadamore@83 | 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
mcimadamore@83 | 20 | * |
mcimadamore@83 | 21 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
mcimadamore@83 | 22 | * CA 95054 USA or visit www.sun.com if you need additional information or |
mcimadamore@83 | 23 | * have any questions. |
mcimadamore@83 | 24 | */ |
mcimadamore@83 | 25 | |
mcimadamore@83 | 26 | package com.sun.tools.javac.util; |
mcimadamore@83 | 27 | |
mcimadamore@83 | 28 | import java.util.HashMap; |
mcimadamore@83 | 29 | import java.util.Locale; |
mcimadamore@83 | 30 | import java.util.Map; |
mcimadamore@83 | 31 | import javax.tools.JavaFileObject; |
mcimadamore@83 | 32 | |
mcimadamore@83 | 33 | import static com.sun.tools.javac.util.BasicDiagnosticFormatter.BasicFormatKind.*; |
mcimadamore@83 | 34 | import static com.sun.tools.javac.api.DiagnosticFormatter.PositionKind.*; |
mcimadamore@83 | 35 | |
mcimadamore@83 | 36 | /** |
mcimadamore@83 | 37 | * A basic formatter for diagnostic messages. |
mcimadamore@83 | 38 | * The basic formatter will format a diagnostic according to one of three format patterns, depending on whether |
mcimadamore@83 | 39 | * or not the source name and position are set. The formatter supports a printf-like string for patterns |
mcimadamore@83 | 40 | * with the following special characters: |
mcimadamore@83 | 41 | * <ul> |
mcimadamore@83 | 42 | * <li>%b: the base of the source name |
mcimadamore@83 | 43 | * <li>%f: the source name (full absolute path) |
mcimadamore@83 | 44 | * <li>%l: the line number of the diagnostic, derived from the character offset |
mcimadamore@83 | 45 | * <li>%c: the column number of the diagnostic, derived from the character offset |
mcimadamore@83 | 46 | * <li>%o: the character offset of the diagnostic if set |
mcimadamore@83 | 47 | * <li>%p: the prefix for the diagnostic, derived from the diagnostic type |
mcimadamore@83 | 48 | * <li>%t: the prefix as it normally appears in standard diagnostics. In this case, no prefix is |
mcimadamore@83 | 49 | * shown if the type is ERROR and if a source name is set |
mcimadamore@83 | 50 | * <li>%m: the text or the diagnostic, including any appropriate arguments |
mcimadamore@83 | 51 | * <li>%_: space delimiter, useful for formatting purposes |
mcimadamore@83 | 52 | * </ul> |
mcimadamore@83 | 53 | */ |
mcimadamore@83 | 54 | public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter { |
mcimadamore@83 | 55 | |
mcimadamore@83 | 56 | protected Map<BasicFormatKind, String> availableFormats; |
mcimadamore@83 | 57 | |
mcimadamore@83 | 58 | /** |
mcimadamore@83 | 59 | * Create a basic formatter based on the supplied options. |
mcimadamore@83 | 60 | * |
mcimadamore@83 | 61 | * @param opts list of command-line options |
mcimadamore@83 | 62 | * @param msgs Messages object used for i18n |
mcimadamore@83 | 63 | */ |
mcimadamore@83 | 64 | BasicDiagnosticFormatter(Options opts, Messages msgs) { |
mcimadamore@83 | 65 | this(msgs); //common init |
mcimadamore@83 | 66 | String fmt = opts.get("diags"); |
mcimadamore@83 | 67 | if (fmt != null) { |
mcimadamore@83 | 68 | String[] formats = fmt.split("\\|"); |
mcimadamore@83 | 69 | switch (formats.length) { |
mcimadamore@83 | 70 | case 3: |
mcimadamore@83 | 71 | availableFormats.put(DEFAULT_CLASS_FORMAT, formats[2]); |
mcimadamore@83 | 72 | case 2: |
mcimadamore@83 | 73 | availableFormats.put(DEFAULT_NO_POS_FORMAT, formats[1]); |
mcimadamore@83 | 74 | default: |
mcimadamore@83 | 75 | availableFormats.put(DEFAULT_POS_FORMAT, formats[0]); |
mcimadamore@83 | 76 | } |
mcimadamore@83 | 77 | } |
mcimadamore@83 | 78 | } |
mcimadamore@83 | 79 | |
mcimadamore@83 | 80 | /** |
mcimadamore@83 | 81 | * Create a standard basic formatter |
mcimadamore@83 | 82 | * |
mcimadamore@83 | 83 | * @param msgs Messages object used for i18n |
mcimadamore@83 | 84 | */ |
mcimadamore@83 | 85 | public BasicDiagnosticFormatter(Messages msgs) { |
mcimadamore@83 | 86 | super(msgs); |
mcimadamore@83 | 87 | availableFormats = new HashMap<BasicFormatKind, String>(); |
mcimadamore@83 | 88 | availableFormats.put(DEFAULT_POS_FORMAT, "%f:%l:%_%t%m"); |
mcimadamore@83 | 89 | availableFormats.put(DEFAULT_NO_POS_FORMAT, "%p%m"); |
mcimadamore@83 | 90 | availableFormats.put(DEFAULT_CLASS_FORMAT, "%f:%_%t%m"); |
mcimadamore@83 | 91 | } |
mcimadamore@83 | 92 | |
mcimadamore@83 | 93 | public String format(JCDiagnostic d, Locale l) { |
mcimadamore@83 | 94 | String format = selectFormat(d); |
mcimadamore@83 | 95 | StringBuilder buf = new StringBuilder(); |
mcimadamore@83 | 96 | for (int i = 0; i < format.length(); i++) { |
mcimadamore@83 | 97 | char c = format.charAt(i); |
mcimadamore@83 | 98 | boolean meta = false; |
mcimadamore@83 | 99 | if (c == '%' && i < format.length() - 1) { |
mcimadamore@83 | 100 | meta = true; |
mcimadamore@83 | 101 | c = format.charAt(++i); |
mcimadamore@83 | 102 | } |
mcimadamore@83 | 103 | buf.append(meta ? formatMeta(c, d, l) : String.valueOf(c)); |
mcimadamore@83 | 104 | } |
mcimadamore@83 | 105 | return buf.toString(); |
mcimadamore@83 | 106 | } |
mcimadamore@83 | 107 | |
mcimadamore@83 | 108 | protected String formatMeta(char c, JCDiagnostic d, Locale l) { |
mcimadamore@83 | 109 | switch (c) { |
mcimadamore@83 | 110 | case 'b': |
mcimadamore@83 | 111 | return formatSource(d, l); |
mcimadamore@83 | 112 | case 'e': |
mcimadamore@83 | 113 | return formatPosition(d, END, l); |
mcimadamore@83 | 114 | case 'f': |
mcimadamore@83 | 115 | return formatSource(d, l); |
mcimadamore@83 | 116 | case 'l': |
mcimadamore@83 | 117 | return formatPosition(d, LINE, l); |
mcimadamore@83 | 118 | case 'c': |
mcimadamore@83 | 119 | return formatPosition(d, COLUMN, l); |
mcimadamore@83 | 120 | case 'o': |
mcimadamore@83 | 121 | return formatPosition(d, OFFSET, l); |
mcimadamore@83 | 122 | case 'p': |
mcimadamore@83 | 123 | return formatKind(d, l); |
mcimadamore@83 | 124 | case 's': |
mcimadamore@83 | 125 | return formatPosition(d, START, l); |
mcimadamore@83 | 126 | case 't': { |
mcimadamore@83 | 127 | boolean usePrefix; |
mcimadamore@83 | 128 | switch (d.getType()) { |
mcimadamore@83 | 129 | case FRAGMENT: |
mcimadamore@83 | 130 | usePrefix = false; |
mcimadamore@83 | 131 | break; |
mcimadamore@83 | 132 | case ERROR: |
mcimadamore@83 | 133 | usePrefix = (d.getIntPosition() == Position.NOPOS); |
mcimadamore@83 | 134 | break; |
mcimadamore@83 | 135 | default: |
mcimadamore@83 | 136 | usePrefix = true; |
mcimadamore@83 | 137 | } |
mcimadamore@83 | 138 | if (usePrefix) |
mcimadamore@83 | 139 | return formatKind(d, l); |
mcimadamore@83 | 140 | else |
mcimadamore@83 | 141 | return ""; |
mcimadamore@83 | 142 | } |
mcimadamore@83 | 143 | case 'm': |
mcimadamore@83 | 144 | return formatMessage(d, l); |
mcimadamore@83 | 145 | case '_': |
mcimadamore@83 | 146 | return " "; |
mcimadamore@83 | 147 | case '%': |
mcimadamore@83 | 148 | return "%"; |
mcimadamore@83 | 149 | default: |
mcimadamore@83 | 150 | return String.valueOf(c); |
mcimadamore@83 | 151 | } |
mcimadamore@83 | 152 | } |
mcimadamore@83 | 153 | |
mcimadamore@83 | 154 | private String selectFormat(JCDiagnostic d) { |
mcimadamore@83 | 155 | DiagnosticSource source = d.getDiagnosticSource(); |
mcimadamore@83 | 156 | String format = availableFormats.get(DEFAULT_NO_POS_FORMAT); |
mcimadamore@83 | 157 | if (source != null) { |
mcimadamore@83 | 158 | if (d.getIntPosition() != Position.NOPOS) { |
mcimadamore@83 | 159 | format = availableFormats.get(DEFAULT_POS_FORMAT); |
mcimadamore@83 | 160 | } else if (source.getFile() != null && |
mcimadamore@83 | 161 | source.getFile().getKind() == JavaFileObject.Kind.CLASS) { |
mcimadamore@83 | 162 | format = availableFormats.get(DEFAULT_CLASS_FORMAT); |
mcimadamore@83 | 163 | } |
mcimadamore@83 | 164 | } |
mcimadamore@83 | 165 | return format; |
mcimadamore@83 | 166 | } |
mcimadamore@83 | 167 | |
mcimadamore@83 | 168 | public boolean displaySource(JCDiagnostic d) { |
mcimadamore@83 | 169 | return true; |
mcimadamore@83 | 170 | } |
mcimadamore@83 | 171 | |
mcimadamore@83 | 172 | /** |
mcimadamore@83 | 173 | * This enum contains all the kinds of formatting patterns supported |
mcimadamore@83 | 174 | * by a basic diagnostic formatter. |
mcimadamore@83 | 175 | */ |
mcimadamore@83 | 176 | public enum BasicFormatKind { |
mcimadamore@83 | 177 | /** |
mcimadamore@83 | 178 | * A format string to be used for diagnostics with a given position. |
mcimadamore@83 | 179 | */ |
mcimadamore@83 | 180 | DEFAULT_POS_FORMAT, |
mcimadamore@83 | 181 | /** |
mcimadamore@83 | 182 | * A format string to be used for diagnostics without a given position. |
mcimadamore@83 | 183 | */ |
mcimadamore@83 | 184 | DEFAULT_NO_POS_FORMAT, |
mcimadamore@83 | 185 | /** |
mcimadamore@83 | 186 | * A format string to be used for diagnostics regarding classfiles |
mcimadamore@83 | 187 | */ |
mcimadamore@83 | 188 | DEFAULT_CLASS_FORMAT; |
mcimadamore@83 | 189 | } |
mcimadamore@83 | 190 | } |