# HG changeset patch # User mcimadamore # Date 1223564858 -3600 # Node ID 57506cdfb7b4d0a350e5949cfffd43e91ba3c425 # Parent 6ff8524783fab6218eb5f168cd6745aa6cf4297c 6406133: JCDiagnostic.getMessage ignores locale argument Summary: Compiler API should take into account locale settings Reviewed-by: jjg diff -r 6ff8524783fa -r 57506cdfb7b4 langtools/src/share/classes/com/sun/tools/apt/util/Bark.java --- a/langtools/src/share/classes/com/sun/tools/apt/util/Bark.java Thu Oct 09 16:04:29 2008 +0100 +++ b/langtools/src/share/classes/com/sun/tools/apt/util/Bark.java Thu Oct 09 16:07:38 2008 +0100 @@ -29,7 +29,7 @@ import com.sun.tools.javac.util.JCDiagnostic; import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition; import com.sun.tools.javac.util.Log; -import com.sun.tools.javac.util.Messages; +import com.sun.tools.javac.util.JavacMessages; import com.sun.tools.javac.util.Position; /** A subtype of Log for use in APT. @@ -87,7 +87,7 @@ context.put(barkKey, this); // register additional resource bundle for APT messages. - Messages aptMessages = Messages.instance(context); + JavacMessages aptMessages = JavacMessages.instance(context); aptMessages.add("com.sun.tools.apt.resources.apt"); aptDiags = new JCDiagnostic.Factory(aptMessages, "apt"); diff -r 6ff8524783fa -r 57506cdfb7b4 langtools/src/share/classes/com/sun/tools/javac/api/Formattable.java --- a/langtools/src/share/classes/com/sun/tools/javac/api/Formattable.java Thu Oct 09 16:04:29 2008 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/api/Formattable.java Thu Oct 09 16:07:38 2008 +0100 @@ -25,7 +25,7 @@ package com.sun.tools.javac.api; -import java.util.ResourceBundle; +import java.util.Locale; /** * This interface must be implemented by any javac class that has non-trivial @@ -39,10 +39,11 @@ * Used to obtain a localized String representing the object accordingly * to a given locale * - * @param bundle resource bundle class used for localization + * @param locale locale in which the object's representation is to be rendered + * @param messages messages object used for localization * @return a locale-dependent string representing the object */ - public String toString(ResourceBundle bundle); + public String toString(Locale locale, Messages messages); /** * Retrieve a pretty name of this object's kind * @return a string representing the object's kind diff -r 6ff8524783fa -r 57506cdfb7b4 langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java --- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Thu Oct 09 16:04:29 2008 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Thu Oct 09 16:07:38 2008 +0100 @@ -68,6 +68,7 @@ private JavacTool tool; private Main compilerMain; private JavaCompiler compiler; + private Locale locale; private String[] args; private Context context; private List fileObjects; @@ -89,6 +90,7 @@ this.args = args; this.context = context; this.fileObjects = fileObjects; + setLocale(Locale.getDefault()); // null checks compilerMain.getClass(); args.getClass(); @@ -156,9 +158,9 @@ } public void setLocale(Locale locale) { - // locale argument is ignored, see RFE 6443132 if (used.get()) throw new IllegalStateException(); + this.locale = locale; } private void prepareCompiler() throws IOException { @@ -191,6 +193,8 @@ if (taskListener != null) context.put(TaskListener.class, wrap(taskListener)); tool.beginContext(context); + //initialize compiler's default locale + JavacMessages.instance(context).setCurrentLocale(locale); } // where private TaskListener wrap(final TaskListener tl) { diff -r 6ff8524783fa -r 57506cdfb7b4 langtools/src/share/classes/com/sun/tools/javac/api/JavacTool.java --- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTool.java Thu Oct 09 16:04:29 2008 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTool.java Thu Oct 09 16:07:38 2008 +0100 @@ -49,6 +49,7 @@ import com.sun.tools.javac.main.RecognizedOptions; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Log; +import com.sun.tools.javac.util.JavacMessages; import com.sun.tools.javac.util.Options; import com.sun.tools.javac.util.Pair; import java.nio.charset.Charset; @@ -144,6 +145,7 @@ Locale locale, Charset charset) { Context context = new Context(); + JavacMessages.instance(context).setCurrentLocale(locale); if (diagnosticListener != null) context.put(DiagnosticListener.class, diagnosticListener); context.put(Log.outKey, new PrintWriter(System.err, true)); // FIXME diff -r 6ff8524783fa -r 57506cdfb7b4 langtools/src/share/classes/com/sun/tools/javac/api/Messages.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/api/Messages.java Thu Oct 09 16:07:38 2008 +0100 @@ -0,0 +1,54 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.tools.javac.api; + +import java.util.Locale; +import java.util.MissingResourceException; + +/** + * This interface defines the minimum requirements in order to provide support + * for localized formatted strings. + * + * @author Maurizio Cimadamore + */ +public interface Messages { + + /** + * Add a new resource bundle to the list that is searched for localized messages. + * @param bundleName the name to identify the resource bundle of localized messages. + * @throws MissingResourceException if the given resource is not found + */ + void add(String bundleName) throws MissingResourceException; + + /** + * Get a localized formatted string + * @param l locale in which the text is to be localized + * @param key locale-independent message key + * @param args misc message arguments + * @return a localized formatted string + */ + String getLocalizedString(Locale l, String key, Object... args); +} diff -r 6ff8524783fa -r 57506cdfb7b4 langtools/src/share/classes/com/sun/tools/javac/code/Kinds.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Kinds.java Thu Oct 09 16:04:29 2008 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Kinds.java Thu Oct 09 16:07:38 2008 +0100 @@ -26,9 +26,10 @@ package com.sun.tools.javac.code; import java.util.EnumSet; -import java.util.ResourceBundle; +import java.util.Locale; import com.sun.tools.javac.api.Formattable; +import com.sun.tools.javac.api.Messages; import static com.sun.tools.javac.code.TypeTags.*; import static com.sun.tools.javac.code.Flags.*; @@ -117,9 +118,9 @@ return "Kindname"; } - public String toString(ResourceBundle bundle) { + public String toString(Locale locale, Messages messages) { String s = toString(); - return bundle.getString("compiler.misc." + s); + return messages.getLocalizedString(locale, "compiler.misc." + s); } } diff -r 6ff8524783fa -r 57506cdfb7b4 langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java Thu Oct 09 16:04:29 2008 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java Thu Oct 09 16:07:38 2008 +0100 @@ -336,7 +336,7 @@ // create the basic builtin symbols rootPackage = new PackageSymbol(names.empty, null); - final Messages messages = Messages.instance(context); + final JavacMessages messages = JavacMessages.instance(context); unnamedPackage = new PackageSymbol(names.empty, rootPackage) { public String toString() { return messages.getLocalizedString("compiler.misc.unnamed.package"); diff -r 6ff8524783fa -r 57506cdfb7b4 langtools/src/share/classes/com/sun/tools/javac/code/Types.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Thu Oct 09 16:04:29 2008 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Thu Oct 09 16:07:38 2008 +0100 @@ -67,7 +67,7 @@ new Context.Key(); final Symtab syms; - final Messages messages; + final JavacMessages messages; final Names names; final boolean allowBoxing; final ClassReader reader; @@ -93,7 +93,7 @@ source = Source.instance(context); chk = Check.instance(context); capturedName = names.fromString(""); - messages = Messages.instance(context); + messages = JavacMessages.instance(context); } // diff -r 6ff8524783fa -r 57506cdfb7b4 langtools/src/share/classes/com/sun/tools/javac/main/Main.java --- a/langtools/src/share/classes/com/sun/tools/javac/main/Main.java Thu Oct 09 16:04:29 2008 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/main/Main.java Thu Oct 09 16:07:38 2008 +0100 @@ -484,7 +484,7 @@ public static String getLocalizedString(String key, Object... args) { // FIXME sb private try { if (messages == null) - messages = new Messages(javacBundleName); + messages = new JavacMessages(javacBundleName); return messages.getLocalizedString("javac." + key, args); } catch (MissingResourceException e) { @@ -494,18 +494,18 @@ public static void useRawMessages(boolean enable) { if (enable) { - messages = new Messages(javacBundleName) { + messages = new JavacMessages(javacBundleName) { public String getLocalizedString(String key, Object... args) { return key; } }; } else { - messages = new Messages(javacBundleName); + messages = new JavacMessages(javacBundleName); } } private static final String javacBundleName = "com.sun.tools.javac.resources.javac"; - private static Messages messages; + private static JavacMessages messages; } diff -r 6ff8524783fa -r 57506cdfb7b4 langtools/src/share/classes/com/sun/tools/javac/parser/Token.java --- a/langtools/src/share/classes/com/sun/tools/javac/parser/Token.java Thu Oct 09 16:04:29 2008 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/Token.java Thu Oct 09 16:07:38 2008 +0100 @@ -25,9 +25,10 @@ package com.sun.tools.javac.parser; -import java.util.ResourceBundle; +import java.util.Locale; import com.sun.tools.javac.api.Formattable; +import com.sun.tools.javac.api.Messages; /** An interface that defines codes for Java source tokens * returned from lexical analysis. @@ -191,8 +192,7 @@ return "Token"; } - public String toString(ResourceBundle bundle) { - String s = toString(); - return s.startsWith("token.") ? bundle.getString("compiler.misc." + s) : s; + public String toString(Locale locale, Messages messages) { + return name != null ? toString() : messages.getLocalizedString(locale, "compiler.misc." + toString()); } } diff -r 6ff8524783fa -r 57506cdfb7b4 langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java --- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Thu Oct 09 16:04:29 2008 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Thu Oct 09 16:07:38 2008 +0100 @@ -69,6 +69,7 @@ import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Log; +import com.sun.tools.javac.util.JavacMessages; import com.sun.tools.javac.util.Name; import com.sun.tools.javac.util.Names; import com.sun.tools.javac.util.Options; @@ -133,9 +134,14 @@ */ Source source; + /** + * JavacMessages object used for localization + */ + private JavacMessages messages; + private Context context; - public JavacProcessingEnvironment(Context context, Iterable processors) { + public JavacProcessingEnvironment(Context context, Iterable processors) { options = Options.instance(context); this.context = context; log = Log.instance(context); @@ -157,6 +163,7 @@ typeUtils = new JavacTypes(context); processorOptions = initProcessorOptions(context); unmatchedProcessorOptions = initUnmatchedProcessorOptions(); + messages = JavacMessages.instance(context); initProcessorIterator(context, processors); } @@ -1246,7 +1253,7 @@ } public Locale getLocale() { - return Locale.getDefault(); + return messages.getCurrentLocale(); } public Set getSpecifiedPackages() { diff -r 6ff8524783fa -r 57506cdfb7b4 langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java --- a/langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java Thu Oct 09 16:04:29 2008 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java Thu Oct 09 16:07:38 2008 +0100 @@ -27,6 +27,7 @@ import java.util.Collection; import java.util.Locale; import javax.tools.JavaFileObject; +import java.util.ResourceBundle; import com.sun.tools.javac.api.DiagnosticFormatter; import com.sun.tools.javac.api.Formattable; @@ -48,15 +49,15 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter { /** - * Messages object used by this formatter for i18n + * JavacMessages object used by this formatter for i18n */ - protected Messages messages; + protected JavacMessages messages; /** - * Initialize an AbstractDiagnosticFormatter by setting its Messages object + * Initialize an AbstractDiagnosticFormatter by setting its JavacMessages object * @param messages */ - protected AbstractDiagnosticFormatter(Messages messages) { + protected AbstractDiagnosticFormatter(JavacMessages messages) { this.messages = messages; } @@ -131,7 +132,7 @@ else if (arg instanceof JavaFileObject) return JavacFileManager.getJavacBaseFileName((JavaFileObject)arg); else if (arg instanceof Formattable) - return ((Formattable)arg).toString(Messages.getDefaultBundle()); + return ((Formattable)arg).toString(l, messages); else return String.valueOf(arg); } @@ -164,6 +165,6 @@ * @return a locale-dependent string */ protected String localize(Locale l, String key, Object... args) { - return messages.getLocalizedString(key, args); + return messages.getLocalizedString(l, key, args); } } diff -r 6ff8524783fa -r 57506cdfb7b4 langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java --- a/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java Thu Oct 09 16:04:29 2008 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java Thu Oct 09 16:07:38 2008 +0100 @@ -59,9 +59,9 @@ * Create a basic formatter based on the supplied options. * * @param opts list of command-line options - * @param msgs Messages object used for i18n + * @param msgs JavacMessages object used for i18n */ - BasicDiagnosticFormatter(Options opts, Messages msgs) { + BasicDiagnosticFormatter(Options opts, JavacMessages msgs) { this(msgs); //common init String fmt = opts.get("diags"); if (fmt != null) { @@ -80,9 +80,9 @@ /** * Create a standard basic formatter * - * @param msgs Messages object used for i18n + * @param msgs JavacMessages object used for i18n */ - public BasicDiagnosticFormatter(Messages msgs) { + public BasicDiagnosticFormatter(JavacMessages msgs) { super(msgs); availableFormats = new HashMap(); availableFormats.put(DEFAULT_POS_FORMAT, "%f:%l:%_%t%m"); @@ -91,6 +91,8 @@ } public String format(JCDiagnostic d, Locale l) { + if (l == null) + l = messages.getCurrentLocale(); String format = selectFormat(d); StringBuilder buf = new StringBuilder(); for (int i = 0; i < format.length(); i++) { diff -r 6ff8524783fa -r 57506cdfb7b4 langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java --- a/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java Thu Oct 09 16:04:29 2008 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java Thu Oct 09 16:07:38 2008 +0100 @@ -64,12 +64,12 @@ /** Create a new diagnostic factory. */ protected Factory(Context context) { - this(Messages.instance(context), "compiler"); + this(JavacMessages.instance(context), "compiler"); context.put(diagnosticFactoryKey, this); } /** Create a new diagnostic factory. */ - public Factory(Messages messages, String prefix) { + public Factory(JavacMessages messages, String prefix) { this.prefix = prefix; this.formatter = new BasicDiagnosticFormatter(messages); } @@ -178,7 +178,7 @@ @Deprecated public static DiagnosticFormatter getFragmentFormatter() { if (fragmentFormatter == null) { - fragmentFormatter = new BasicDiagnosticFormatter(Messages.getDefaultMessages()); + fragmentFormatter = new BasicDiagnosticFormatter(JavacMessages.getDefaultMessages()); } return fragmentFormatter; } diff -r 6ff8524783fa -r 57506cdfb7b4 langtools/src/share/classes/com/sun/tools/javac/util/JavacMessages.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/util/JavacMessages.java Thu Oct 09 16:07:38 2008 +0100 @@ -0,0 +1,194 @@ +/* + * Copyright 2005 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.tools.javac.util; + +import com.sun.tools.javac.api.Messages; +import java.lang.ref.SoftReference; +import java.util.ResourceBundle; +import java.util.MissingResourceException; +import java.text.MessageFormat; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +/** + * Support for formatted localized messages. + * + *

