1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/classes/com/sun/tools/javac/util/Log.java Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,723 @@ 1.4 +/* 1.5 + * Copyright 1999-2006 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 + 1.29 +package com.sun.tools.javac.util; 1.30 + 1.31 +import java.io.*; 1.32 +import java.nio.CharBuffer; 1.33 +import java.util.HashMap; 1.34 +import java.util.HashSet; 1.35 +import java.util.Map; 1.36 +import java.util.Set; 1.37 +import javax.tools.DiagnosticListener; 1.38 +import javax.tools.JavaFileObject; 1.39 +import com.sun.tools.javac.code.Source; 1.40 +import com.sun.tools.javac.tree.JCTree; 1.41 +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 1.42 +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType; 1.43 +import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition; 1.44 +import static com.sun.tools.javac.util.LayoutCharacters.*; 1.45 + 1.46 +/** A class for error logs. Reports errors and warnings, and 1.47 + * keeps track of error numbers and positions. 1.48 + * 1.49 + * <p><b>This is NOT part of any API supported by Sun Microsystems. If 1.50 + * you write code that depends on this, you do so at your own risk. 1.51 + * This code and its internal interfaces are subject to change or 1.52 + * deletion without notice.</b> 1.53 + */ 1.54 +public class Log { 1.55 + /** The context key for the log. */ 1.56 + public static final Context.Key<Log> logKey 1.57 + = new Context.Key<Log>(); 1.58 + 1.59 + /** The context key for the output PrintWriter. */ 1.60 + public static final Context.Key<PrintWriter> outKey = 1.61 + new Context.Key<PrintWriter>(); 1.62 + 1.63 + //@Deprecated 1.64 + public final PrintWriter errWriter; 1.65 + 1.66 + //@Deprecated 1.67 + public final PrintWriter warnWriter; 1.68 + 1.69 + //@Deprecated 1.70 + public final PrintWriter noticeWriter; 1.71 + 1.72 + /** The maximum number of errors/warnings that are reported. 1.73 + */ 1.74 + public final int MaxErrors; 1.75 + public final int MaxWarnings; 1.76 + 1.77 + /** Whether or not to display the line of source containing a diagnostic. 1.78 + */ 1.79 + private final boolean showSourceLine; 1.80 + 1.81 + /** Switch: prompt user on each error. 1.82 + */ 1.83 + public boolean promptOnError; 1.84 + 1.85 + /** Switch: emit warning messages. 1.86 + */ 1.87 + public boolean emitWarnings; 1.88 + 1.89 + /** Enforce mandatory warnings. 1.90 + */ 1.91 + private boolean enforceMandatoryWarnings; 1.92 + 1.93 + /** Print stack trace on errors? 1.94 + */ 1.95 + public boolean dumpOnError; 1.96 + 1.97 + /** Print multiple errors for same source locations. 1.98 + */ 1.99 + public boolean multipleErrors; 1.100 + 1.101 + /** 1.102 + * Diagnostic listener, if provided through programmatic 1.103 + * interface to javac (JSR 199). 1.104 + */ 1.105 + protected DiagnosticListener<? super JavaFileObject> diagListener; 1.106 + /** 1.107 + * Formatter for diagnostics 1.108 + */ 1.109 + private DiagnosticFormatter diagFormatter; 1.110 + 1.111 + /** 1.112 + * Factory for diagnostics 1.113 + */ 1.114 + private JCDiagnostic.Factory diags; 1.115 + 1.116 + 1.117 + /** Construct a log with given I/O redirections. 1.118 + */ 1.119 + @Deprecated 1.120 + protected Log(Context context, PrintWriter errWriter, PrintWriter warnWriter, PrintWriter noticeWriter) { 1.121 + context.put(logKey, this); 1.122 + this.errWriter = errWriter; 1.123 + this.warnWriter = warnWriter; 1.124 + this.noticeWriter = noticeWriter; 1.125 + 1.126 + this.diags = JCDiagnostic.Factory.instance(context); 1.127 + 1.128 + Options options = Options.instance(context); 1.129 + this.dumpOnError = options.get("-doe") != null; 1.130 + this.promptOnError = options.get("-prompt") != null; 1.131 + this.emitWarnings = options.get("-Xlint:none") == null; 1.132 + this.MaxErrors = getIntOption(options, "-Xmaxerrs", 100); 1.133 + this.MaxWarnings = getIntOption(options, "-Xmaxwarns", 100); 1.134 + this.showSourceLine = options.get("rawDiagnostics") == null; 1.135 + 1.136 + this.diagFormatter = DiagnosticFormatter.instance(context); 1.137 + @SuppressWarnings("unchecked") // FIXME 1.138 + DiagnosticListener<? super JavaFileObject> diagListener = 1.139 + context.get(DiagnosticListener.class); 1.140 + this.diagListener = diagListener; 1.141 + 1.142 + Source source = Source.instance(context); 1.143 + this.enforceMandatoryWarnings = source.enforceMandatoryWarnings(); 1.144 + } 1.145 + // where 1.146 + private int getIntOption(Options options, String optionName, int defaultValue) { 1.147 + String s = options.get(optionName); 1.148 + try { 1.149 + if (s != null) return Integer.parseInt(s); 1.150 + } catch (NumberFormatException e) { 1.151 + // silently ignore ill-formed numbers 1.152 + } 1.153 + return defaultValue; 1.154 + } 1.155 + 1.156 + /** The default writer for diagnostics 1.157 + */ 1.158 + static final PrintWriter defaultWriter(Context context) { 1.159 + PrintWriter result = context.get(outKey); 1.160 + if (result == null) 1.161 + context.put(outKey, result = new PrintWriter(System.err)); 1.162 + return result; 1.163 + } 1.164 + 1.165 + /** Construct a log with default settings. 1.166 + */ 1.167 + protected Log(Context context) { 1.168 + this(context, defaultWriter(context)); 1.169 + } 1.170 + 1.171 + /** Construct a log with all output redirected. 1.172 + */ 1.173 + protected Log(Context context, PrintWriter defaultWriter) { 1.174 + this(context, defaultWriter, defaultWriter, defaultWriter); 1.175 + } 1.176 + 1.177 + /** Get the Log instance for this context. */ 1.178 + public static Log instance(Context context) { 1.179 + Log instance = context.get(logKey); 1.180 + if (instance == null) 1.181 + instance = new Log(context); 1.182 + return instance; 1.183 + } 1.184 + 1.185 + /** The file that's currently translated. 1.186 + */ 1.187 + protected JCDiagnostic.DiagnosticSource source; 1.188 + 1.189 + /** The number of errors encountered so far. 1.190 + */ 1.191 + public int nerrors = 0; 1.192 + 1.193 + /** The number of warnings encountered so far. 1.194 + */ 1.195 + public int nwarnings = 0; 1.196 + 1.197 + /** A set of all errors generated so far. This is used to avoid printing an 1.198 + * error message more than once. For each error, a pair consisting of the 1.199 + * source file name and source code position of the error is added to the set. 1.200 + */ 1.201 + private Set<Pair<JavaFileObject, Integer>> recorded = new HashSet<Pair<JavaFileObject,Integer>>(); 1.202 + 1.203 + private Map<JavaFileObject, Map<JCTree, Integer>> endPosTables; 1.204 + 1.205 + /** The buffer containing the file that's currently translated. 1.206 + */ 1.207 + private char[] buf = null; 1.208 + 1.209 + /** The position in the buffer at which last error was reported 1.210 + */ 1.211 + private int bp; 1.212 + 1.213 + /** number of the current source line; first line is 1 1.214 + */ 1.215 + private int line; 1.216 + 1.217 + /** buffer index of the first character of the current source line 1.218 + */ 1.219 + private int lineStart; 1.220 + 1.221 + public boolean hasDiagnosticListener() { 1.222 + return diagListener != null; 1.223 + } 1.224 + 1.225 + public void setEndPosTable(JavaFileObject name, Map<JCTree, Integer> table) { 1.226 + if (endPosTables == null) 1.227 + endPosTables = new HashMap<JavaFileObject, Map<JCTree, Integer>>(); 1.228 + endPosTables.put(name, table); 1.229 + } 1.230 + 1.231 + /** Re-assign source, returning previous setting. 1.232 + */ 1.233 + public JavaFileObject useSource(final JavaFileObject name) { 1.234 + JavaFileObject prev = currentSource(); 1.235 + if (name != prev) { 1.236 + source = new JCDiagnostic.DiagnosticSource() { 1.237 + public JavaFileObject getFile() { 1.238 + return name; 1.239 + } 1.240 + public CharSequence getName() { 1.241 + return JavacFileManager.getJavacBaseFileName(getFile()); 1.242 + } 1.243 + public int getLineNumber(int pos) { 1.244 + return Log.this.getLineNumber(pos); 1.245 + } 1.246 + public int getColumnNumber(int pos) { 1.247 + return Log.this.getColumnNumber(pos); 1.248 + } 1.249 + public Map<JCTree, Integer> getEndPosTable() { 1.250 + return (endPosTables == null ? null : endPosTables.get(name)); 1.251 + } 1.252 + }; 1.253 + buf = null; 1.254 + } 1.255 + return prev; 1.256 + } 1.257 + 1.258 + /** Re-assign source buffer for existing source name. 1.259 + */ 1.260 + protected void setBuf(char[] newBuf) { 1.261 + buf = newBuf; 1.262 + bp = 0; 1.263 + lineStart = 0; 1.264 + line = 1; 1.265 + } 1.266 + 1.267 + protected char[] getBuf() { 1.268 + return buf; 1.269 + } 1.270 + 1.271 + /** Return current source name. 1.272 + */ 1.273 + public JavaFileObject currentSource() { 1.274 + return source == null ? null : source.getFile(); 1.275 + } 1.276 + 1.277 + /** Flush the logs 1.278 + */ 1.279 + public void flush() { 1.280 + errWriter.flush(); 1.281 + warnWriter.flush(); 1.282 + noticeWriter.flush(); 1.283 + } 1.284 + 1.285 + /** Returns true if an error needs to be reported for a given 1.286 + * source name and pos. 1.287 + */ 1.288 + protected boolean shouldReport(JavaFileObject file, int pos) { 1.289 + if (multipleErrors || file == null) 1.290 + return true; 1.291 + 1.292 + Pair<JavaFileObject,Integer> coords = new Pair<JavaFileObject,Integer>(file, pos); 1.293 + boolean shouldReport = !recorded.contains(coords); 1.294 + if (shouldReport) 1.295 + recorded.add(coords); 1.296 + return shouldReport; 1.297 + } 1.298 + 1.299 + /** Prompt user after an error. 1.300 + */ 1.301 + public void prompt() { 1.302 + if (promptOnError) { 1.303 + System.err.println(getLocalizedString("resume.abort")); 1.304 + char ch; 1.305 + try { 1.306 + while (true) { 1.307 + switch (System.in.read()) { 1.308 + case 'a': case 'A': 1.309 + System.exit(-1); 1.310 + return; 1.311 + case 'r': case 'R': 1.312 + return; 1.313 + case 'x': case 'X': 1.314 + throw new AssertionError("user abort"); 1.315 + default: 1.316 + } 1.317 + } 1.318 + } catch (IOException e) {} 1.319 + } 1.320 + } 1.321 + 1.322 + /** Print the faulty source code line and point to the error. 1.323 + * @param pos Buffer index of the error position, must be on current line 1.324 + */ 1.325 + private void printErrLine(int pos, PrintWriter writer) { 1.326 + if (!findLine(pos)) 1.327 + return; 1.328 + 1.329 + int lineEnd = lineStart; 1.330 + while (lineEnd < buf.length && buf[lineEnd] != CR && buf[lineEnd] != LF) 1.331 + lineEnd++; 1.332 + if (lineEnd - lineStart == 0) 1.333 + return; 1.334 + printLines(writer, new String(buf, lineStart, lineEnd - lineStart)); 1.335 + for (bp = lineStart; bp < pos; bp++) { 1.336 + writer.print((buf[bp] == '\t') ? "\t" : " "); 1.337 + } 1.338 + writer.println("^"); 1.339 + writer.flush(); 1.340 + } 1.341 + 1.342 + protected static char[] getCharContent(JavaFileObject fileObject) throws IOException { 1.343 + CharSequence cs = fileObject.getCharContent(true); 1.344 + if (cs instanceof CharBuffer) { 1.345 + return JavacFileManager.toArray((CharBuffer)cs); 1.346 + } else { 1.347 + return cs.toString().toCharArray(); 1.348 + } 1.349 + } 1.350 + 1.351 + /** Find the line in the buffer that contains the current position 1.352 + * @param pos Character offset into the buffer 1.353 + */ 1.354 + private boolean findLine(int pos) { 1.355 + if (pos == Position.NOPOS || currentSource() == null) 1.356 + return false; 1.357 + try { 1.358 + if (buf == null) { 1.359 + buf = getCharContent(currentSource()); 1.360 + lineStart = 0; 1.361 + line = 1; 1.362 + } else if (lineStart > pos) { // messages don't come in order 1.363 + lineStart = 0; 1.364 + line = 1; 1.365 + } 1.366 + bp = lineStart; 1.367 + while (bp < buf.length && bp < pos) { 1.368 + switch (buf[bp++]) { 1.369 + case CR: 1.370 + if (bp < buf.length && buf[bp] == LF) bp++; 1.371 + line++; 1.372 + lineStart = bp; 1.373 + break; 1.374 + case LF: 1.375 + line++; 1.376 + lineStart = bp; 1.377 + break; 1.378 + } 1.379 + } 1.380 + return bp <= buf.length; 1.381 + } catch (IOException e) { 1.382 + //e.printStackTrace(); 1.383 + // FIXME: include e.getLocalizedMessage() in error message 1.384 + printLines(errWriter, getLocalizedString("source.unavailable")); 1.385 + errWriter.flush(); 1.386 + buf = new char[0]; 1.387 + } 1.388 + return false; 1.389 + } 1.390 + 1.391 + /** Print the text of a message, translating newlines appropriately 1.392 + * for the platform. 1.393 + */ 1.394 + public static void printLines(PrintWriter writer, String msg) { 1.395 + int nl; 1.396 + while ((nl = msg.indexOf('\n')) != -1) { 1.397 + writer.println(msg.substring(0, nl)); 1.398 + msg = msg.substring(nl+1); 1.399 + } 1.400 + if (msg.length() != 0) writer.println(msg); 1.401 + } 1.402 + 1.403 + /** Report an error, unless another error was already reported at same 1.404 + * source position. 1.405 + * @param key The key for the localized error message. 1.406 + * @param args Fields of the error message. 1.407 + */ 1.408 + public void error(String key, Object ... args) { 1.409 + report(diags.error(source, null, key, args)); 1.410 + } 1.411 + 1.412 + /** Report an error, unless another error was already reported at same 1.413 + * source position. 1.414 + * @param pos The source position at which to report the error. 1.415 + * @param key The key for the localized error message. 1.416 + * @param args Fields of the error message. 1.417 + */ 1.418 + public void error(DiagnosticPosition pos, String key, Object ... args) { 1.419 + report(diags.error(source, pos, key, args)); 1.420 + } 1.421 + 1.422 + /** Report an error, unless another error was already reported at same 1.423 + * source position. 1.424 + * @param pos The source position at which to report the error. 1.425 + * @param key The key for the localized error message. 1.426 + * @param args Fields of the error message. 1.427 + */ 1.428 + public void error(int pos, String key, Object ... args) { 1.429 + report(diags.error(source, wrap(pos), key, args)); 1.430 + } 1.431 + 1.432 + /** Report a warning, unless suppressed by the -nowarn option or the 1.433 + * maximum number of warnings has been reached. 1.434 + * @param pos The source position at which to report the warning. 1.435 + * @param key The key for the localized warning message. 1.436 + * @param args Fields of the warning message. 1.437 + */ 1.438 + public void warning(String key, Object ... args) { 1.439 + report(diags.warning(source, null, key, args)); 1.440 + } 1.441 + 1.442 + /** Report a warning, unless suppressed by the -nowarn option or the 1.443 + * maximum number of warnings has been reached. 1.444 + * @param pos The source position at which to report the warning. 1.445 + * @param key The key for the localized warning message. 1.446 + * @param args Fields of the warning message. 1.447 + */ 1.448 + public void warning(DiagnosticPosition pos, String key, Object ... args) { 1.449 + report(diags.warning(source, pos, key, args)); 1.450 + } 1.451 + 1.452 + /** Report a warning, unless suppressed by the -nowarn option or the 1.453 + * maximum number of warnings has been reached. 1.454 + * @param pos The source position at which to report the warning. 1.455 + * @param key The key for the localized warning message. 1.456 + * @param args Fields of the warning message. 1.457 + */ 1.458 + public void warning(int pos, String key, Object ... args) { 1.459 + report(diags.warning(source, wrap(pos), key, args)); 1.460 + } 1.461 + 1.462 + /** Report a warning. 1.463 + * @param pos The source position at which to report the warning. 1.464 + * @param key The key for the localized warning message. 1.465 + * @param args Fields of the warning message. 1.466 + */ 1.467 + public void mandatoryWarning(DiagnosticPosition pos, String key, Object ... args) { 1.468 + if (enforceMandatoryWarnings) 1.469 + report(diags.mandatoryWarning(source, pos, key, args)); 1.470 + else 1.471 + report(diags.warning(source, pos, key, args)); 1.472 + } 1.473 + 1.474 + /** Report a warning that cannot be suppressed. 1.475 + * @param pos The source position at which to report the warning. 1.476 + * @param key The key for the localized warning message. 1.477 + * @param args Fields of the warning message. 1.478 + */ 1.479 + public void strictWarning(DiagnosticPosition pos, String key, Object ... args) { 1.480 + writeDiagnostic(diags.warning(source, pos, key, args)); 1.481 + nwarnings++; 1.482 + } 1.483 + 1.484 + /** Provide a non-fatal notification, unless suppressed by the -nowarn option. 1.485 + * @param key The key for the localized notification message. 1.486 + * @param args Fields of the notification message. 1.487 + */ 1.488 + public void note(String key, Object ... args) { 1.489 + report(diags.note(source, null, key, args)); 1.490 + } 1.491 + 1.492 + /** Provide a non-fatal notification, unless suppressed by the -nowarn option. 1.493 + * @param key The key for the localized notification message. 1.494 + * @param args Fields of the notification message. 1.495 + */ 1.496 + public void note(DiagnosticPosition pos, String key, Object ... args) { 1.497 + report(diags.note(source, pos, key, args)); 1.498 + } 1.499 + 1.500 + /** Provide a non-fatal notification, unless suppressed by the -nowarn option. 1.501 + * @param key The key for the localized notification message. 1.502 + * @param args Fields of the notification message. 1.503 + */ 1.504 + public void note(int pos, String key, Object ... args) { 1.505 + report(diags.note(source, wrap(pos), key, args)); 1.506 + } 1.507 + 1.508 + /** Provide a non-fatal notification, unless suppressed by the -nowarn option. 1.509 + * @param key The key for the localized notification message. 1.510 + * @param args Fields of the notification message. 1.511 + */ 1.512 + public void mandatoryNote(final JavaFileObject file, String key, Object ... args) { 1.513 + JCDiagnostic.DiagnosticSource wrapper = null; 1.514 + if (file != null) { 1.515 + wrapper = new JCDiagnostic.DiagnosticSource() { 1.516 + public JavaFileObject getFile() { 1.517 + return file; 1.518 + } 1.519 + public CharSequence getName() { 1.520 + return JavacFileManager.getJavacBaseFileName(getFile()); 1.521 + } 1.522 + public int getLineNumber(int pos) { 1.523 + return Log.this.getLineNumber(pos); 1.524 + } 1.525 + public int getColumnNumber(int pos) { 1.526 + return Log.this.getColumnNumber(pos); 1.527 + } 1.528 + public Map<JCTree, Integer> getEndPosTable() { 1.529 + return (endPosTables == null ? null : endPosTables.get(file)); 1.530 + } 1.531 + }; 1.532 + } 1.533 + if (enforceMandatoryWarnings) 1.534 + report(diags.mandatoryNote(wrapper, key, args)); 1.535 + else 1.536 + report(diags.note(wrapper, null, key, args)); 1.537 + } 1.538 + 1.539 + private DiagnosticPosition wrap(int pos) { 1.540 + return (pos == Position.NOPOS ? null : new SimpleDiagnosticPosition(pos)); 1.541 + } 1.542 + 1.543 + /** 1.544 + * Common diagnostic handling. 1.545 + * The diagnostic is counted, and depending on the options and how many diagnostics have been 1.546 + * reported so far, the diagnostic may be handed off to writeDiagnostic. 1.547 + */ 1.548 + public void report(JCDiagnostic diagnostic) { 1.549 + switch (diagnostic.getType()) { 1.550 + case FRAGMENT: 1.551 + throw new IllegalArgumentException(); 1.552 + 1.553 + case NOTE: 1.554 + // Print out notes only when we are permitted to report warnings 1.555 + // Notes are only generated at the end of a compilation, so should be small 1.556 + // in number. 1.557 + if (emitWarnings || diagnostic.isMandatory()) { 1.558 + writeDiagnostic(diagnostic); 1.559 + } 1.560 + break; 1.561 + 1.562 + case WARNING: 1.563 + if (emitWarnings || diagnostic.isMandatory()) { 1.564 + if (nwarnings < MaxWarnings) { 1.565 + writeDiagnostic(diagnostic); 1.566 + nwarnings++; 1.567 + } 1.568 + } 1.569 + break; 1.570 + 1.571 + case ERROR: 1.572 + if (nerrors < MaxErrors 1.573 + && shouldReport(diagnostic.getSource(), diagnostic.getIntPosition())) { 1.574 + writeDiagnostic(diagnostic); 1.575 + nerrors++; 1.576 + } 1.577 + break; 1.578 + } 1.579 + } 1.580 + 1.581 + /** 1.582 + * Write out a diagnostic. 1.583 + */ 1.584 + protected void writeDiagnostic(JCDiagnostic diag) { 1.585 + if (diagListener != null) { 1.586 + try { 1.587 + diagListener.report(diag); 1.588 + return; 1.589 + } 1.590 + catch (Throwable t) { 1.591 + throw new ClientCodeException(t); 1.592 + } 1.593 + } 1.594 + 1.595 + PrintWriter writer = getWriterForDiagnosticType(diag.getType()); 1.596 + 1.597 + printLines(writer, diagFormatter.format(diag)); 1.598 + if (showSourceLine) { 1.599 + int pos = diag.getIntPosition(); 1.600 + if (pos != Position.NOPOS) { 1.601 + JavaFileObject prev = useSource(diag.getSource()); 1.602 + printErrLine(pos, writer); 1.603 + useSource(prev); 1.604 + } 1.605 + } 1.606 + 1.607 + if (promptOnError) { 1.608 + switch (diag.getType()) { 1.609 + case ERROR: 1.610 + case WARNING: 1.611 + prompt(); 1.612 + } 1.613 + } 1.614 + 1.615 + if (dumpOnError) 1.616 + new RuntimeException().printStackTrace(writer); 1.617 + 1.618 + writer.flush(); 1.619 + } 1.620 + 1.621 + @Deprecated 1.622 + protected PrintWriter getWriterForDiagnosticType(DiagnosticType dt) { 1.623 + switch (dt) { 1.624 + case FRAGMENT: 1.625 + throw new IllegalArgumentException(); 1.626 + 1.627 + case NOTE: 1.628 + return noticeWriter; 1.629 + 1.630 + case WARNING: 1.631 + return warnWriter; 1.632 + 1.633 + case ERROR: 1.634 + return errWriter; 1.635 + 1.636 + default: 1.637 + throw new Error(); 1.638 + } 1.639 + } 1.640 + 1.641 + /** Find a localized string in the resource bundle. 1.642 + * @param key The key for the localized string. 1.643 + * @param args Fields to substitute into the string. 1.644 + */ 1.645 + public static String getLocalizedString(String key, Object ... args) { 1.646 + return Messages.getDefaultLocalizedString("compiler.misc." + key, args); 1.647 + } 1.648 + 1.649 +/*************************************************************************** 1.650 + * raw error messages without internationalization; used for experimentation 1.651 + * and quick prototyping 1.652 + ***************************************************************************/ 1.653 + 1.654 +/** print an error or warning message: 1.655 + */ 1.656 + private void printRawError(int pos, String msg) { 1.657 + if (!findLine(pos)) { 1.658 + printLines(errWriter, "error: " + msg); 1.659 + } else { 1.660 + JavaFileObject file = currentSource(); 1.661 + if (file != null) 1.662 + printLines(errWriter, 1.663 + JavacFileManager.getJavacFileName(file) + ":" + 1.664 + line + ": " + msg); 1.665 + printErrLine(pos, errWriter); 1.666 + } 1.667 + errWriter.flush(); 1.668 + } 1.669 + 1.670 +/** report an error: 1.671 + */ 1.672 + public void rawError(int pos, String msg) { 1.673 + if (nerrors < MaxErrors && shouldReport(currentSource(), pos)) { 1.674 + printRawError(pos, msg); 1.675 + prompt(); 1.676 + nerrors++; 1.677 + } 1.678 + errWriter.flush(); 1.679 + } 1.680 + 1.681 +/** report a warning: 1.682 + */ 1.683 + public void rawWarning(int pos, String msg) { 1.684 + if (nwarnings < MaxWarnings && emitWarnings) { 1.685 + printRawError(pos, "warning: " + msg); 1.686 + } 1.687 + prompt(); 1.688 + nwarnings++; 1.689 + errWriter.flush(); 1.690 + } 1.691 + 1.692 + /** Return the one-based line number associated with a given pos 1.693 + * for the current source file. Zero is returned if no line exists 1.694 + * for the given position. 1.695 + */ 1.696 + protected int getLineNumber(int pos) { 1.697 + if (findLine(pos)) 1.698 + return line; 1.699 + return 0; 1.700 + } 1.701 + 1.702 + /** Return the one-based column number associated with a given pos 1.703 + * for the current source file. Zero is returned if no column exists 1.704 + * for the given position. 1.705 + */ 1.706 + protected int getColumnNumber(int pos) { 1.707 + if (findLine(pos)) { 1.708 + int column = 0; 1.709 + for (bp = lineStart; bp < pos; bp++) { 1.710 + if (bp >= buf.length) 1.711 + return 0; 1.712 + if (buf[bp] == '\t') 1.713 + column = (column / TabInc * TabInc) + TabInc; 1.714 + else 1.715 + column++; 1.716 + } 1.717 + return column + 1; // positions are one-based 1.718 + } 1.719 + return 0; 1.720 + } 1.721 + 1.722 + public static String format(String fmt, Object... args) { 1.723 + return String.format((java.util.Locale)null, fmt, args); 1.724 + } 1.725 + 1.726 +}