# HG changeset patch # User jjg # Date 1470265269 25200 # Node ID 4995ab1a4558f2a87c8515b6eb99b16de6835928 # Parent ba38ad2dd1373304dc19e6faa7eb7bd423e4dce7 8162359: javac should use stdout for --help and --version Reviewed-by: vromero diff -r ba38ad2dd137 -r 4995ab1a4558 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTool.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTool.java Wed Aug 03 11:30:27 2016 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTool.java Wed Aug 03 16:01:09 2016 -0700 @@ -97,7 +97,7 @@ PrintWriter pw = (charset == null) ? new PrintWriter(System.err, true) : new PrintWriter(new OutputStreamWriter(System.err, charset), true); - context.put(Log.outKey, pw); + context.put(Log.errKey, pw); CacheFSInfo.preRegister(context); return new JavacFileManager(context, true, charset); } @@ -161,9 +161,9 @@ context.put(DiagnosticListener.class, ccw.wrap(diagnosticListener)); if (out == null) - context.put(Log.outKey, new PrintWriter(System.err, true)); + context.put(Log.errKey, new PrintWriter(System.err, true)); else - context.put(Log.outKey, new PrintWriter(out, true)); + context.put(Log.errKey, new PrintWriter(out, true)); if (fileManager == null) { fileManager = getStandardFileManager(diagnosticListener, null, null); diff -r ba38ad2dd137 -r 4995ab1a4558 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java Wed Aug 03 11:30:27 2016 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java Wed Aug 03 16:01:09 2016 -0700 @@ -62,9 +62,13 @@ */ String ownName; + /** The writer to use for normal output. + */ + PrintWriter stdOut; + /** The writer to use for diagnostic output. */ - PrintWriter out; + PrintWriter stdErr; /** The log to use for diagnostic output. */ @@ -102,7 +106,7 @@ * @param name the name of this tool */ public Main(String name) { - this(name, new PrintWriter(System.err, true)); + this.ownName = name; } /** @@ -112,7 +116,7 @@ */ public Main(String name, PrintWriter out) { this.ownName = name; - this.out = out; + this.stdOut = this.stdErr = out; } /** Report a usage error. @@ -161,7 +165,14 @@ * @return the result of the compilation */ public Result compile(String[] argv, Context context) { - context.put(Log.outKey, out); + if (stdOut != null) { + context.put(Log.outKey, stdOut); + } + + if (stdErr != null) { + context.put(Log.errKey, stdErr); + } + log = Log.instance(context); if (argv.length == 0) { diff -r ba38ad2dd137 -r 4995ab1a4558 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java Wed Aug 03 11:30:27 2016 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java Wed Aug 03 16:01:09 2016 -0700 @@ -96,23 +96,23 @@ if (this.kind != kind) return; - log.printRawLines(WriterKind.NOTICE, + log.printRawLines(WriterKind.STDOUT, String.format(HELP_LINE_FORMAT, log.localize(PrefixKind.JAVAC, "opt.Xlint.subopts"), log.localize(PrefixKind.JAVAC, "opt.Xlint.suboptlist"))); - log.printRawLines(WriterKind.NOTICE, + log.printRawLines(WriterKind.STDOUT, String.format(LINT_KEY_FORMAT, "all", log.localize(PrefixKind.JAVAC, "opt.Xlint.all"))); for (LintCategory lc : LintCategory.values()) { if (lc.hidden) continue; - log.printRawLines(WriterKind.NOTICE, + log.printRawLines(WriterKind.STDOUT, String.format(LINT_KEY_FORMAT, lc.option, log.localize(PrefixKind.JAVAC, "opt.Xlint.desc." + lc.option))); } - log.printRawLines(WriterKind.NOTICE, + log.printRawLines(WriterKind.STDOUT, String.format(LINT_KEY_FORMAT, "none", log.localize(PrefixKind.JAVAC, "opt.Xlint.none"))); @@ -307,7 +307,7 @@ delim = ", "; } - log.printRawLines(WriterKind.NOTICE, + log.printRawLines(WriterKind.STDOUT, String.format(HELP_LINE_FORMAT, super.helpSynopsis(log), log.localize(PrefixKind.JAVAC, descrKey, targets.toString()))); @@ -331,7 +331,7 @@ public boolean process(OptionHelper helper, String option) { Log log = helper.getLog(); String ownName = helper.getOwnName(); - log.printLines(PrefixKind.JAVAC, "version", ownName, JavaCompiler.version()); + log.printLines(WriterKind.STDOUT, PrefixKind.JAVAC, "version", ownName, JavaCompiler.version()); return super.process(helper, option); } }, @@ -341,7 +341,7 @@ public boolean process(OptionHelper helper, String option) { Log log = helper.getLog(); String ownName = helper.getOwnName(); - log.printLines(PrefixKind.JAVAC, "fullVersion", ownName, JavaCompiler.fullVersion()); + log.printLines(WriterKind.STDOUT, PrefixKind.JAVAC, "fullVersion", ownName, JavaCompiler.fullVersion()); return super.process(helper, option); } }, @@ -351,11 +351,11 @@ public boolean process(OptionHelper helper, String option) { Log log = helper.getLog(); String ownName = helper.getOwnName(); - log.printLines(PrefixKind.JAVAC, "msg.usage.header", ownName); + log.printLines(WriterKind.STDOUT, PrefixKind.JAVAC, "msg.usage.header", ownName); for (Option o: getJavaCompilerOptions()) { o.help(log, OptionKind.STANDARD); } - log.printNewline(); + log.printNewline(WriterKind.STDOUT); return super.process(helper, option); } }, @@ -396,8 +396,8 @@ for (Option o: getJavaCompilerOptions()) { o.help(log, OptionKind.EXTENDED); } - log.printNewline(); - log.printLines(PrefixKind.JAVAC, "msg.usage.nonstandard.footer"); + log.printNewline(WriterKind.STDOUT); + log.printLines(WriterKind.STDOUT, PrefixKind.JAVAC, "msg.usage.nonstandard.footer"); return super.process(helper, option); } }, @@ -840,7 +840,7 @@ if (this.kind != kind) return; - log.printRawLines(WriterKind.NOTICE, + log.printRawLines(WriterKind.STDOUT, String.format(HELP_LINE_FORMAT, helpSynopsis(log), log.localize(PrefixKind.JAVAC, descrKey))); diff -r ba38ad2dd137 -r 4995ab1a4558 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacFiler.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacFiler.java Wed Aug 03 11:30:27 2016 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacFiler.java Wed Aug 03 16:01:09 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -604,7 +604,7 @@ * Debugging function to display internal state. */ public void displayState() { - PrintWriter xout = context.get(Log.outKey); + PrintWriter xout = context.get(Log.logKey).getWriter(Log.WriterKind.STDERR); xout.println("File Object History : " + fileObjectHistory); xout.println("Open Type Names : " + openTypeNames); xout.println("Gen. Src Names : " + generatedSourceNames); diff -r ba38ad2dd137 -r 4995ab1a4558 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Wed Aug 03 11:30:27 2016 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Wed Aug 03 16:01:09 2016 -0700 @@ -26,12 +26,10 @@ package com.sun.tools.javac.processing; import java.io.Closeable; -import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.reflect.Method; -import java.lang.reflect.Constructor; import java.net.MalformedURLException; import java.net.URL; import java.nio.file.Path; diff -r ba38ad2dd137 -r 4995ab1a4558 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java Wed Aug 03 11:30:27 2016 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java Wed Aug 03 16:01:09 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,10 +27,13 @@ import java.io.*; import java.util.Arrays; +import java.util.EnumMap; import java.util.EnumSet; import java.util.HashSet; +import java.util.Map; import java.util.Queue; import java.util.Set; + import javax.tools.DiagnosticListener; import javax.tools.JavaFileObject; @@ -56,9 +59,12 @@ /** The context key for the log. */ public static final Context.Key logKey = new Context.Key<>(); - /** The context key for the output PrintWriter. */ + /** The context key for the standard output PrintWriter. */ public static final Context.Key outKey = new Context.Key<>(); + /** The context key for the diagnostic PrintWriter. */ + public static final Context.Key errKey = new Context.Key<>(); + /* TODO: Should unify this with prefix handling in JCDiagnostic.Factory. */ public enum PrefixKind { JAVAC("javac."), @@ -111,6 +117,7 @@ install(log); } + @Override public void report(JCDiagnostic diag) { } } @@ -134,6 +141,7 @@ install(log); } + @Override public void report(JCDiagnostic diag) { if (!diag.isFlagSet(JCDiagnostic.DiagnosticFlag.NON_DEFERRABLE) && (filter == null || filter.accepts(diag))) { @@ -163,13 +171,9 @@ } } - public enum WriterKind { NOTICE, WARNING, ERROR } - - protected PrintWriter errWriter; + public enum WriterKind { NOTICE, WARNING, ERROR, STDOUT, STDERR } - protected PrintWriter warnWriter; - - protected PrintWriter noticeWriter; + private final Map writers; /** The maximum number of errors/warnings that are reported. */ @@ -223,14 +227,130 @@ */ private DiagnosticHandler diagnosticHandler; - /** Construct a log with given I/O redirections. + /** Get the Log instance for this context. */ + public static Log instance(Context context) { + Log instance = context.get(logKey); + if (instance == null) + instance = new Log(context); + return instance; + } + + /** + * Register a Context.Factory to create a Log. + */ + public static void preRegister(Context context, PrintWriter w) { + context.put(Log.class, (Context.Factory) (c -> new Log(c, w))); + } + + /** + * Construct a log with default settings. + * If no streams are set in the context, the log will be initialized to use + * System.out for normal output, and System.err for all diagnostic output. + * If one stream is set in the context, with either Log.outKey or Log.errKey, + * it will be used for all output. + * Otherwise, the log will be initialized to use both streams found in the context. + */ + protected Log(Context context) { + this(context, initWriters(context)); + } + + /** + * Initialize a map of writers based on values found in the context + * @param context the context in which to find writers to use + * @return a map of writers + */ + private static Map initWriters(Context context) { + PrintWriter out = context.get(outKey); + PrintWriter err = context.get(errKey); + if (out == null && err == null) { + out = new PrintWriter(System.out, true); + err = new PrintWriter(System.err, true); + return initWriters(out, err); + } else if (out == null || err == null) { + PrintWriter pw = (out != null) ? out : err; + return initWriters(pw, pw); + } else { + return initWriters(out, err); + } + } + + /** + * Construct a log with all output sent to a single output stream. + */ + protected Log(Context context, PrintWriter writer) { + this(context, initWriters(writer, writer)); + } + + /** + * Construct a log. + * The log will be initialized to use stdOut for normal output, and stdErr + * for all diagnostic output. */ + protected Log(Context context, PrintWriter out, PrintWriter err) { + this(context, initWriters(out, err)); + } + + /** + * Initialize a writer map for a stream for normal output, and a stream for diagnostics. + * @param out a stream to be used for normal output + * @param err a stream to be used for diagnostic messages, such as errors, warnings, etc + * @return a map of writers + */ + private static Map initWriters(PrintWriter out, PrintWriter err) { + Map writers = new EnumMap<>(WriterKind.class); + writers.put(WriterKind.ERROR, err); + writers.put(WriterKind.WARNING, err); + writers.put(WriterKind.NOTICE, err); + + writers.put(WriterKind.STDOUT, out); + writers.put(WriterKind.STDERR, err); + + return writers; + } + + /** + * Construct a log with given I/O redirections. + * @deprecated + * This constructor is provided to support the supported but now-deprecated javadoc entry point + * com.sun.tools.javadoc.Main.execute(String programName, + * PrintWriter errWriter, PrintWriter warnWriter, PrintWriter noticeWriter, + * String defaultDocletClassName, String... args) + */ + @Deprecated protected Log(Context context, PrintWriter errWriter, PrintWriter warnWriter, PrintWriter noticeWriter) { + this(context, initWriters(errWriter, warnWriter, noticeWriter)); + } + + /** + * Initialize a writer map with different streams for different types of diagnostics. + * @param errWriter a stream for writing error messages + * @param warnWriter a stream for writing warning messages + * @param noticeWriter a stream for writing notice messages + * @return a map of writers + * @deprecated This method exists to support a supported but now deprecated javadoc entry point. + */ + @Deprecated + private static Map initWriters(PrintWriter errWriter, PrintWriter warnWriter, PrintWriter noticeWriter) { + Map writers = new EnumMap<>(WriterKind.class); + writers.put(WriterKind.ERROR, errWriter); + writers.put(WriterKind.WARNING, warnWriter); + writers.put(WriterKind.NOTICE, noticeWriter); + + writers.put(WriterKind.STDOUT, noticeWriter); + writers.put(WriterKind.STDERR, errWriter); + + return writers; + } + + /** + * Creates a log. + * @param context the context in which the log should be registered + * @param writers a map of writers that can be accessed by the kind of writer required + */ + private Log(Context context, Map writers) { super(JCDiagnostic.Factory.instance(context)); context.put(logKey, this); - this.errWriter = errWriter; - this.warnWriter = warnWriter; - this.noticeWriter = noticeWriter; + this.writers = writers; @SuppressWarnings("unchecked") // FIXME DiagnosticListener dl = @@ -245,6 +365,7 @@ final Options options = Options.instance(context); initOptions(options); options.addListener(new Runnable() { + @Override public void run() { initOptions(options); } @@ -293,42 +414,6 @@ return 100; } - /** The default writer for diagnostics - */ - static PrintWriter defaultWriter(Context context) { - PrintWriter result = context.get(outKey); - if (result == null) - context.put(outKey, result = new PrintWriter(System.err)); - return result; - } - - /** Construct a log with default settings. - */ - protected Log(Context context) { - this(context, defaultWriter(context)); - } - - /** Construct a log with all output redirected. - */ - protected Log(Context context, PrintWriter defaultWriter) { - this(context, defaultWriter, defaultWriter, defaultWriter); - } - - /** Get the Log instance for this context. */ - public static Log instance(Context context) { - Log instance = context.get(logKey); - if (instance == null) - instance = new Log(context); - return instance; - } - - /** - * Register a Context.Factory to create a Log. - */ - public static void preRegister(Context context, PrintWriter w) { - context.put(Log.class, (Context.Factory) (c -> new Log(c, w))); - } - /** The number of errors encountered so far. */ public int nerrors = 0; @@ -371,26 +456,18 @@ } public PrintWriter getWriter(WriterKind kind) { - switch (kind) { - case NOTICE: return noticeWriter; - case WARNING: return warnWriter; - case ERROR: return errWriter; - default: throw new IllegalArgumentException(); - } + return writers.get(kind); } public void setWriter(WriterKind kind, PrintWriter pw) { Assert.checkNonNull(pw); - switch (kind) { - case NOTICE: noticeWriter = pw; break; - case WARNING: warnWriter = pw; break; - case ERROR: errWriter = pw; break; - default: throw new IllegalArgumentException(); - } + writers.put(kind, pw); } public void setWriters(PrintWriter pw) { - noticeWriter = warnWriter = errWriter = Assert.checkNonNull(pw); + Assert.checkNonNull(pw); + for (WriterKind k: WriterKind.values()) + writers.put(k, pw); } /** @@ -407,9 +484,9 @@ /** Flush the logs */ public void flush() { - errWriter.flush(); - warnWriter.flush(); - noticeWriter.flush(); + for (PrintWriter pw: writers.values()) { + pw.flush(); + } } public void flush(WriterKind kind) { @@ -470,6 +547,7 @@ } public void printNewline() { + PrintWriter noticeWriter = writers.get(WriterKind.NOTICE); noticeWriter.println(); } @@ -478,10 +556,12 @@ } public void printLines(String key, Object... args) { + PrintWriter noticeWriter = writers.get(WriterKind.NOTICE); printRawLines(noticeWriter, localize(key, args)); } public void printLines(PrefixKind pk, String key, Object... args) { + PrintWriter noticeWriter = writers.get(WriterKind.NOTICE); printRawLines(noticeWriter, localize(pk, key, args)); } @@ -497,6 +577,7 @@ * for the platform. */ public void printRawLines(String msg) { + PrintWriter noticeWriter = writers.get(WriterKind.NOTICE); printRawLines(noticeWriter, msg); } @@ -524,10 +605,13 @@ * noticeWriter stream. */ public void printVerbose(String key, Object... args) { + PrintWriter noticeWriter = writers.get(WriterKind.NOTICE); printRawLines(noticeWriter, localize("verbose." + key, args)); } + @Override protected void directError(String key, Object... args) { + PrintWriter errWriter = writers.get(WriterKind.ERROR); printRawLines(errWriter, localize(key, args)); errWriter.flush(); } @@ -546,6 +630,7 @@ * Primary method to report a diagnostic. * @param diagnostic */ + @Override public void report(JCDiagnostic diagnostic) { diagnosticHandler.report(diagnostic); } @@ -556,6 +641,7 @@ * reported so far, the diagnostic may be handed off to writeDiagnostic. */ private class DefaultDiagnosticHandler extends DiagnosticHandler { + @Override public void report(JCDiagnostic diagnostic) { if (expectDiagKeys != null) expectDiagKeys.remove(diagnostic.getCode()); @@ -631,13 +717,13 @@ throw new IllegalArgumentException(); case NOTE: - return noticeWriter; + return writers.get(WriterKind.NOTICE); case WARNING: - return warnWriter; + return writers.get(WriterKind.WARNING); case ERROR: - return errWriter; + return writers.get(WriterKind.ERROR); default: throw new Error(); @@ -683,26 +769,27 @@ /** print an error or warning message: */ - private void printRawError(int pos, String msg) { + private void printRawDiag(PrintWriter pw, String prefix, int pos, String msg) { if (source == null || pos == Position.NOPOS) { - printRawLines(errWriter, "error: " + msg); + printRawLines(pw, prefix + msg); } else { int line = source.getLineNumber(pos); JavaFileObject file = source.getFile(); if (file != null) - printRawLines(errWriter, + printRawLines(pw, file.getName() + ":" + line + ": " + msg); - printErrLine(pos, errWriter); + printErrLine(pos, pw); } - errWriter.flush(); + pw.flush(); } /** report an error: */ public void rawError(int pos, String msg) { + PrintWriter errWriter = writers.get(WriterKind.ERROR); if (nerrors < MaxErrors && shouldReport(currentSourceFile(), pos)) { - printRawError(pos, msg); + printRawDiag(errWriter, "error: ", pos, msg); prompt(); nerrors++; } @@ -712,12 +799,13 @@ /** report a warning: */ public void rawWarning(int pos, String msg) { + PrintWriter warnWriter = writers.get(WriterKind.ERROR); if (nwarnings < MaxWarnings && emitWarnings) { - printRawError(pos, "warning: " + msg); + printRawDiag(warnWriter, "warning: ", pos, msg); } prompt(); nwarnings++; - errWriter.flush(); + warnWriter.flush(); } public static String format(String fmt, Object... args) { diff -r ba38ad2dd137 -r 4995ab1a4558 langtools/src/jdk.compiler/share/classes/com/sun/tools/javah/JavahFileManager.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javah/JavahFileManager.java Wed Aug 03 11:30:27 2016 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javah/JavahFileManager.java Wed Aug 03 16:01:09 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ if (dl != null) javac_context.put(DiagnosticListener.class, dl); - javac_context.put(com.sun.tools.javac.util.Log.outKey, log); + javac_context.put(com.sun.tools.javac.util.Log.errKey, log); return new JavahFileManager(javac_context, null); } diff -r ba38ad2dd137 -r 4995ab1a4558 langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/Messager.java --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/Messager.java Wed Aug 03 11:30:27 2016 -0700 +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/Messager.java Wed Aug 03 16:01:09 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -174,6 +174,7 @@ if (nerrors < MaxErrors) { String prefix = (pos == null) ? programName : pos.toString(); + PrintWriter errWriter = getWriter(WriterKind.ERROR); errWriter.println(prefix + ": " + getText("javadoc.error") + " - " + msg); errWriter.flush(); prompt(); @@ -206,6 +207,7 @@ if (nwarnings < MaxWarnings) { String prefix = (pos == null) ? programName : pos.toString(); + PrintWriter warnWriter = getWriter(WriterKind.WARNING); warnWriter.println(prefix + ": " + getText("javadoc.warning") +" - " + msg); warnWriter.flush(); nwarnings++; @@ -235,6 +237,7 @@ return; } + PrintWriter noticeWriter = getWriter(WriterKind.NOTICE); if (pos == null) noticeWriter.println(msg); else diff -r ba38ad2dd137 -r 4995ab1a4558 langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/Start.java --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/Start.java Wed Aug 03 11:30:27 2016 -0700 +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/Start.java Wed Aug 03 16:01:09 2016 -0700 @@ -158,7 +158,7 @@ if (log instanceof Messager) messager = (Messager) log; else { - PrintWriter out = context.get(Log.outKey); + PrintWriter out = context.get(Log.errKey); messager = (out == null) ? new Messager(context, javadocName) : new Messager(context, javadocName, out, out, out); } diff -r ba38ad2dd137 -r 4995ab1a4558 langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/api/JavadocTool.java --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/api/JavadocTool.java Wed Aug 03 11:30:27 2016 -0700 +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/api/JavadocTool.java Wed Aug 03 16:01:09 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -107,11 +107,11 @@ context.put(DiagnosticListener.class, ccw.wrap(diagnosticListener)); if (out == null) - context.put(Log.outKey, new PrintWriter(System.err, true)); + context.put(Log.errKey, new PrintWriter(System.err, true)); else if (out instanceof PrintWriter) - context.put(Log.outKey, ((PrintWriter) out)); + context.put(Log.errKey, ((PrintWriter) out)); else - context.put(Log.outKey, new PrintWriter(out, true)); + context.put(Log.errKey, new PrintWriter(out, true)); if (fileManager == null) { fileManager = getStandardFileManager(diagnosticListener, null, null); @@ -141,7 +141,7 @@ PrintWriter pw = (charset == null) ? new PrintWriter(System.err, true) : new PrintWriter(new OutputStreamWriter(System.err, charset), true); - context.put(Log.outKey, pw); + context.put(Log.errKey, pw); return new JavacFileManager(context, true, charset); } diff -r ba38ad2dd137 -r 4995ab1a4558 langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Messager.java --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Messager.java Wed Aug 03 11:30:27 2016 -0700 +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Messager.java Wed Aug 03 16:01:09 2016 -0700 @@ -165,8 +165,8 @@ /** * Constructor * @param programName Name of the program (for error messages). - * @param outWriter Stream for notices etc. - * @param errWriter Stream for errors and warnings + * @param stdOut Stream for notices etc. + * @param stdErr Stream for errors and warnings */ @SuppressWarnings("deprecation") public Messager(Context context, String programName, PrintWriter outWriter, PrintWriter errWriter) { @@ -254,6 +254,7 @@ private void incrementErrorCount(String prefix, String msg) { if (nerrors < MaxErrors) { + PrintWriter errWriter = getWriter(WriterKind.ERROR); errWriter.println(prefix + ": " + getText("javadoc.error") + " - " + msg); errWriter.flush(); prompt(); @@ -291,6 +292,7 @@ private void incrementWarningCount(String prefix, String msg) { if (nwarnings < MaxWarnings) { + PrintWriter warnWriter = getWriter(WriterKind.WARNING); warnWriter.println(prefix + ": " + getText("javadoc.warning") + " - " + msg); warnWriter.flush(); nwarnings++; @@ -314,6 +316,7 @@ return; } + PrintWriter noticeWriter = getWriter(WriterKind.NOTICE); if (path == null) { noticeWriter.println(msg); } else { @@ -329,6 +332,7 @@ return; } + PrintWriter noticeWriter = getWriter(WriterKind.NOTICE); if (e == null) { noticeWriter.println(msg); } else { diff -r ba38ad2dd137 -r 4995ab1a4558 langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java Wed Aug 03 11:30:27 2016 -0700 +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java Wed Aug 03 16:01:09 2016 -0700 @@ -155,7 +155,7 @@ if (log instanceof Messager) { messager = (Messager) log; } else { - PrintWriter out = context.get(Log.outKey); + PrintWriter out = context.get(Log.errKey); messager = (out == null) ? new Messager(context, ProgramName) : new Messager(context, ProgramName, out, out); diff -r ba38ad2dd137 -r 4995ab1a4558 langtools/src/jdk.jdeps/share/classes/com/sun/tools/javap/JavapFileManager.java --- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/javap/JavapFileManager.java Wed Aug 03 11:30:27 2016 -0700 +++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/javap/JavapFileManager.java Wed Aug 03 16:01:09 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ if (dl != null) javac_context.put(DiagnosticListener.class, dl); - javac_context.put(com.sun.tools.javac.util.Log.outKey, log); + javac_context.put(com.sun.tools.javac.util.Log.errKey, log); return new JavapFileManager(javac_context, null); } diff -r ba38ad2dd137 -r 4995ab1a4558 langtools/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java --- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java Wed Aug 03 11:30:27 2016 -0700 +++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java Wed Aug 03 16:01:09 2016 -0700 @@ -110,14 +110,13 @@ private static CaLog createLog(Context context) { PrintWriter pw = new PrintWriter(new StringWriter()); - CaLog log = new CaLog(context, pw, pw, pw); - context.put(outKey, pw); + CaLog log = new CaLog(context, pw); context.put(logKey, log); return log; } - private CaLog(Context context, PrintWriter errWriter, PrintWriter warnWriter, PrintWriter noticeWriter) { - super(context, errWriter, warnWriter, noticeWriter); + private CaLog(Context context, PrintWriter pw) { + super(context, pw); } @Override diff -r ba38ad2dd137 -r 4995ab1a4558 langtools/test/tools/javac/lib/DPrinter.java --- a/langtools/test/tools/javac/lib/DPrinter.java Wed Aug 03 11:30:27 2016 -0700 +++ b/langtools/test/tools/javac/lib/DPrinter.java Wed Aug 03 16:01:09 2016 -0700 @@ -138,7 +138,7 @@ protected DPrinter(Context context) { context.put(DPrinter.class, this); - out = context.get(Log.outKey); + out = context.get(Log.logKey).getWriter(Log.WriterKind.STDERR); trees = JavacTrees.instance(context); } diff -r ba38ad2dd137 -r 4995ab1a4558 langtools/test/tools/javac/lib/combo/ReusableContext.java --- a/langtools/test/tools/javac/lib/combo/ReusableContext.java Wed Aug 03 11:30:27 2016 -0700 +++ b/langtools/test/tools/javac/lib/combo/ReusableContext.java Wed Aug 03 16:01:09 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -83,6 +83,7 @@ drop(Arguments.argsKey); drop(DiagnosticListener.class); drop(Log.outKey); + drop(Log.errKey); drop(JavaFileManager.class); drop(JavacTask.class); diff -r ba38ad2dd137 -r 4995ab1a4558 langtools/test/tools/javac/main/StreamsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/main/StreamsTest.java Wed Aug 03 16:01:09 2016 -0700 @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8162359 + * @summary extra space in javac -help for -J and @ options + * @modules jdk.compiler + * @library /tools/lib + * @build toolbox.TestRunner toolbox.ToolBox + * @run main StreamsTest + */ + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; + +import static java.util.Arrays.asList; + +import toolbox.TestRunner; +import toolbox.ToolBox; + +public class StreamsTest extends TestRunner { + public static void main(String... args) throws Exception { + new StreamsTest().runTests(m -> new Object[] { Paths.get(m.getName()) }); + } + + StreamsTest() { + super(System.err); + } + + ToolBox tb = new ToolBox(); + static final String LINESEP = System.getProperty("line.separator"); + + @Test // errors should be written to stderr + public void testError(Path base) throws Exception { + Path src = base.resolve("src"); + Path classes = base.resolve("classes"); + tb.writeJavaFiles(src, + "import java.util.*; class C { # }"); + test(asList("-d", classes.toString(), src.resolve("C.java").toString()), + null, "illegal character: '#'"); + } + + @Test // warnings should be written to stderr + public void testWarning(Path base) throws Exception { + Path src = base.resolve("src"); + Path classes = base.resolve("classes"); + tb.writeJavaFiles(src, + "import java.util.*; class C { List list = new ArrayList(); }"); + test(asList("-d", classes.toString(), "-Xlint", src.resolve("C.java").toString()), + null, "warning: [rawtypes]"); + } + + @Test // notes should be written to stderr + public void testNote(Path base) throws Exception { + Path src = base.resolve("src"); + Path classes = base.resolve("classes"); + tb.writeJavaFiles(src, + "import java.util.*; class C { List list = (List) new ArrayList(); }"); + test(asList("-d", classes.toString(), src.resolve("C.java").toString()), + null, "uses unchecked or unsafe operations."); + } + + @Test // help output should be written to stdout + public void testHelp(Path base) throws Exception { + test(asList("-help"), "Usage: javac ", null); + } + + @Test // version output should be written to stdout + public void testVersion(Path base) throws Exception { + test(asList("-version"), "javac", null); + } + + @Test // version output should be written to stdout + public void testFullVersion(Path base) throws Exception { + test(asList("-fullversion"), "javac full version", null); + } + + /** + * Run javac as though run from the command line (but avoiding the entry point that + * calls System.exit()), and that that expected output appears on appropriate output streams. + * @param options the command-line options for javac + * @param expectOut a string that should be contained in the output generated on stdout, + * or null, if no output should be generated to stdout + * @param expectErra string that should be contained in the output generated on stderr, + * or null, if no output should be generated to stderr + * @throws IOException if a problem occurs while setting up the streams + */ + void test(List options, String expectOut, String expectErr) throws IOException { + out.println("test " + options); + ByteArrayOutputStream bsOut = new ByteArrayOutputStream(); + ByteArrayOutputStream bsErr = new ByteArrayOutputStream(); + try (PrintStream psOut = new PrintStream(bsOut); PrintStream psErr = new PrintStream(bsErr)) { + int rc; + PrintStream saveOut = System.out; + PrintStream saveErr = System.err; + try { + System.setOut(psOut); + System.setErr(psErr); + rc = com.sun.tools.javac.Main.compile(options.toArray(new String[0])); + } finally { + System.setErr(saveErr); + System.setOut(saveOut); + } + System.err.println("javac exit code: " + rc); + } + check("stdout", bsOut.toString(), expectOut); + check("stderr", bsErr.toString(), expectErr); + } + + /** + * Check that output is as expected. + * @param name the name of the stream on which the output was found + * @param actual the contents written to the stream + * @param expect string that should be contained in the output, or null, if the output should be empty + */ + void check(String name, String actual, String expect) { + out.println("Check " + name); + out.println("Expected: " + (expect == null ? "(nothing)" : expect)); + out.println("Actual:"); + out.println(actual.replace("\n", LINESEP)); + if (expect == null) { + if (!actual.isEmpty()) { + error(name + ": unexpected output"); + } + } else if (!actual.contains(expect)) { + error(name + ": expected output not found"); + } + } +} + diff -r ba38ad2dd137 -r 4995ab1a4558 langtools/test/tools/javac/modules/ModuleTestBase.java --- a/langtools/test/tools/javac/modules/ModuleTestBase.java Wed Aug 03 11:30:27 2016 -0700 +++ b/langtools/test/tools/javac/modules/ModuleTestBase.java Wed Aug 03 16:01:09 2016 -0700 @@ -71,10 +71,4 @@ Path[] findJavaFiles(Path... paths) throws IOException { return tb.findJavaFiles(paths); } - - void error(String message) { - out.println("Error: " + message); - errors++; - } - } diff -r ba38ad2dd137 -r 4995ab1a4558 langtools/test/tools/javac/newlines/NewLineTest.java --- a/langtools/test/tools/javac/newlines/NewLineTest.java Wed Aug 03 11:30:27 2016 -0700 +++ b/langtools/test/tools/javac/newlines/NewLineTest.java Wed Aug 03 16:01:09 2016 -0700 @@ -42,17 +42,23 @@ import toolbox.ToolBox; //original test: test/tools/javac/newlines/Newlines.sh +/* + * Checks that the usage message, contained in the properties in the + * resource file javac.properties, is correctly rendered, including + * embedded newlines in the resource strings. For more context, + * see JDK-4110560. + */ public class NewLineTest { public static void main(String args[]) throws Exception { ToolBox tb = new ToolBox(); - File javacErrOutput = new File("output.txt"); + File javacOutput = new File("output.txt"); new JavacTask(tb, Task.Mode.EXEC) - .redirect(Task.OutputKind.STDERR, javacErrOutput.getPath()) + .redirect(Task.OutputKind.STDOUT, javacOutput.getPath()) .options("-J-Dline.separator='@'") .run(Task.Expect.FAIL); - List lines = Files.readAllLines(javacErrOutput.toPath(), + List lines = Files.readAllLines(javacOutput.toPath(), Charset.defaultCharset()); if (lines.size() != 1) { throw new AssertionError("The compiler output should have one line only"); diff -r ba38ad2dd137 -r 4995ab1a4558 langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.java --- a/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.java Wed Aug 03 11:30:27 2016 -0700 +++ b/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.java Wed Aug 03 16:01:09 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,7 @@ @Override public void init(ProcessingEnvironment env) { super.init(env); - out = ((JavacProcessingEnvironment) env).getContext().get(Log.outKey); + out = ((JavacProcessingEnvironment) env).getContext().get(Log.logKey).getWriter(Log.WriterKind.STDERR); } @Override diff -r ba38ad2dd137 -r 4995ab1a4558 langtools/test/tools/lib/toolbox/TestRunner.java --- a/langtools/test/tools/lib/toolbox/TestRunner.java Wed Aug 03 11:30:27 2016 -0700 +++ b/langtools/test/tools/lib/toolbox/TestRunner.java Wed Aug 03 16:01:09 2016 -0700 @@ -116,4 +116,9 @@ throw new Exception(errorCount + " errors found"); } } + + public void error(String message) { + out.println("Error: " + message); + errorCount++; + } }