This is NOT part of any API supported by Sun Microsystems. If + * you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + */ +public class JavacMessages implements Messages { + /** The context key for the JavacMessages object. */ + protected static final Context.Key messagesKey = + new Context.Key(); + + /** Get the JavacMessages instance for this context. */ + public static JavacMessages instance(Context context) { + JavacMessages instance = context.get(messagesKey); + if (instance == null) + instance = new JavacMessages(context); + return instance; + } + + private Map>> bundleCache; + + private List bundleNames; + + private Locale currentLocale; + private List currentBundles; + + public Locale getCurrentLocale() { + return currentLocale; + } + + public void setCurrentLocale(Locale locale) { + if (locale == null) { + locale = Locale.getDefault(); + } + this.currentBundles = getBundles(locale); + this.currentLocale = locale; + } + + /** Creates a JavacMessages object. + */ + public JavacMessages(Context context) { + this(defaultBundleName); + context.put(messagesKey, this); + } + + /** Creates a JavacMessages object. + * @param bundleName the name to identify the resource buundle of localized messages. + */ + public JavacMessages(String bundleName) throws MissingResourceException { + bundleNames = List.nil(); + bundleCache = new HashMap>>(); + add(bundleName); + setCurrentLocale(Locale.getDefault()); + } + + public JavacMessages() throws MissingResourceException { + this(defaultBundleName); + } + + public void add(String bundleName) throws MissingResourceException { + bundleNames = bundleNames.prepend(bundleName); + if (!bundleCache.isEmpty()) + bundleCache.clear(); + } + + public List getBundles(Locale locale) { + if (locale == currentLocale) + return currentBundles; + SoftReference> bundles = bundleCache.get(locale); + List bundleList = bundles == null ? null : bundles.get(); + if (bundleList == null) { + bundleList = List.nil(); + for (String bundleName : bundleNames) { + try { + ResourceBundle rb = ResourceBundle.getBundle(bundleName, locale); + bundleList = bundleList.prepend(rb); + } catch (MissingResourceException e) { + throw new InternalError("Cannot find javac resource bundle for locale " + locale); + } + } + bundleCache.put(locale, new SoftReference>(bundleList)); + } + return bundleList; + } + + /** Gets the localized string corresponding to a key, formatted with a set of args. + */ + public String getLocalizedString(String key, Object... args) { + return getLocalizedString(currentLocale, key, args); + } + + public String getLocalizedString(Locale l, String key, Object... args) { + if (l == null) + l = getCurrentLocale(); + return getLocalizedString(getBundles(l), key, args); + } + + /* Static access: + * javac has a firmly entrenched notion of a default message bundle + * which it can access from any static context. This is used to get + * easy access to simple localized strings. + */ + + private static final String defaultBundleName = + "com.sun.tools.javac.resources.compiler"; + private static ResourceBundle defaultBundle; + private static JavacMessages defaultMessages; + + + /** + * Gets a localized string from the compiler's default bundle. + */ + // used to support legacy Log.getLocalizedString + static String getDefaultLocalizedString(String key, Object... args) { + return getLocalizedString(List.of(getDefaultBundle()), key, args); + } + + // used to support legacy static Diagnostic.fragment + @Deprecated + static JavacMessages getDefaultMessages() { + if (defaultMessages == null) + defaultMessages = new JavacMessages(defaultBundleName); + return defaultMessages; + } + + public static ResourceBundle getDefaultBundle() { + try { + if (defaultBundle == null) + defaultBundle = ResourceBundle.getBundle(defaultBundleName); + return defaultBundle; + } + catch (MissingResourceException e) { + throw new Error("Fatal: Resource for compiler is missing", e); + } + } + + private static String getLocalizedString(List bundles, + String key, + Object... args) { + String msg = null; + for (List l = bundles; l.nonEmpty() && msg == null; l = l.tail) { + ResourceBundle rb = l.head; + try { + msg = rb.getString(key); + } + catch (MissingResourceException e) { + // ignore, try other bundles in list + } + } + if (msg == null) { + msg = "compiler message file broken: key=" + key + + " arguments={0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}"; + } + return MessageFormat.format(msg, args); + } +} diff -r 6ff8524783fa -r 57506cdfb7b4 langtools/src/share/classes/com/sun/tools/javac/util/Log.java --- a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java Thu Oct 09 16:04:29 2008 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java Thu Oct 09 16:07:38 2008 +0100 @@ -29,7 +29,6 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; -import java.util.Locale; import javax.tools.DiagnosticListener; import javax.tools.JavaFileObject; @@ -97,6 +96,11 @@ */ private DiagnosticFormatter diagFormatter; + /** + * JavacMessages object used for localization + */ + private JavacMessages messages; + /** Construct a log with given I/O redirections. */ @Deprecated @@ -115,9 +119,9 @@ this.MaxWarnings = getIntOption(options, "-Xmaxwarns", 100); boolean rawDiagnostics = options.get("rawDiagnostics") != null; - Messages msgs = Messages.instance(context); - this.diagFormatter = rawDiagnostics ? new RawDiagnosticFormatter(msgs) : - new BasicDiagnosticFormatter(options, msgs); + messages = JavacMessages.instance(context); + this.diagFormatter = rawDiagnostics ? new RawDiagnosticFormatter(messages) : + new BasicDiagnosticFormatter(options, messages); @SuppressWarnings("unchecked") // FIXME DiagnosticListener diagListener = context.get(DiagnosticListener.class); @@ -335,7 +339,7 @@ PrintWriter writer = getWriterForDiagnosticType(diag.getType()); - printLines(writer, diagFormatter.format(diag, Locale.getDefault())); + printLines(writer, diagFormatter.format(diag, messages.getCurrentLocale())); if (diagFormatter.displaySource(diag)) { int pos = diag.getIntPosition(); if (pos != Position.NOPOS) { @@ -384,7 +388,7 @@ * @param args Fields to substitute into the string. */ public static String getLocalizedString(String key, Object ... args) { - return Messages.getDefaultLocalizedString("compiler.misc." + key, args); + return JavacMessages.getDefaultLocalizedString("compiler.misc." + key, args); } /*************************************************************************** diff -r 6ff8524783fa -r 57506cdfb7b4 langtools/src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java --- a/langtools/src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java Thu Oct 09 16:04:29 2008 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java Thu Oct 09 16:07:38 2008 +0100 @@ -41,7 +41,7 @@ * Create a formatter based on the supplied options. * @param msgs */ - public RawDiagnosticFormatter(Messages msgs) { + public RawDiagnosticFormatter(JavacMessages msgs) { super(null); } diff -r 6ff8524783fa -r 57506cdfb7b4 langtools/test/tools/javac/6457284/T6457284.java --- a/langtools/test/tools/javac/6457284/T6457284.java Thu Oct 09 16:04:29 2008 +0100 +++ b/langtools/test/tools/javac/6457284/T6457284.java Thu Oct 09 16:07:38 2008 +0100 @@ -35,7 +35,7 @@ import com.sun.tools.javac.api.JavacTaskImpl; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.List; -import com.sun.tools.javac.util.Messages; +import com.sun.tools.javac.util.JavacMessages; import javax.tools.*; @@ -63,7 +63,7 @@ throw new AssertionError("No top-level classes!"); } - static class MyMessages extends Messages { + static class MyMessages extends JavacMessages { static void preRegister(Context context) { context.put(messagesKey, new MyMessages()); } diff -r 6ff8524783fa -r 57506cdfb7b4 langtools/test/tools/javac/api/6406133/Erroneous.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/api/6406133/Erroneous.java Thu Oct 09 16:07:38 2008 +0100 @@ -0,0 +1,4 @@ +@Deprecated +class A { + class A {} +} diff -r 6ff8524783fa -r 57506cdfb7b4 langtools/test/tools/javac/api/6406133/T6406133.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/api/6406133/T6406133.java Thu Oct 09 16:07:38 2008 +0100 @@ -0,0 +1,109 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6443132 6406133 6597678 + * @summary Compiler API ignores locale settings + * @author Maurizio Cimadamore + * @library ../lib + */ + +import javax.tools.*; +import javax.annotation.processing.*; +import javax.lang.model.element.*; +import java.util.*; +import java.io.*; + +public class T6406133 extends ToolTester { + + List locales = Arrays.asList(Locale.US, Locale.JAPAN, Locale.CHINA); + + class DiagnosticTester implements DiagnosticListener { + Locale locale; + String result; + + DiagnosticTester(Locale locale) { + this.locale = locale; + } + public void report(Diagnostic diagnostic) { + result = diagnostic.getMessage(locale); //6406133 + } + } + + class ProcessorTester extends AbstractProcessor { + + Locale locale; + + public Set getSupportedAnnotationTypes() { + return new HashSet(Arrays.asList("*")); + } + + public void init(ProcessingEnvironment env) { + locale = env.getLocale(); + } + + public boolean process(Set annotations, RoundEnvironment roundEnv) { + return true; + } + } + + void compare(Locale loc1, Locale loc2, boolean useListener) { + String res1 = exec(useListener, loc1); + String res2 = exec(useListener, loc2); + boolean success = (loc1.equals(loc2) && res1.equals(res2)) || + (!loc1.equals(loc2) && !res1.equals(res2)); + if (!success) + throw new AssertionError("Error in diagnostic localization"); + } + + String exec(boolean useListener, Locale locale) { + final Iterable compilationUnits = + fm.getJavaFileObjects(new File(test_src, "Erroneous.java")); + StringWriter pw = new StringWriter(); + DiagnosticTester listener = useListener ? new DiagnosticTester(locale) : null; + ProcessorTester processor = new ProcessorTester(); + task = tool.getTask(pw, fm, listener, null, null, compilationUnits); + task.setProcessors(Arrays.asList(processor)); + task.setLocale(locale); //6443132 + task.call(); + if (!processor.locale.equals(locale)) + throw new AssertionError("Error in diagnostic localization during annotation processing"); + String res = useListener ? listener.result : pw.toString(); + System.err.println("[locale:"+ locale + ", listener:" + useListener + "] " +res); + return res; + } + + void test() { + for (Locale l1 : locales) { + for (Locale l2 : locales) { + compare(l1, l2, true); + compare(l1, l2, false); + } + } + } + + public static void main(String... args) throws Exception { + new T6406133().test(); + } +}