langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java
changeset 40232 4995ab1a4558
parent 32799 ee577901f4bb
child 40308 274367a99f98
equal deleted inserted replaced
40231:ba38ad2dd137 40232:4995ab1a4558
     1 /*
     1 /*
     2  * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    25 
    25 
    26 package com.sun.tools.javac.util;
    26 package com.sun.tools.javac.util;
    27 
    27 
    28 import java.io.*;
    28 import java.io.*;
    29 import java.util.Arrays;
    29 import java.util.Arrays;
       
    30 import java.util.EnumMap;
    30 import java.util.EnumSet;
    31 import java.util.EnumSet;
    31 import java.util.HashSet;
    32 import java.util.HashSet;
       
    33 import java.util.Map;
    32 import java.util.Queue;
    34 import java.util.Queue;
    33 import java.util.Set;
    35 import java.util.Set;
       
    36 
    34 import javax.tools.DiagnosticListener;
    37 import javax.tools.DiagnosticListener;
    35 import javax.tools.JavaFileObject;
    38 import javax.tools.JavaFileObject;
    36 
    39 
    37 import com.sun.tools.javac.api.DiagnosticFormatter;
    40 import com.sun.tools.javac.api.DiagnosticFormatter;
    38 import com.sun.tools.javac.main.Main;
    41 import com.sun.tools.javac.main.Main;
    54  */
    57  */
    55 public class Log extends AbstractLog {
    58 public class Log extends AbstractLog {
    56     /** The context key for the log. */
    59     /** The context key for the log. */
    57     public static final Context.Key<Log> logKey = new Context.Key<>();
    60     public static final Context.Key<Log> logKey = new Context.Key<>();
    58 
    61 
    59     /** The context key for the output PrintWriter. */
    62     /** The context key for the standard output PrintWriter. */
    60     public static final Context.Key<PrintWriter> outKey = new Context.Key<>();
    63     public static final Context.Key<PrintWriter> outKey = new Context.Key<>();
       
    64 
       
    65     /** The context key for the diagnostic PrintWriter. */
       
    66     public static final Context.Key<PrintWriter> errKey = new Context.Key<>();
    61 
    67 
    62     /* TODO: Should unify this with prefix handling in JCDiagnostic.Factory. */
    68     /* TODO: Should unify this with prefix handling in JCDiagnostic.Factory. */
    63     public enum PrefixKind {
    69     public enum PrefixKind {
    64         JAVAC("javac."),
    70         JAVAC("javac."),
    65         COMPILER_MISC("compiler.misc.");
    71         COMPILER_MISC("compiler.misc.");
   109     public static class DiscardDiagnosticHandler extends DiagnosticHandler {
   115     public static class DiscardDiagnosticHandler extends DiagnosticHandler {
   110         public DiscardDiagnosticHandler(Log log) {
   116         public DiscardDiagnosticHandler(Log log) {
   111             install(log);
   117             install(log);
   112         }
   118         }
   113 
   119 
       
   120         @Override
   114         public void report(JCDiagnostic diag) { }
   121         public void report(JCDiagnostic diag) { }
   115     }
   122     }
   116 
   123 
   117     /**
   124     /**
   118      * A DiagnosticHandler that can defer some or all diagnostics,
   125      * A DiagnosticHandler that can defer some or all diagnostics,
   132         public DeferredDiagnosticHandler(Log log, Filter<JCDiagnostic> filter) {
   139         public DeferredDiagnosticHandler(Log log, Filter<JCDiagnostic> filter) {
   133             this.filter = filter;
   140             this.filter = filter;
   134             install(log);
   141             install(log);
   135         }
   142         }
   136 
   143 
       
   144         @Override
   137         public void report(JCDiagnostic diag) {
   145         public void report(JCDiagnostic diag) {
   138             if (!diag.isFlagSet(JCDiagnostic.DiagnosticFlag.NON_DEFERRABLE) &&
   146             if (!diag.isFlagSet(JCDiagnostic.DiagnosticFlag.NON_DEFERRABLE) &&
   139                 (filter == null || filter.accepts(diag))) {
   147                 (filter == null || filter.accepts(diag))) {
   140                 deferred.add(diag);
   148                 deferred.add(diag);
   141             } else {
   149             } else {
   161             }
   169             }
   162             deferred = null; // prevent accidental ongoing use
   170             deferred = null; // prevent accidental ongoing use
   163         }
   171         }
   164     }
   172     }
   165 
   173 
   166     public enum WriterKind { NOTICE, WARNING, ERROR }
   174     public enum WriterKind { NOTICE, WARNING, ERROR, STDOUT, STDERR }
   167 
   175 
   168     protected PrintWriter errWriter;
   176     private final Map<WriterKind, PrintWriter> writers;
   169 
       
   170     protected PrintWriter warnWriter;
       
   171 
       
   172     protected PrintWriter noticeWriter;
       
   173 
   177 
   174     /** The maximum number of errors/warnings that are reported.
   178     /** The maximum number of errors/warnings that are reported.
   175      */
   179      */
   176     protected int MaxErrors;
   180     protected int MaxErrors;
   177     protected int MaxWarnings;
   181     protected int MaxWarnings;
   221     /**
   225     /**
   222      * Handler for initial dispatch of diagnostics.
   226      * Handler for initial dispatch of diagnostics.
   223      */
   227      */
   224     private DiagnosticHandler diagnosticHandler;
   228     private DiagnosticHandler diagnosticHandler;
   225 
   229 
   226     /** Construct a log with given I/O redirections.
   230     /** Get the Log instance for this context. */
   227      */
   231     public static Log instance(Context context) {
       
   232         Log instance = context.get(logKey);
       
   233         if (instance == null)
       
   234             instance = new Log(context);
       
   235         return instance;
       
   236     }
       
   237 
       
   238     /**
       
   239      * Register a Context.Factory to create a Log.
       
   240      */
       
   241     public static void preRegister(Context context, PrintWriter w) {
       
   242         context.put(Log.class, (Context.Factory<Log>) (c -> new Log(c, w)));
       
   243     }
       
   244 
       
   245     /**
       
   246      * Construct a log with default settings.
       
   247      * If no streams are set in the context, the log will be initialized to use
       
   248      * System.out for normal output, and System.err for all diagnostic output.
       
   249      * If one stream is set in the context, with either Log.outKey or Log.errKey,
       
   250      * it will be used for all output.
       
   251      * Otherwise, the log will be initialized to use both streams found in the context.
       
   252      */
       
   253     protected Log(Context context) {
       
   254         this(context, initWriters(context));
       
   255     }
       
   256 
       
   257     /**
       
   258      * Initialize a map of writers based on values found in the context
       
   259      * @param context the context in which to find writers to use
       
   260      * @return a map of writers
       
   261      */
       
   262     private static Map<WriterKind, PrintWriter> initWriters(Context context) {
       
   263         PrintWriter out = context.get(outKey);
       
   264         PrintWriter err = context.get(errKey);
       
   265         if (out == null && err == null) {
       
   266             out = new PrintWriter(System.out, true);
       
   267             err = new PrintWriter(System.err, true);
       
   268             return initWriters(out, err);
       
   269         } else if (out == null || err == null) {
       
   270             PrintWriter pw = (out != null) ? out : err;
       
   271             return initWriters(pw, pw);
       
   272         } else {
       
   273             return initWriters(out, err);
       
   274         }
       
   275     }
       
   276 
       
   277     /**
       
   278      * Construct a log with all output sent to a single output stream.
       
   279      */
       
   280     protected Log(Context context, PrintWriter writer) {
       
   281         this(context, initWriters(writer, writer));
       
   282     }
       
   283 
       
   284     /**
       
   285      * Construct a log.
       
   286      * The log will be initialized to use stdOut for normal output, and stdErr
       
   287      * for all diagnostic output.
       
   288      */
       
   289     protected Log(Context context, PrintWriter out, PrintWriter err) {
       
   290         this(context, initWriters(out, err));
       
   291     }
       
   292 
       
   293     /**
       
   294      * Initialize a writer map for a stream for normal output, and a stream for diagnostics.
       
   295      * @param out a stream to be used for normal output
       
   296      * @param err a stream to be used for diagnostic messages, such as errors, warnings, etc
       
   297      * @return a map of writers
       
   298      */
       
   299     private static Map<WriterKind, PrintWriter> initWriters(PrintWriter out, PrintWriter err) {
       
   300         Map<WriterKind, PrintWriter> writers = new EnumMap<>(WriterKind.class);
       
   301         writers.put(WriterKind.ERROR, err);
       
   302         writers.put(WriterKind.WARNING, err);
       
   303         writers.put(WriterKind.NOTICE, err);
       
   304 
       
   305         writers.put(WriterKind.STDOUT, out);
       
   306         writers.put(WriterKind.STDERR, err);
       
   307 
       
   308         return writers;
       
   309     }
       
   310 
       
   311     /**
       
   312      * Construct a log with given I/O redirections.
       
   313      * @deprecated
       
   314      * This constructor is provided to support the supported but now-deprecated javadoc entry point
       
   315      *      com.sun.tools.javadoc.Main.execute(String programName,
       
   316      *          PrintWriter errWriter, PrintWriter warnWriter, PrintWriter noticeWriter,
       
   317      *          String defaultDocletClassName, String... args)
       
   318      */
       
   319     @Deprecated
   228     protected Log(Context context, PrintWriter errWriter, PrintWriter warnWriter, PrintWriter noticeWriter) {
   320     protected Log(Context context, PrintWriter errWriter, PrintWriter warnWriter, PrintWriter noticeWriter) {
       
   321         this(context, initWriters(errWriter, warnWriter, noticeWriter));
       
   322     }
       
   323 
       
   324     /**
       
   325      * Initialize a writer map with different streams for different types of diagnostics.
       
   326      * @param errWriter a stream for writing error messages
       
   327      * @param warnWriter a stream for writing warning messages
       
   328      * @param noticeWriter a stream for writing notice messages
       
   329      * @return a map of writers
       
   330      * @deprecated This method exists to support a supported but now deprecated javadoc entry point.
       
   331      */
       
   332     @Deprecated
       
   333     private static Map<WriterKind, PrintWriter>  initWriters(PrintWriter errWriter, PrintWriter warnWriter, PrintWriter noticeWriter) {
       
   334         Map<WriterKind, PrintWriter> writers = new EnumMap<>(WriterKind.class);
       
   335         writers.put(WriterKind.ERROR, errWriter);
       
   336         writers.put(WriterKind.WARNING, warnWriter);
       
   337         writers.put(WriterKind.NOTICE, noticeWriter);
       
   338 
       
   339         writers.put(WriterKind.STDOUT, noticeWriter);
       
   340         writers.put(WriterKind.STDERR, errWriter);
       
   341 
       
   342         return writers;
       
   343     }
       
   344 
       
   345     /**
       
   346      * Creates a log.
       
   347      * @param context the context in which the log should be registered
       
   348      * @param writers a map of writers that can be accessed by the kind of writer required
       
   349      */
       
   350     private Log(Context context, Map<WriterKind, PrintWriter> writers) {
   229         super(JCDiagnostic.Factory.instance(context));
   351         super(JCDiagnostic.Factory.instance(context));
   230         context.put(logKey, this);
   352         context.put(logKey, this);
   231         this.errWriter = errWriter;
   353         this.writers = writers;
   232         this.warnWriter = warnWriter;
       
   233         this.noticeWriter = noticeWriter;
       
   234 
   354 
   235         @SuppressWarnings("unchecked") // FIXME
   355         @SuppressWarnings("unchecked") // FIXME
   236         DiagnosticListener<? super JavaFileObject> dl =
   356         DiagnosticListener<? super JavaFileObject> dl =
   237             context.get(DiagnosticListener.class);
   357             context.get(DiagnosticListener.class);
   238         this.diagListener = dl;
   358         this.diagListener = dl;
   243         messages.add(Main.javacBundleName);
   363         messages.add(Main.javacBundleName);
   244 
   364 
   245         final Options options = Options.instance(context);
   365         final Options options = Options.instance(context);
   246         initOptions(options);
   366         initOptions(options);
   247         options.addListener(new Runnable() {
   367         options.addListener(new Runnable() {
       
   368             @Override
   248             public void run() {
   369             public void run() {
   249                 initOptions(options);
   370                 initOptions(options);
   250             }
   371             }
   251         });
   372         });
   252     }
   373     }
   291          */
   412          */
   292         protected int getDefaultMaxWarnings() {
   413         protected int getDefaultMaxWarnings() {
   293             return 100;
   414             return 100;
   294         }
   415         }
   295 
   416 
   296     /** The default writer for diagnostics
       
   297      */
       
   298     static PrintWriter defaultWriter(Context context) {
       
   299         PrintWriter result = context.get(outKey);
       
   300         if (result == null)
       
   301             context.put(outKey, result = new PrintWriter(System.err));
       
   302         return result;
       
   303     }
       
   304 
       
   305     /** Construct a log with default settings.
       
   306      */
       
   307     protected Log(Context context) {
       
   308         this(context, defaultWriter(context));
       
   309     }
       
   310 
       
   311     /** Construct a log with all output redirected.
       
   312      */
       
   313     protected Log(Context context, PrintWriter defaultWriter) {
       
   314         this(context, defaultWriter, defaultWriter, defaultWriter);
       
   315     }
       
   316 
       
   317     /** Get the Log instance for this context. */
       
   318     public static Log instance(Context context) {
       
   319         Log instance = context.get(logKey);
       
   320         if (instance == null)
       
   321             instance = new Log(context);
       
   322         return instance;
       
   323     }
       
   324 
       
   325     /**
       
   326      * Register a Context.Factory to create a Log.
       
   327      */
       
   328     public static void preRegister(Context context, PrintWriter w) {
       
   329         context.put(Log.class, (Context.Factory<Log>) (c -> new Log(c, w)));
       
   330     }
       
   331 
       
   332     /** The number of errors encountered so far.
   417     /** The number of errors encountered so far.
   333      */
   418      */
   334     public int nerrors = 0;
   419     public int nerrors = 0;
   335 
   420 
   336     /** The number of warnings encountered so far.
   421     /** The number of warnings encountered so far.
   369     public void setDiagnosticFormatter(DiagnosticFormatter<JCDiagnostic> diagFormatter) {
   454     public void setDiagnosticFormatter(DiagnosticFormatter<JCDiagnostic> diagFormatter) {
   370         this.diagFormatter = diagFormatter;
   455         this.diagFormatter = diagFormatter;
   371     }
   456     }
   372 
   457 
   373     public PrintWriter getWriter(WriterKind kind) {
   458     public PrintWriter getWriter(WriterKind kind) {
   374         switch (kind) {
   459         return writers.get(kind);
   375             case NOTICE:    return noticeWriter;
       
   376             case WARNING:   return warnWriter;
       
   377             case ERROR:     return errWriter;
       
   378             default:        throw new IllegalArgumentException();
       
   379         }
       
   380     }
   460     }
   381 
   461 
   382     public void setWriter(WriterKind kind, PrintWriter pw) {
   462     public void setWriter(WriterKind kind, PrintWriter pw) {
   383         Assert.checkNonNull(pw);
   463         Assert.checkNonNull(pw);
   384         switch (kind) {
   464         writers.put(kind, pw);
   385             case NOTICE:    noticeWriter = pw;  break;
       
   386             case WARNING:   warnWriter = pw;    break;
       
   387             case ERROR:     errWriter = pw;     break;
       
   388             default:        throw new IllegalArgumentException();
       
   389         }
       
   390     }
   465     }
   391 
   466 
   392     public void setWriters(PrintWriter pw) {
   467     public void setWriters(PrintWriter pw) {
   393         noticeWriter = warnWriter = errWriter = Assert.checkNonNull(pw);
   468         Assert.checkNonNull(pw);
       
   469         for (WriterKind k: WriterKind.values())
       
   470             writers.put(k, pw);
   394     }
   471     }
   395 
   472 
   396     /**
   473     /**
   397      * Replace the specified diagnostic handler with the
   474      * Replace the specified diagnostic handler with the
   398      * handler that was current at the time this handler was created.
   475      * handler that was current at the time this handler was created.
   405     }
   482     }
   406 
   483 
   407     /** Flush the logs
   484     /** Flush the logs
   408      */
   485      */
   409     public void flush() {
   486     public void flush() {
   410         errWriter.flush();
   487         for (PrintWriter pw: writers.values()) {
   411         warnWriter.flush();
   488             pw.flush();
   412         noticeWriter.flush();
   489         }
   413     }
   490     }
   414 
   491 
   415     public void flush(WriterKind kind) {
   492     public void flush(WriterKind kind) {
   416         getWriter(kind).flush();
   493         getWriter(kind).flush();
   417     }
   494     }
   468         writer.println("^");
   545         writer.println("^");
   469         writer.flush();
   546         writer.flush();
   470     }
   547     }
   471 
   548 
   472     public void printNewline() {
   549     public void printNewline() {
       
   550         PrintWriter noticeWriter = writers.get(WriterKind.NOTICE);
   473         noticeWriter.println();
   551         noticeWriter.println();
   474     }
   552     }
   475 
   553 
   476     public void printNewline(WriterKind wk) {
   554     public void printNewline(WriterKind wk) {
   477         getWriter(wk).println();
   555         getWriter(wk).println();
   478     }
   556     }
   479 
   557 
   480     public void printLines(String key, Object... args) {
   558     public void printLines(String key, Object... args) {
       
   559         PrintWriter noticeWriter = writers.get(WriterKind.NOTICE);
   481         printRawLines(noticeWriter, localize(key, args));
   560         printRawLines(noticeWriter, localize(key, args));
   482     }
   561     }
   483 
   562 
   484     public void printLines(PrefixKind pk, String key, Object... args) {
   563     public void printLines(PrefixKind pk, String key, Object... args) {
       
   564         PrintWriter noticeWriter = writers.get(WriterKind.NOTICE);
   485         printRawLines(noticeWriter, localize(pk, key, args));
   565         printRawLines(noticeWriter, localize(pk, key, args));
   486     }
   566     }
   487 
   567 
   488     public void printLines(WriterKind wk, String key, Object... args) {
   568     public void printLines(WriterKind wk, String key, Object... args) {
   489         printRawLines(getWriter(wk), localize(key, args));
   569         printRawLines(getWriter(wk), localize(key, args));
   495 
   575 
   496     /** Print the text of a message, translating newlines appropriately
   576     /** Print the text of a message, translating newlines appropriately
   497      *  for the platform.
   577      *  for the platform.
   498      */
   578      */
   499     public void printRawLines(String msg) {
   579     public void printRawLines(String msg) {
       
   580         PrintWriter noticeWriter = writers.get(WriterKind.NOTICE);
   500         printRawLines(noticeWriter, msg);
   581         printRawLines(noticeWriter, msg);
   501     }
   582     }
   502 
   583 
   503     /** Print the text of a message, translating newlines appropriately
   584     /** Print the text of a message, translating newlines appropriately
   504      *  for the platform.
   585      *  for the platform.
   522     /**
   603     /**
   523      * Print the localized text of a "verbose" message to the
   604      * Print the localized text of a "verbose" message to the
   524      * noticeWriter stream.
   605      * noticeWriter stream.
   525      */
   606      */
   526     public void printVerbose(String key, Object... args) {
   607     public void printVerbose(String key, Object... args) {
       
   608         PrintWriter noticeWriter = writers.get(WriterKind.NOTICE);
   527         printRawLines(noticeWriter, localize("verbose." + key, args));
   609         printRawLines(noticeWriter, localize("verbose." + key, args));
   528     }
   610     }
   529 
   611 
       
   612     @Override
   530     protected void directError(String key, Object... args) {
   613     protected void directError(String key, Object... args) {
       
   614         PrintWriter errWriter = writers.get(WriterKind.ERROR);
   531         printRawLines(errWriter, localize(key, args));
   615         printRawLines(errWriter, localize(key, args));
   532         errWriter.flush();
   616         errWriter.flush();
   533     }
   617     }
   534 
   618 
   535     /** Report a warning that cannot be suppressed.
   619     /** Report a warning that cannot be suppressed.
   544 
   628 
   545     /**
   629     /**
   546      * Primary method to report a diagnostic.
   630      * Primary method to report a diagnostic.
   547      * @param diagnostic
   631      * @param diagnostic
   548      */
   632      */
       
   633     @Override
   549     public void report(JCDiagnostic diagnostic) {
   634     public void report(JCDiagnostic diagnostic) {
   550         diagnosticHandler.report(diagnostic);
   635         diagnosticHandler.report(diagnostic);
   551      }
   636      }
   552 
   637 
   553     /**
   638     /**
   554      * Common diagnostic handling.
   639      * Common diagnostic handling.
   555      * The diagnostic is counted, and depending on the options and how many diagnostics have been
   640      * The diagnostic is counted, and depending on the options and how many diagnostics have been
   556      * reported so far, the diagnostic may be handed off to writeDiagnostic.
   641      * reported so far, the diagnostic may be handed off to writeDiagnostic.
   557      */
   642      */
   558     private class DefaultDiagnosticHandler extends DiagnosticHandler {
   643     private class DefaultDiagnosticHandler extends DiagnosticHandler {
       
   644         @Override
   559         public void report(JCDiagnostic diagnostic) {
   645         public void report(JCDiagnostic diagnostic) {
   560             if (expectDiagKeys != null)
   646             if (expectDiagKeys != null)
   561                 expectDiagKeys.remove(diagnostic.getCode());
   647                 expectDiagKeys.remove(diagnostic.getCode());
   562 
   648 
   563             switch (diagnostic.getType()) {
   649             switch (diagnostic.getType()) {
   629         switch (dt) {
   715         switch (dt) {
   630         case FRAGMENT:
   716         case FRAGMENT:
   631             throw new IllegalArgumentException();
   717             throw new IllegalArgumentException();
   632 
   718 
   633         case NOTE:
   719         case NOTE:
   634             return noticeWriter;
   720             return writers.get(WriterKind.NOTICE);
   635 
   721 
   636         case WARNING:
   722         case WARNING:
   637             return warnWriter;
   723             return writers.get(WriterKind.WARNING);
   638 
   724 
   639         case ERROR:
   725         case ERROR:
   640             return errWriter;
   726             return writers.get(WriterKind.ERROR);
   641 
   727 
   642         default:
   728         default:
   643             throw new Error();
   729             throw new Error();
   644         }
   730         }
   645     }
   731     }
   681  * and quick prototyping
   767  * and quick prototyping
   682  ***************************************************************************/
   768  ***************************************************************************/
   683 
   769 
   684     /** print an error or warning message:
   770     /** print an error or warning message:
   685      */
   771      */
   686     private void printRawError(int pos, String msg) {
   772     private void printRawDiag(PrintWriter pw, String prefix, int pos, String msg) {
   687         if (source == null || pos == Position.NOPOS) {
   773         if (source == null || pos == Position.NOPOS) {
   688             printRawLines(errWriter, "error: " + msg);
   774             printRawLines(pw, prefix + msg);
   689         } else {
   775         } else {
   690             int line = source.getLineNumber(pos);
   776             int line = source.getLineNumber(pos);
   691             JavaFileObject file = source.getFile();
   777             JavaFileObject file = source.getFile();
   692             if (file != null)
   778             if (file != null)
   693                 printRawLines(errWriter,
   779                 printRawLines(pw,
   694                            file.getName() + ":" +
   780                            file.getName() + ":" +
   695                            line + ": " + msg);
   781                            line + ": " + msg);
   696             printErrLine(pos, errWriter);
   782             printErrLine(pos, pw);
   697         }
   783         }
   698         errWriter.flush();
   784         pw.flush();
   699     }
   785     }
   700 
   786 
   701     /** report an error:
   787     /** report an error:
   702      */
   788      */
   703     public void rawError(int pos, String msg) {
   789     public void rawError(int pos, String msg) {
       
   790         PrintWriter errWriter = writers.get(WriterKind.ERROR);
   704         if (nerrors < MaxErrors && shouldReport(currentSourceFile(), pos)) {
   791         if (nerrors < MaxErrors && shouldReport(currentSourceFile(), pos)) {
   705             printRawError(pos, msg);
   792             printRawDiag(errWriter, "error: ", pos, msg);
   706             prompt();
   793             prompt();
   707             nerrors++;
   794             nerrors++;
   708         }
   795         }
   709         errWriter.flush();
   796         errWriter.flush();
   710     }
   797     }
   711 
   798 
   712     /** report a warning:
   799     /** report a warning:
   713      */
   800      */
   714     public void rawWarning(int pos, String msg) {
   801     public void rawWarning(int pos, String msg) {
       
   802         PrintWriter warnWriter = writers.get(WriterKind.ERROR);
   715         if (nwarnings < MaxWarnings && emitWarnings) {
   803         if (nwarnings < MaxWarnings && emitWarnings) {
   716             printRawError(pos, "warning: " + msg);
   804             printRawDiag(warnWriter, "warning: ", pos, msg);
   717         }
   805         }
   718         prompt();
   806         prompt();
   719         nwarnings++;
   807         nwarnings++;
   720         errWriter.flush();
   808         warnWriter.flush();
   721     }
   809     }
   722 
   810 
   723     public static String format(String fmt, Object... args) {
   811     public static String format(String fmt, Object... args) {
   724         return String.format((java.util.Locale)null, fmt, args);
   812         return String.format((java.util.Locale)null, fmt, args);
   725     }
   813     }