src/share/classes/com/sun/tools/javac/util/DiagnosticFormatter.java

changeset 1
9a66ca7c79fa
child 50
b9bcea8bbe24
equal deleted inserted replaced
-1:000000000000 1:9a66ca7c79fa
1 /*
2 * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26 package com.sun.tools.javac.util;
27
28 import javax.tools.JavaFileObject;
29
30 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticSource;
31 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
32
33 /**
34 * A formatter for diagnostic messages.
35 * The formatter will format a diagnostic according to one of two format strings, depending on whether
36 * or not the source name and position are set. The format is a printf-like string,
37 * with the following special characters:
38 * <ul>
39 * <li>%b: the base of the source name, or "-" if not set
40 * <li>%f: the source name, or "-" if not set
41 * <li>%l: the line number of the diagnostic, derived from the character offset if set, or "-" otherwise
42 * <li>%c: the column number of the diagnostic, derived from the character offset if set, or "-" otherwise
43 * <li>%o: the character offset of the diagnostic if set, or "-" otherwise
44 * <li>%p: the prefix for the diagnostic, derived from the diagnostic type
45 * <li>%t: the prefix as it normally appears in standard diagnostics. In this case, no prefix is
46 * shown if the type is ERROR and if a source name is set
47 * <li>%m: the text or the diagnostic, including any appropriate arguments
48 * </ul>
49 */
50 public class DiagnosticFormatter {
51 /**
52 * A format string to be used for diagnostics with a given position.
53 */
54 protected String posFormat;
55
56 /**
57 * A format string to be used for diagnostics regarding classfiles
58 */
59 protected String classFormat = DEFAULT_CLASS_FORMAT;
60
61 /**
62 * A format string to be used for diagnostics without a given position.
63 */
64 protected String noPosFormat;
65
66 /**
67 * A value to indicate whether to output the i18n key and args, instead of
68 * the derived l10n message.
69 */
70 protected boolean raw;
71
72 /** The context key for the formatter. */
73 protected static final Context.Key<DiagnosticFormatter> formatterKey =
74 new Context.Key<DiagnosticFormatter>();
75
76 /** Get the DiagnosticFormatter instance for this context. */
77 public static DiagnosticFormatter instance(Context context) {
78 DiagnosticFormatter instance = context.get(formatterKey);
79 if (instance == null)
80 instance = new DiagnosticFormatter(context);
81 return instance;
82 }
83
84 /**
85 * Create a formatter based on the supplied options.
86 */
87 protected DiagnosticFormatter(Context context) {
88 Options options = Options.instance(context);
89 raw = options.get("rawDiagnostics") != null;
90 String fmt = options.get("diags");
91 if (fmt != null) {
92 int sep = fmt.indexOf('|');
93 if (sep == -1)
94 posFormat = noPosFormat = fmt;
95 else {
96 posFormat = fmt.substring(0, sep);
97 noPosFormat = fmt.substring(sep + 1);
98 }
99 }
100 else {
101 posFormat = DEFAULT_POS_FORMAT;
102 noPosFormat = DEFAULT_NO_POS_FORMAT;
103 }
104 }
105
106 public static final String DEFAULT_POS_FORMAT = "%f:%l: %t%m";
107 public static final String DEFAULT_CLASS_FORMAT = "%f: %t%m";
108 public static final String DEFAULT_NO_POS_FORMAT = "%p%m";
109
110 public DiagnosticFormatter() {
111 posFormat = DEFAULT_POS_FORMAT;
112 noPosFormat = DEFAULT_NO_POS_FORMAT;
113 raw = false;
114 }
115
116 public DiagnosticFormatter(String pos, String noPos) {
117 posFormat = pos;
118 noPosFormat = noPos;
119 raw = false;
120 }
121
122 String format(JCDiagnostic d) {
123 return (raw ? format_raw(d) : format_std(d));
124 }
125
126 private String format_raw(JCDiagnostic d) {
127 DiagnosticSource source = d.getDiagnosticSource();
128 int position = d.getIntPosition();
129
130 StringBuilder sb = new StringBuilder();
131 if (position == Position.NOPOS)
132 sb.append("-");
133 else {
134 sb.append(source.getName() + ":" + source.getLineNumber(position) + ":" + source.getColumnNumber(position) + ":");
135 }
136 sb.append(" ");
137 sb.append(d.getCode());
138 String sep = ": ";
139 for (Object arg: d.getArgs()) {
140 sb.append(sep);
141 if (arg instanceof JCDiagnostic) {
142 sb.append('(');
143 sb.append(format_raw((JCDiagnostic) arg));
144 sb.append(')');
145 }
146 else if (arg instanceof JavaFileObject)
147 sb.append(JavacFileManager.getJavacBaseFileName((JavaFileObject) arg));
148 else
149 sb.append(arg);
150 sep = ", ";
151 }
152 return sb.toString();
153 }
154
155 private String format_std(JCDiagnostic d) {
156 DiagnosticSource source = d.getDiagnosticSource();
157 DiagnosticType type = d.getType();
158 int position = d.getIntPosition();
159
160
161 String format = noPosFormat;
162 if (source != null) {
163 if (position != Position.NOPOS) {
164 format = posFormat;
165 } else if (source.getFile() != null &&
166 source.getFile().getKind() == JavaFileObject.Kind.CLASS) {
167 format = classFormat;
168 }
169 }
170
171 StringBuilder sb = new StringBuilder();
172
173 for (int i = 0; i < format.length(); i++) {
174 char c = format.charAt(i);
175 if (c == '%' && i < format.length() - 1) {
176 c = format.charAt(++i);
177 switch (c) {
178 case 'b':
179 sb.append(source == null ? "-" : source.getName());
180 break;
181
182 case 'e':
183 sb.append(position == Position.NOPOS ? "-" : String.valueOf(d.getEndPosition()));
184 break;
185
186 case 'f':
187 sb.append(source == null ? "-" : d.getSourceName());
188 break;
189
190 case 'l':
191 sb.append(position == Position.NOPOS ? "-" : String.valueOf(d.getLineNumber()));
192 break;
193
194 case 'c':
195 sb.append(position == Position.NOPOS ? "-" : String.valueOf(d.getColumnNumber()));
196 break;
197
198 case 'o':
199 sb.append(position == Position.NOPOS ? "-" : String.valueOf(position));
200 break;
201
202 case 'p':
203 sb.append(d.getPrefix());
204 break;
205
206 case 's':
207 sb.append(position == Position.NOPOS ? "-" : String.valueOf(d.getStartPosition()));
208 break;
209
210 case 't': {
211 boolean usePrefix;
212 switch (type) {
213 case FRAGMENT:
214 usePrefix = false;
215 break;
216
217 case ERROR:
218 usePrefix = (position == Position.NOPOS);
219 break;
220
221 default:
222 usePrefix = true;
223 }
224
225 if (usePrefix)
226 sb.append(d.getPrefix());
227 break;
228 }
229
230 case 'm':
231 sb.append(d.getMessage(null));
232 break;
233
234 case '_':
235 sb.append(' ');
236 break;
237
238 case '%':
239 sb.append('%');
240 break;
241
242 default:
243 sb.append(c);
244 break;
245 }
246 }
247 else
248 sb.append(c);
249 }
250 return sb.toString();
251 }
252 }

mercurial