6406133: JCDiagnostic.getMessage ignores locale argument
Compiler API should take into account locale settings Reviewed-by: jjg
This commit is contained in:
parent
ab5f1cb24b
commit
7a442ce178
@ -29,7 +29,7 @@ import com.sun.tools.javac.util.Context;
|
|||||||
import com.sun.tools.javac.util.JCDiagnostic;
|
import com.sun.tools.javac.util.JCDiagnostic;
|
||||||
import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
|
import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
|
||||||
import com.sun.tools.javac.util.Log;
|
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;
|
import com.sun.tools.javac.util.Position;
|
||||||
|
|
||||||
/** A subtype of Log for use in APT.
|
/** A subtype of Log for use in APT.
|
||||||
@ -87,7 +87,7 @@ public class Bark extends Log {
|
|||||||
context.put(barkKey, this);
|
context.put(barkKey, this);
|
||||||
|
|
||||||
// register additional resource bundle for APT messages.
|
// 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");
|
aptMessages.add("com.sun.tools.apt.resources.apt");
|
||||||
aptDiags = new JCDiagnostic.Factory(aptMessages, "apt");
|
aptDiags = new JCDiagnostic.Factory(aptMessages, "apt");
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
package com.sun.tools.javac.api;
|
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
|
* This interface must be implemented by any javac class that has non-trivial
|
||||||
@ -39,10 +39,11 @@ public interface Formattable {
|
|||||||
* Used to obtain a localized String representing the object accordingly
|
* Used to obtain a localized String representing the object accordingly
|
||||||
* to a given locale
|
* 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
|
* @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
|
* Retrieve a pretty name of this object's kind
|
||||||
* @return a string representing the object's kind
|
* @return a string representing the object's kind
|
||||||
|
@ -68,6 +68,7 @@ public class JavacTaskImpl extends JavacTask {
|
|||||||
private JavacTool tool;
|
private JavacTool tool;
|
||||||
private Main compilerMain;
|
private Main compilerMain;
|
||||||
private JavaCompiler compiler;
|
private JavaCompiler compiler;
|
||||||
|
private Locale locale;
|
||||||
private String[] args;
|
private String[] args;
|
||||||
private Context context;
|
private Context context;
|
||||||
private List<JavaFileObject> fileObjects;
|
private List<JavaFileObject> fileObjects;
|
||||||
@ -89,6 +90,7 @@ public class JavacTaskImpl extends JavacTask {
|
|||||||
this.args = args;
|
this.args = args;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.fileObjects = fileObjects;
|
this.fileObjects = fileObjects;
|
||||||
|
setLocale(Locale.getDefault());
|
||||||
// null checks
|
// null checks
|
||||||
compilerMain.getClass();
|
compilerMain.getClass();
|
||||||
args.getClass();
|
args.getClass();
|
||||||
@ -156,9 +158,9 @@ public class JavacTaskImpl extends JavacTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setLocale(Locale locale) {
|
public void setLocale(Locale locale) {
|
||||||
// locale argument is ignored, see RFE 6443132
|
|
||||||
if (used.get())
|
if (used.get())
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
|
this.locale = locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareCompiler() throws IOException {
|
private void prepareCompiler() throws IOException {
|
||||||
@ -191,6 +193,8 @@ public class JavacTaskImpl extends JavacTask {
|
|||||||
if (taskListener != null)
|
if (taskListener != null)
|
||||||
context.put(TaskListener.class, wrap(taskListener));
|
context.put(TaskListener.class, wrap(taskListener));
|
||||||
tool.beginContext(context);
|
tool.beginContext(context);
|
||||||
|
//initialize compiler's default locale
|
||||||
|
JavacMessages.instance(context).setCurrentLocale(locale);
|
||||||
}
|
}
|
||||||
// where
|
// where
|
||||||
private TaskListener wrap(final TaskListener tl) {
|
private TaskListener wrap(final TaskListener tl) {
|
||||||
|
@ -49,6 +49,7 @@ import com.sun.tools.javac.main.RecognizedOptions.GrumpyHelper;
|
|||||||
import com.sun.tools.javac.main.RecognizedOptions;
|
import com.sun.tools.javac.main.RecognizedOptions;
|
||||||
import com.sun.tools.javac.util.Context;
|
import com.sun.tools.javac.util.Context;
|
||||||
import com.sun.tools.javac.util.Log;
|
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.Options;
|
||||||
import com.sun.tools.javac.util.Pair;
|
import com.sun.tools.javac.util.Pair;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
@ -144,6 +145,7 @@ public final class JavacTool implements JavaCompiler {
|
|||||||
Locale locale,
|
Locale locale,
|
||||||
Charset charset) {
|
Charset charset) {
|
||||||
Context context = new Context();
|
Context context = new Context();
|
||||||
|
JavacMessages.instance(context).setCurrentLocale(locale);
|
||||||
if (diagnosticListener != null)
|
if (diagnosticListener != null)
|
||||||
context.put(DiagnosticListener.class, diagnosticListener);
|
context.put(DiagnosticListener.class, diagnosticListener);
|
||||||
context.put(Log.outKey, new PrintWriter(System.err, true)); // FIXME
|
context.put(Log.outKey, new PrintWriter(System.err, true)); // FIXME
|
||||||
|
@ -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);
|
||||||
|
}
|
@ -26,9 +26,10 @@
|
|||||||
package com.sun.tools.javac.code;
|
package com.sun.tools.javac.code;
|
||||||
|
|
||||||
import java.util.EnumSet;
|
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.Formattable;
|
||||||
|
import com.sun.tools.javac.api.Messages;
|
||||||
|
|
||||||
import static com.sun.tools.javac.code.TypeTags.*;
|
import static com.sun.tools.javac.code.TypeTags.*;
|
||||||
import static com.sun.tools.javac.code.Flags.*;
|
import static com.sun.tools.javac.code.Flags.*;
|
||||||
@ -117,9 +118,9 @@ public class Kinds {
|
|||||||
return "Kindname";
|
return "Kindname";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString(ResourceBundle bundle) {
|
public String toString(Locale locale, Messages messages) {
|
||||||
String s = toString();
|
String s = toString();
|
||||||
return bundle.getString("compiler.misc." + s);
|
return messages.getLocalizedString(locale, "compiler.misc." + s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,7 +336,7 @@ public class Symtab {
|
|||||||
|
|
||||||
// create the basic builtin symbols
|
// create the basic builtin symbols
|
||||||
rootPackage = new PackageSymbol(names.empty, null);
|
rootPackage = new PackageSymbol(names.empty, null);
|
||||||
final Messages messages = Messages.instance(context);
|
final JavacMessages messages = JavacMessages.instance(context);
|
||||||
unnamedPackage = new PackageSymbol(names.empty, rootPackage) {
|
unnamedPackage = new PackageSymbol(names.empty, rootPackage) {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return messages.getLocalizedString("compiler.misc.unnamed.package");
|
return messages.getLocalizedString("compiler.misc.unnamed.package");
|
||||||
|
@ -67,7 +67,7 @@ public class Types {
|
|||||||
new Context.Key<Types>();
|
new Context.Key<Types>();
|
||||||
|
|
||||||
final Symtab syms;
|
final Symtab syms;
|
||||||
final Messages messages;
|
final JavacMessages messages;
|
||||||
final Names names;
|
final Names names;
|
||||||
final boolean allowBoxing;
|
final boolean allowBoxing;
|
||||||
final ClassReader reader;
|
final ClassReader reader;
|
||||||
@ -93,7 +93,7 @@ public class Types {
|
|||||||
source = Source.instance(context);
|
source = Source.instance(context);
|
||||||
chk = Check.instance(context);
|
chk = Check.instance(context);
|
||||||
capturedName = names.fromString("<captured wildcard>");
|
capturedName = names.fromString("<captured wildcard>");
|
||||||
messages = Messages.instance(context);
|
messages = JavacMessages.instance(context);
|
||||||
}
|
}
|
||||||
// </editor-fold>
|
// </editor-fold>
|
||||||
|
|
||||||
|
@ -484,7 +484,7 @@ public class Main {
|
|||||||
public static String getLocalizedString(String key, Object... args) { // FIXME sb private
|
public static String getLocalizedString(String key, Object... args) { // FIXME sb private
|
||||||
try {
|
try {
|
||||||
if (messages == null)
|
if (messages == null)
|
||||||
messages = new Messages(javacBundleName);
|
messages = new JavacMessages(javacBundleName);
|
||||||
return messages.getLocalizedString("javac." + key, args);
|
return messages.getLocalizedString("javac." + key, args);
|
||||||
}
|
}
|
||||||
catch (MissingResourceException e) {
|
catch (MissingResourceException e) {
|
||||||
@ -494,18 +494,18 @@ public class Main {
|
|||||||
|
|
||||||
public static void useRawMessages(boolean enable) {
|
public static void useRawMessages(boolean enable) {
|
||||||
if (enable) {
|
if (enable) {
|
||||||
messages = new Messages(javacBundleName) {
|
messages = new JavacMessages(javacBundleName) {
|
||||||
public String getLocalizedString(String key, Object... args) {
|
public String getLocalizedString(String key, Object... args) {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
messages = new Messages(javacBundleName);
|
messages = new JavacMessages(javacBundleName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String javacBundleName =
|
private static final String javacBundleName =
|
||||||
"com.sun.tools.javac.resources.javac";
|
"com.sun.tools.javac.resources.javac";
|
||||||
|
|
||||||
private static Messages messages;
|
private static JavacMessages messages;
|
||||||
}
|
}
|
||||||
|
@ -25,9 +25,10 @@
|
|||||||
|
|
||||||
package com.sun.tools.javac.parser;
|
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.Formattable;
|
||||||
|
import com.sun.tools.javac.api.Messages;
|
||||||
|
|
||||||
/** An interface that defines codes for Java source tokens
|
/** An interface that defines codes for Java source tokens
|
||||||
* returned from lexical analysis.
|
* returned from lexical analysis.
|
||||||
@ -191,8 +192,7 @@ public enum Token implements Formattable {
|
|||||||
return "Token";
|
return "Token";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString(ResourceBundle bundle) {
|
public String toString(Locale locale, Messages messages) {
|
||||||
String s = toString();
|
return name != null ? toString() : messages.getLocalizedString(locale, "compiler.misc." + toString());
|
||||||
return s.startsWith("token.") ? bundle.getString("compiler.misc." + s) : s;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,7 @@ import com.sun.tools.javac.util.Context;
|
|||||||
import com.sun.tools.javac.util.List;
|
import com.sun.tools.javac.util.List;
|
||||||
import com.sun.tools.javac.util.ListBuffer;
|
import com.sun.tools.javac.util.ListBuffer;
|
||||||
import com.sun.tools.javac.util.Log;
|
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.Name;
|
||||||
import com.sun.tools.javac.util.Names;
|
import com.sun.tools.javac.util.Names;
|
||||||
import com.sun.tools.javac.util.Options;
|
import com.sun.tools.javac.util.Options;
|
||||||
@ -133,9 +134,14 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
|||||||
*/
|
*/
|
||||||
Source source;
|
Source source;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JavacMessages object used for localization
|
||||||
|
*/
|
||||||
|
private JavacMessages messages;
|
||||||
|
|
||||||
private Context context;
|
private Context context;
|
||||||
|
|
||||||
public JavacProcessingEnvironment(Context context, Iterable<? extends Processor> processors) {
|
public JavacProcessingEnvironment(Context context, Iterable<? extends Processor> processors) {
|
||||||
options = Options.instance(context);
|
options = Options.instance(context);
|
||||||
this.context = context;
|
this.context = context;
|
||||||
log = Log.instance(context);
|
log = Log.instance(context);
|
||||||
@ -157,6 +163,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
|||||||
typeUtils = new JavacTypes(context);
|
typeUtils = new JavacTypes(context);
|
||||||
processorOptions = initProcessorOptions(context);
|
processorOptions = initProcessorOptions(context);
|
||||||
unmatchedProcessorOptions = initUnmatchedProcessorOptions();
|
unmatchedProcessorOptions = initUnmatchedProcessorOptions();
|
||||||
|
messages = JavacMessages.instance(context);
|
||||||
initProcessorIterator(context, processors);
|
initProcessorIterator(context, processors);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1246,7 +1253,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Locale getLocale() {
|
public Locale getLocale() {
|
||||||
return Locale.getDefault();
|
return messages.getCurrentLocale();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Symbol.PackageSymbol> getSpecifiedPackages() {
|
public Set<Symbol.PackageSymbol> getSpecifiedPackages() {
|
||||||
|
@ -27,6 +27,7 @@ package com.sun.tools.javac.util;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
import com.sun.tools.javac.api.DiagnosticFormatter;
|
import com.sun.tools.javac.api.DiagnosticFormatter;
|
||||||
import com.sun.tools.javac.api.Formattable;
|
import com.sun.tools.javac.api.Formattable;
|
||||||
@ -48,15 +49,15 @@ import com.sun.tools.javac.file.JavacFileManager;
|
|||||||
public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter<JCDiagnostic> {
|
public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter<JCDiagnostic> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
* @param messages
|
||||||
*/
|
*/
|
||||||
protected AbstractDiagnosticFormatter(Messages messages) {
|
protected AbstractDiagnosticFormatter(JavacMessages messages) {
|
||||||
this.messages = messages;
|
this.messages = messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +132,7 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
|
|||||||
else if (arg instanceof JavaFileObject)
|
else if (arg instanceof JavaFileObject)
|
||||||
return JavacFileManager.getJavacBaseFileName((JavaFileObject)arg);
|
return JavacFileManager.getJavacBaseFileName((JavaFileObject)arg);
|
||||||
else if (arg instanceof Formattable)
|
else if (arg instanceof Formattable)
|
||||||
return ((Formattable)arg).toString(Messages.getDefaultBundle());
|
return ((Formattable)arg).toString(l, messages);
|
||||||
else
|
else
|
||||||
return String.valueOf(arg);
|
return String.valueOf(arg);
|
||||||
}
|
}
|
||||||
@ -164,6 +165,6 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
|
|||||||
* @return a locale-dependent string
|
* @return a locale-dependent string
|
||||||
*/
|
*/
|
||||||
protected String localize(Locale l, String key, Object... args) {
|
protected String localize(Locale l, String key, Object... args) {
|
||||||
return messages.getLocalizedString(key, args);
|
return messages.getLocalizedString(l, key, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,9 +59,9 @@ public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter {
|
|||||||
* Create a basic formatter based on the supplied options.
|
* Create a basic formatter based on the supplied options.
|
||||||
*
|
*
|
||||||
* @param opts list of command-line 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
|
this(msgs); //common init
|
||||||
String fmt = opts.get("diags");
|
String fmt = opts.get("diags");
|
||||||
if (fmt != null) {
|
if (fmt != null) {
|
||||||
@ -80,9 +80,9 @@ public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter {
|
|||||||
/**
|
/**
|
||||||
* Create a standard basic formatter
|
* 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);
|
super(msgs);
|
||||||
availableFormats = new HashMap<BasicFormatKind, String>();
|
availableFormats = new HashMap<BasicFormatKind, String>();
|
||||||
availableFormats.put(DEFAULT_POS_FORMAT, "%f:%l:%_%t%m");
|
availableFormats.put(DEFAULT_POS_FORMAT, "%f:%l:%_%t%m");
|
||||||
@ -91,6 +91,8 @@ public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String format(JCDiagnostic d, Locale l) {
|
public String format(JCDiagnostic d, Locale l) {
|
||||||
|
if (l == null)
|
||||||
|
l = messages.getCurrentLocale();
|
||||||
String format = selectFormat(d);
|
String format = selectFormat(d);
|
||||||
StringBuilder buf = new StringBuilder();
|
StringBuilder buf = new StringBuilder();
|
||||||
for (int i = 0; i < format.length(); i++) {
|
for (int i = 0; i < format.length(); i++) {
|
||||||
|
@ -64,12 +64,12 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
|
|||||||
|
|
||||||
/** Create a new diagnostic factory. */
|
/** Create a new diagnostic factory. */
|
||||||
protected Factory(Context context) {
|
protected Factory(Context context) {
|
||||||
this(Messages.instance(context), "compiler");
|
this(JavacMessages.instance(context), "compiler");
|
||||||
context.put(diagnosticFactoryKey, this);
|
context.put(diagnosticFactoryKey, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a new diagnostic factory. */
|
/** Create a new diagnostic factory. */
|
||||||
public Factory(Messages messages, String prefix) {
|
public Factory(JavacMessages messages, String prefix) {
|
||||||
this.prefix = prefix;
|
this.prefix = prefix;
|
||||||
this.formatter = new BasicDiagnosticFormatter(messages);
|
this.formatter = new BasicDiagnosticFormatter(messages);
|
||||||
}
|
}
|
||||||
@ -178,7 +178,7 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
public static DiagnosticFormatter<JCDiagnostic> getFragmentFormatter() {
|
public static DiagnosticFormatter<JCDiagnostic> getFragmentFormatter() {
|
||||||
if (fragmentFormatter == null) {
|
if (fragmentFormatter == null) {
|
||||||
fragmentFormatter = new BasicDiagnosticFormatter(Messages.getDefaultMessages());
|
fragmentFormatter = new BasicDiagnosticFormatter(JavacMessages.getDefaultMessages());
|
||||||
}
|
}
|
||||||
return fragmentFormatter;
|
return fragmentFormatter;
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
*
|
||||||
|
* <p><b>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.</b>
|
||||||
|
*/
|
||||||
|
public class JavacMessages implements Messages {
|
||||||
|
/** The context key for the JavacMessages object. */
|
||||||
|
protected static final Context.Key<JavacMessages> messagesKey =
|
||||||
|
new Context.Key<JavacMessages>();
|
||||||
|
|
||||||
|
/** 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<Locale, SoftReference<List<ResourceBundle>>> bundleCache;
|
||||||
|
|
||||||
|
private List<String> bundleNames;
|
||||||
|
|
||||||
|
private Locale currentLocale;
|
||||||
|
private List<ResourceBundle> 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<Locale, SoftReference<List<ResourceBundle>>>();
|
||||||
|
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<ResourceBundle> getBundles(Locale locale) {
|
||||||
|
if (locale == currentLocale)
|
||||||
|
return currentBundles;
|
||||||
|
SoftReference<List<ResourceBundle>> bundles = bundleCache.get(locale);
|
||||||
|
List<ResourceBundle> 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<List<ResourceBundle>>(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<ResourceBundle> bundles,
|
||||||
|
String key,
|
||||||
|
Object... args) {
|
||||||
|
String msg = null;
|
||||||
|
for (List<ResourceBundle> 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);
|
||||||
|
}
|
||||||
|
}
|
@ -29,7 +29,6 @@ import java.io.*;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Locale;
|
|
||||||
import javax.tools.DiagnosticListener;
|
import javax.tools.DiagnosticListener;
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
|
|
||||||
@ -97,6 +96,11 @@ public class Log extends AbstractLog {
|
|||||||
*/
|
*/
|
||||||
private DiagnosticFormatter<JCDiagnostic> diagFormatter;
|
private DiagnosticFormatter<JCDiagnostic> diagFormatter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JavacMessages object used for localization
|
||||||
|
*/
|
||||||
|
private JavacMessages messages;
|
||||||
|
|
||||||
/** Construct a log with given I/O redirections.
|
/** Construct a log with given I/O redirections.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ -115,9 +119,9 @@ public class Log extends AbstractLog {
|
|||||||
this.MaxWarnings = getIntOption(options, "-Xmaxwarns", 100);
|
this.MaxWarnings = getIntOption(options, "-Xmaxwarns", 100);
|
||||||
|
|
||||||
boolean rawDiagnostics = options.get("rawDiagnostics") != null;
|
boolean rawDiagnostics = options.get("rawDiagnostics") != null;
|
||||||
Messages msgs = Messages.instance(context);
|
messages = JavacMessages.instance(context);
|
||||||
this.diagFormatter = rawDiagnostics ? new RawDiagnosticFormatter(msgs) :
|
this.diagFormatter = rawDiagnostics ? new RawDiagnosticFormatter(messages) :
|
||||||
new BasicDiagnosticFormatter(options, msgs);
|
new BasicDiagnosticFormatter(options, messages);
|
||||||
@SuppressWarnings("unchecked") // FIXME
|
@SuppressWarnings("unchecked") // FIXME
|
||||||
DiagnosticListener<? super JavaFileObject> diagListener =
|
DiagnosticListener<? super JavaFileObject> diagListener =
|
||||||
context.get(DiagnosticListener.class);
|
context.get(DiagnosticListener.class);
|
||||||
@ -335,7 +339,7 @@ public class Log extends AbstractLog {
|
|||||||
|
|
||||||
PrintWriter writer = getWriterForDiagnosticType(diag.getType());
|
PrintWriter writer = getWriterForDiagnosticType(diag.getType());
|
||||||
|
|
||||||
printLines(writer, diagFormatter.format(diag, Locale.getDefault()));
|
printLines(writer, diagFormatter.format(diag, messages.getCurrentLocale()));
|
||||||
if (diagFormatter.displaySource(diag)) {
|
if (diagFormatter.displaySource(diag)) {
|
||||||
int pos = diag.getIntPosition();
|
int pos = diag.getIntPosition();
|
||||||
if (pos != Position.NOPOS) {
|
if (pos != Position.NOPOS) {
|
||||||
@ -384,7 +388,7 @@ public class Log extends AbstractLog {
|
|||||||
* @param args Fields to substitute into the string.
|
* @param args Fields to substitute into the string.
|
||||||
*/
|
*/
|
||||||
public static String getLocalizedString(String key, Object ... args) {
|
public static String getLocalizedString(String key, Object ... args) {
|
||||||
return Messages.getDefaultLocalizedString("compiler.misc." + key, args);
|
return JavacMessages.getDefaultLocalizedString("compiler.misc." + key, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
|
@ -41,7 +41,7 @@ public class RawDiagnosticFormatter extends AbstractDiagnosticFormatter {
|
|||||||
* Create a formatter based on the supplied options.
|
* Create a formatter based on the supplied options.
|
||||||
* @param msgs
|
* @param msgs
|
||||||
*/
|
*/
|
||||||
public RawDiagnosticFormatter(Messages msgs) {
|
public RawDiagnosticFormatter(JavacMessages msgs) {
|
||||||
super(null);
|
super(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ import javax.lang.model.element.Element;
|
|||||||
import com.sun.tools.javac.api.JavacTaskImpl;
|
import com.sun.tools.javac.api.JavacTaskImpl;
|
||||||
import com.sun.tools.javac.util.Context;
|
import com.sun.tools.javac.util.Context;
|
||||||
import com.sun.tools.javac.util.List;
|
import com.sun.tools.javac.util.List;
|
||||||
import com.sun.tools.javac.util.Messages;
|
import com.sun.tools.javac.util.JavacMessages;
|
||||||
|
|
||||||
import javax.tools.*;
|
import javax.tools.*;
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ public class T6457284 {
|
|||||||
throw new AssertionError("No top-level classes!");
|
throw new AssertionError("No top-level classes!");
|
||||||
}
|
}
|
||||||
|
|
||||||
static class MyMessages extends Messages {
|
static class MyMessages extends JavacMessages {
|
||||||
static void preRegister(Context context) {
|
static void preRegister(Context context) {
|
||||||
context.put(messagesKey, new MyMessages());
|
context.put(messagesKey, new MyMessages());
|
||||||
}
|
}
|
||||||
|
4
langtools/test/tools/javac/api/6406133/Erroneous.java
Normal file
4
langtools/test/tools/javac/api/6406133/Erroneous.java
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
@Deprecated
|
||||||
|
class A {
|
||||||
|
class A {}
|
||||||
|
}
|
109
langtools/test/tools/javac/api/6406133/T6406133.java
Normal file
109
langtools/test/tools/javac/api/6406133/T6406133.java
Normal file
@ -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<Locale> locales = Arrays.asList(Locale.US, Locale.JAPAN, Locale.CHINA);
|
||||||
|
|
||||||
|
class DiagnosticTester implements DiagnosticListener<JavaFileObject> {
|
||||||
|
Locale locale;
|
||||||
|
String result;
|
||||||
|
|
||||||
|
DiagnosticTester(Locale locale) {
|
||||||
|
this.locale = locale;
|
||||||
|
}
|
||||||
|
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
|
||||||
|
result = diagnostic.getMessage(locale); //6406133
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ProcessorTester extends AbstractProcessor {
|
||||||
|
|
||||||
|
Locale locale;
|
||||||
|
|
||||||
|
public Set<String> getSupportedAnnotationTypes() {
|
||||||
|
return new HashSet<String>(Arrays.asList("*"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(ProcessingEnvironment env) {
|
||||||
|
locale = env.getLocale();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean process(Set<? extends TypeElement> 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<? extends JavaFileObject> 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();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user