8003967: detect and remove all mutable implicit static enum fields in langtools

Reviewed-by: jjg
This commit is contained in:
Vicente Romero 2012-12-10 16:21:26 +00:00
parent 5c0bff8f21
commit 8fc2d739bd
31 changed files with 333 additions and 128 deletions

View file

@ -448,10 +448,10 @@ public enum Opcode {
} }
private static Opcode[] stdOpcodes = new Opcode[256]; private static final Opcode[] stdOpcodes = new Opcode[256];
private static Opcode[] wideOpcodes = new Opcode[256]; private static final Opcode[] wideOpcodes = new Opcode[256];
private static Opcode[] nonPrivOpcodes = new Opcode[256]; private static final Opcode[] nonPrivOpcodes = new Opcode[256];
private static Opcode[] privOpcodes = new Opcode[256]; private static final Opcode[] privOpcodes = new Opcode[256];
static { static {
for (Opcode o: values()) for (Opcode o: values())
getOpcodeBlock(o.opcode >> 8)[o.opcode & 0xff] = o; getOpcodeBlock(o.opcode >> 8)[o.opcode & 0xff] = o;

View file

@ -46,7 +46,7 @@ import com.sun.tools.doclets.internal.toolkit.Configuration;
* @since 1.8 * @since 1.8
*/ */
abstract class DocFileFactory { abstract class DocFileFactory {
private static Map<Configuration, DocFileFactory> factories = private static final Map<Configuration, DocFileFactory> factories =
new WeakHashMap<Configuration, DocFileFactory>(); new WeakHashMap<Configuration, DocFileFactory>();
/** /**

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -49,7 +49,7 @@ class Server implements Runnable {
private final OutputStream out; private final OutputStream out;
private final boolean isSocket; private final boolean isSocket;
private static final JavaCompiler tool = ToolProvider.getSystemJavaCompiler(); private static final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
private static Logger logger = Logger.getLogger("com.sun.tools.javac"); private static final Logger logger = Logger.getLogger("com.sun.tools.javac");
static class CwdFileManager extends ForwardingJavaFileManager<JavaFileManager> { static class CwdFileManager extends ForwardingJavaFileManager<JavaFileManager> {
String cwd; String cwd;
CwdFileManager(JavaFileManager fileManager) { CwdFileManager(JavaFileManager fileManager) {
@ -69,7 +69,7 @@ class Server implements Runnable {
// } // }
} }
// static CwdFileManager fm = new CwdFileManager(tool.getStandardFileManager()); // static CwdFileManager fm = new CwdFileManager(tool.getStandardFileManager());
static StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); static final StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
static { static {
// Use the same file manager for all compilations. This will // Use the same file manager for all compilations. This will
// cache jar files in the standard file manager. Use // cache jar files in the standard file manager. Use

View file

@ -307,7 +307,7 @@ public class Flags {
} }
// Cache of modifier sets. // Cache of modifier sets.
private static Map<Long, Set<Modifier>> modifierSets = private static final Map<Long, Set<Modifier>> modifierSets =
new java.util.concurrent.ConcurrentHashMap<Long, Set<Modifier>>(64); new java.util.concurrent.ConcurrentHashMap<Long, Set<Modifier>>(64);
public static boolean isStatic(Symbol symbol) { public static boolean isStatic(Symbol symbol) {
@ -356,7 +356,7 @@ public class Flags {
VARARGS("varargs"), VARARGS("varargs"),
PACKAGE("package"); PACKAGE("package");
String name; private final String name;
Flag(String name) { Flag(String name) {
this.name = name; this.name = name;

View file

@ -110,7 +110,7 @@ public class Kinds {
INSTANCE_INIT("kindname.instance.init"), INSTANCE_INIT("kindname.instance.init"),
PACKAGE("kindname.package"); PACKAGE("kindname.package");
private String name; private final String name;
KindName(String name) { KindName(String name) {
this.name = name; this.name = name;

View file

@ -28,11 +28,14 @@ package com.sun.tools.javac.code;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import javax.lang.model.element.Modifier;
import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Symbol.*;
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.Options; import com.sun.tools.javac.util.Options;
import com.sun.tools.javac.util.Pair; import com.sun.tools.javac.util.Pair;
import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Flags.*;
@ -95,7 +98,8 @@ public class Lint
private final EnumSet<LintCategory> values; private final EnumSet<LintCategory> values;
private final EnumSet<LintCategory> suppressedValues; private final EnumSet<LintCategory> suppressedValues;
private static Map<String, LintCategory> map = new HashMap<String,LintCategory>(); private static final Map<String, LintCategory> map =
new java.util.concurrent.ConcurrentHashMap<String, LintCategory>(20);
protected Lint(Context context) { protected Lint(Context context) {

View file

@ -87,7 +87,7 @@ public enum Source {
public final String name; public final String name;
private static Map<String,Source> tab = new HashMap<String,Source>(); private static final Map<String,Source> tab = new HashMap<String,Source>();
static { static {
for (Source s : values()) { for (Source s : values()) {
tab.put(s.name, s); tab.put(s.name, s);

View file

@ -166,7 +166,7 @@ public enum TargetType {
static final int MAXIMUM_TARGET_TYPE_VALUE = 0x22; static final int MAXIMUM_TARGET_TYPE_VALUE = 0x22;
private final int targetTypeValue; private final int targetTypeValue;
private Set<TargetAttribute> flags; private final Set<TargetAttribute> flags;
TargetType(int targetTypeValue, TargetAttribute... attributes) { TargetType(int targetTypeValue, TargetAttribute... attributes) {
if (targetTypeValue < Byte.MIN_VALUE if (targetTypeValue < Byte.MIN_VALUE
@ -233,10 +233,10 @@ public enum TargetType {
return this.targetTypeValue; return this.targetTypeValue;
} }
private static TargetType[] targets = null; private static final TargetType[] targets;
private static TargetType[] buildTargets() { static {
TargetType[] targets = new TargetType[MAXIMUM_TARGET_TYPE_VALUE + 1]; targets = new TargetType[MAXIMUM_TARGET_TYPE_VALUE + 1];
TargetType[] alltargets = values(); TargetType[] alltargets = values();
for (TargetType target : alltargets) { for (TargetType target : alltargets) {
if (target.targetTypeValue >= 0) if (target.targetTypeValue >= 0)
@ -246,13 +246,9 @@ public enum TargetType {
if (targets[i] == null) if (targets[i] == null)
targets[i] = UNKNOWN; targets[i] = UNKNOWN;
} }
return targets;
} }
public static boolean isValidTargetTypeValue(int tag) { public static boolean isValidTargetTypeValue(int tag) {
if (targets == null)
targets = buildTargets();
if (((byte)tag) == ((byte)UNKNOWN.targetTypeValue)) if (((byte)tag) == ((byte)UNKNOWN.targetTypeValue))
return true; return true;
@ -260,9 +256,6 @@ public enum TargetType {
} }
public static TargetType fromTargetTypeValue(int tag) { public static TargetType fromTargetTypeValue(int tag) {
if (targets == null)
targets = buildTargets();
if (((byte)tag) == ((byte)UNKNOWN.targetTypeValue)) if (((byte)tag) == ((byte)UNKNOWN.targetTypeValue))
return UNKNOWN; return UNKNOWN;

View file

@ -135,9 +135,11 @@ public enum TypeTag {
/** This field will only be used for tags related with numeric types for /** This field will only be used for tags related with numeric types for
* optimization reasons. * optimization reasons.
*/ */
private int order = 0; private final int order;
private TypeTag() {} private TypeTag() {
this(0);
}
private TypeTag(int order) { private TypeTag(int order) {
this.order = order; this.order = order;

View file

@ -2849,7 +2849,7 @@ public class Types {
} }
return tvars1; return tvars1;
} }
static private Mapping newInstanceFun = new Mapping("newInstanceFun") { private static final Mapping newInstanceFun = new Mapping("newInstanceFun") {
public Type apply(Type t) { return new TypeVar(t.tsym, t.getUpperBound(), t.getLowerBound()); } public Type apply(Type t) { return new TypeVar(t.tsym, t.getUpperBound(), t.getLowerBound()); }
}; };
// </editor-fold> // </editor-fold>

View file

@ -62,9 +62,9 @@ strictfp class ConstFold {
syms = Symtab.instance(context); syms = Symtab.instance(context);
} }
static Integer minusOne = -1; static final Integer minusOne = -1;
static Integer zero = 0; static final Integer zero = 0;
static Integer one = 1; static final Integer one = 1;
/** Convert boolean to integer (true = 1, false = 0). /** Convert boolean to integer (true = 1, false = 0).
*/ */

View file

@ -246,8 +246,8 @@ public class Flow {
*/ */
SPECULATIVE_LOOP("var.might.be.assigned.in.loop", true); SPECULATIVE_LOOP("var.might.be.assigned.in.loop", true);
String errKey; final String errKey;
boolean isFinal; final boolean isFinal;
FlowKind(String errKey, boolean isFinal) { FlowKind(String errKey, boolean isFinal) {
this.errKey = errKey; this.errKey = errKey;
@ -295,7 +295,7 @@ public class Flow {
} }
}; };
JCTree.Tag treeTag; final JCTree.Tag treeTag;
private JumpKind(Tag treeTag) { private JumpKind(Tag treeTag) {
this.treeTag = treeTag; this.treeTag = treeTag;

View file

@ -156,7 +156,7 @@ public class Resolve {
OBJECT_INIT("object-init"), OBJECT_INIT("object-init"),
INTERNAL("internal"); INTERNAL("internal");
String opt; final String opt;
private VerboseResolutionMode(String opt) { private VerboseResolutionMode(String opt) {
this.opt = opt; this.opt = opt;
@ -3381,8 +3381,8 @@ public class Resolve {
} }
}; };
boolean isBoxingRequired; final boolean isBoxingRequired;
boolean isVarargsRequired; final boolean isVarargsRequired;
MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) { MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) {
this.isBoxingRequired = isBoxingRequired; this.isBoxingRequired = isBoxingRequired;

View file

@ -83,7 +83,7 @@ public class ZipFileIndex {
public final static long NOT_MODIFIED = Long.MIN_VALUE; public final static long NOT_MODIFIED = Long.MIN_VALUE;
private static boolean NON_BATCH_MODE = System.getProperty("nonBatchMode") != null;// TODO: Use -XD compiler switch for this. private static final boolean NON_BATCH_MODE = System.getProperty("nonBatchMode") != null;// TODO: Use -XD compiler switch for this.
private Map<RelativeDirectory, DirectoryEntry> directories = private Map<RelativeDirectory, DirectoryEntry> directories =
Collections.<RelativeDirectory, DirectoryEntry>emptyMap(); Collections.<RelativeDirectory, DirectoryEntry>emptyMap();

View file

@ -1825,7 +1825,7 @@ public class Code {
} }
} }
static Type jsrReturnValue = new Type(INT, null); static final Type jsrReturnValue = new Type(INT, null);
/* ************************************************************************** /* **************************************************************************

View file

@ -86,17 +86,15 @@ public enum Target {
return instance; return instance;
} }
private static Target MIN; private static final Target MIN = values()[0];
public static Target MIN() { return MIN; } public static Target MIN() { return MIN; }
private static Target MAX; private static final Target MAX = values()[values().length - 1];
public static Target MAX() { return MAX; } public static Target MAX() { return MAX; }
private static Map<String,Target> tab = new HashMap<String,Target>(); private static final Map<String,Target> tab = new HashMap<String,Target>();
static { static {
for (Target t : values()) { for (Target t : values()) {
if (MIN == null) MIN = t;
MAX = t;
tab.put(t.name, t); tab.put(t.name, t);
} }
tab.put("5", JDK1_5); tab.put("5", JDK1_5);

View file

@ -189,7 +189,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
} }
} }
private static CompilePolicy DEFAULT_COMPILE_POLICY = CompilePolicy.BY_TODO; private static final CompilePolicy DEFAULT_COMPILE_POLICY = CompilePolicy.BY_TODO;
protected static enum ImplicitSourcePolicy { protected static enum ImplicitSourcePolicy {
/** Don't generate or process implicitly read source files. */ /** Don't generate or process implicitly read source files. */
@ -543,7 +543,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
public static CompileState max(CompileState a, CompileState b) { public static CompileState max(CompileState a, CompileState b) {
return a.value > b.value ? a : b; return a.value > b.value ? a : b;
} }
private int value; private final int value;
}; };
/** Partial map to record which compiler phases have been executed /** Partial map to record which compiler phases have been executed
* for each compilation unit. Used for ATTR and FLOW phases. * for each compilation unit. Used for ATTR and FLOW phases.

View file

@ -167,7 +167,6 @@ public enum Option {
ENCODING("-encoding", "opt.arg.encoding", "opt.encoding", STANDARD, FILEMANAGER) { ENCODING("-encoding", "opt.arg.encoding", "opt.encoding", STANDARD, FILEMANAGER) {
@Override @Override
public boolean process(OptionHelper helper, String option, String operand) { public boolean process(OptionHelper helper, String option, String operand) {
// System.err.println("process encoding " + operand);
return super.process(helper, option, operand); return super.process(helper, option, operand);
} }
@ -246,9 +245,7 @@ public enum Option {
} }
}, },
A("-A", "opt.arg.key.equals.value", "opt.A", STANDARD, BASIC) { A("-A", "opt.arg.key.equals.value", "opt.A", STANDARD, BASIC, true) {
{ hasSuffix = true; }
@Override @Override
public boolean matches(String arg) { public boolean matches(String arg) {
return arg.startsWith("-A"); return arg.startsWith("-A");
@ -293,8 +290,6 @@ public enum Option {
// This option exists only for the purpose of documenting itself. // This option exists only for the purpose of documenting itself.
// It's actually implemented by the launcher. // It's actually implemented by the launcher.
J("-J", "opt.arg.flag", "opt.J", STANDARD, INFO) { J("-J", "opt.arg.flag", "opt.J", STANDARD, INFO) {
{ hasSuffix = true; }
@Override @Override
public boolean process(OptionHelper helper, String option) { public boolean process(OptionHelper helper, String option) {
throw new AssertionError throw new AssertionError
@ -302,10 +297,6 @@ public enum Option {
} }
}, },
// stop after parsing and attributing.
// new HiddenOption("-attrparseonly"),
// new Option("-moreinfo", "opt.moreinfo") {
MOREINFO("-moreinfo", null, HIDDEN, BASIC) { MOREINFO("-moreinfo", null, HIDDEN, BASIC) {
@Override @Override
public boolean process(OptionHelper helper, String option) { public boolean process(OptionHelper helper, String option) {
@ -317,23 +308,6 @@ public enum Option {
// treat warnings as errors // treat warnings as errors
WERROR("-Werror", "opt.Werror", STANDARD, BASIC), WERROR("-Werror", "opt.Werror", STANDARD, BASIC),
// // use complex inference from context in the position of a method call argument
// COMPLEXINFERENCE("-complexinference", null, HIDDEN, BASIC),
// generare source stubs
// new HiddenOption("-stubs"),
// relax some constraints to allow compiling from stubs
// new HiddenOption("-relax"),
// output source after translating away inner classes
// new Option("-printflat", "opt.printflat"),
// new HiddenOption("-printflat"),
// display scope search details
// new Option("-printsearch", "opt.printsearch"),
// new HiddenOption("-printsearch"),
// prompt after each error // prompt after each error
// new Option("-prompt", "opt.prompt"), // new Option("-prompt", "opt.prompt"),
PROMPT("-prompt", null, HIDDEN, BASIC), PROMPT("-prompt", null, HIDDEN, BASIC),
@ -342,13 +316,8 @@ public enum Option {
DOE("-doe", null, HIDDEN, BASIC), DOE("-doe", null, HIDDEN, BASIC),
// output source after type erasure // output source after type erasure
// new Option("-s", "opt.s"),
PRINTSOURCE("-printsource", null, HIDDEN, BASIC), PRINTSOURCE("-printsource", null, HIDDEN, BASIC),
// output shrouded class files
// new Option("-scramble", "opt.scramble"),
// new Option("-scrambleall", "opt.scrambleall"),
// display warnings for generic unchecked operations // display warnings for generic unchecked operations
WARNUNCHECKED("-warnunchecked", null, HIDDEN, BASIC) { WARNUNCHECKED("-warnunchecked", null, HIDDEN, BASIC) {
@Override @Override
@ -408,18 +377,16 @@ public enum Option {
* -XDx sets the option x to the value x. * -XDx sets the option x to the value x.
*/ */
XD("-XD", null, HIDDEN, BASIC) { XD("-XD", null, HIDDEN, BASIC) {
String s;
@Override @Override
public boolean matches(String s) { public boolean matches(String s) {
this.s = s;
return s.startsWith(text); return s.startsWith(text);
} }
@Override @Override
public boolean process(OptionHelper helper, String option) { public boolean process(OptionHelper helper, String option) {
s = s.substring(text.length()); option = option.substring(text.length());
int eq = s.indexOf('='); int eq = option.indexOf('=');
String key = (eq < 0) ? s : s.substring(0, eq); String key = (eq < 0) ? option : option.substring(0, eq);
String value = (eq < 0) ? s : s.substring(eq+1); String value = (eq < 0) ? option : option.substring(eq+1);
helper.put(key, value); helper.put(key, value);
return false; return false;
} }
@ -428,8 +395,6 @@ public enum Option {
// This option exists only for the purpose of documenting itself. // This option exists only for the purpose of documenting itself.
// It's actually implemented by the CommandLine class. // It's actually implemented by the CommandLine class.
AT("@", "opt.arg.file", "opt.AT", STANDARD, INFO) { AT("@", "opt.arg.file", "opt.AT", STANDARD, INFO) {
{ hasSuffix = true; }
@Override @Override
public boolean process(OptionHelper helper, String option) { public boolean process(OptionHelper helper, String option) {
throw new AssertionError("the @ flag should be caught by CommandLine."); throw new AssertionError("the @ flag should be caught by CommandLine.");
@ -445,17 +410,15 @@ public enum Option {
* name to a separate list. * name to a separate list.
*/ */
SOURCEFILE("sourcefile", null, HIDDEN, INFO) { SOURCEFILE("sourcefile", null, HIDDEN, INFO) {
String s;
@Override @Override
public boolean matches(String s) { public boolean matches(String s) {
this.s = s;
return s.endsWith(".java") // Java source file return s.endsWith(".java") // Java source file
|| SourceVersion.isName(s); // Legal type name || SourceVersion.isName(s); // Legal type name
} }
@Override @Override
public boolean process(OptionHelper helper, String option) { public boolean process(OptionHelper helper, String option) {
if (s.endsWith(".java") ) { if (option.endsWith(".java") ) {
File f = new File(s); File f = new File(option);
if (!f.exists()) { if (!f.exists()) {
helper.error("err.file.not.found", f); helper.error("err.file.not.found", f);
return true; return true;
@ -465,9 +428,9 @@ public enum Option {
return true; return true;
} }
helper.addFile(f); helper.addFile(f);
} else {
helper.addClassName(option);
} }
else
helper.addClassName(s);
return false; return false;
} }
}; };
@ -521,7 +484,7 @@ public enum Option {
/** Suffix option (-foo=bar or -foo:bar) /** Suffix option (-foo=bar or -foo:bar)
*/ */
boolean hasSuffix; final boolean hasSuffix;
/** The kind of choices for this option, if any. /** The kind of choices for this option, if any.
*/ */
@ -535,24 +498,30 @@ public enum Option {
Option(String text, String descrKey, Option(String text, String descrKey,
OptionKind kind, OptionGroup group) { OptionKind kind, OptionGroup group) {
this(text, null, descrKey, kind, group, null, null); this(text, null, descrKey, kind, group, null, null, false);
} }
Option(String text, String argsNameKey, String descrKey, Option(String text, String argsNameKey, String descrKey,
OptionKind kind, OptionGroup group) { OptionKind kind, OptionGroup group) {
this(text, argsNameKey, descrKey, kind, group, null, null); this(text, argsNameKey, descrKey, kind, group, null, null, false);
}
Option(String text, String argsNameKey, String descrKey,
OptionKind kind, OptionGroup group, boolean doHasSuffix) {
this(text, argsNameKey, descrKey, kind, group, null, null, doHasSuffix);
} }
Option(String text, String descrKey, Option(String text, String descrKey,
OptionKind kind, OptionGroup group, OptionKind kind, OptionGroup group,
ChoiceKind choiceKind, Map<String,Boolean> choices) { ChoiceKind choiceKind, Map<String,Boolean> choices) {
this(text, null, descrKey, kind, group, choiceKind, choices); this(text, null, descrKey, kind, group, choiceKind, choices, false);
} }
Option(String text, String descrKey, Option(String text, String descrKey,
OptionKind kind, OptionGroup group, OptionKind kind, OptionGroup group,
ChoiceKind choiceKind, String... choices) { ChoiceKind choiceKind, String... choices) {
this(text, null, descrKey, kind, group, choiceKind, createChoices(choices)); this(text, null, descrKey, kind, group, choiceKind,
createChoices(choices), false);
} }
// where // where
private static Map<String,Boolean> createChoices(String... choices) { private static Map<String,Boolean> createChoices(String... choices) {
@ -564,7 +533,8 @@ public enum Option {
private Option(String text, String argsNameKey, String descrKey, private Option(String text, String argsNameKey, String descrKey,
OptionKind kind, OptionGroup group, OptionKind kind, OptionGroup group,
ChoiceKind choiceKind, Map<String,Boolean> choices) { ChoiceKind choiceKind, Map<String,Boolean> choices,
boolean doHasSuffix) {
this.text = text; this.text = text;
this.argsNameKey = argsNameKey; this.argsNameKey = argsNameKey;
this.descrKey = descrKey; this.descrKey = descrKey;
@ -573,7 +543,7 @@ public enum Option {
this.choiceKind = choiceKind; this.choiceKind = choiceKind;
this.choices = choices; this.choices = choices;
char lastChar = text.charAt(text.length()-1); char lastChar = text.charAt(text.length()-1);
hasSuffix = lastChar == ':' || lastChar == '='; this.hasSuffix = doHasSuffix || lastChar == ':' || lastChar == '=';
} }
public String getText() { public String getText() {

View file

@ -44,7 +44,7 @@ import static com.sun.tools.javac.util.LayoutCharacters.*;
*/ */
public class JavaTokenizer { public class JavaTokenizer {
private static boolean scannerDebug = false; private static final boolean scannerDebug = false;
/** Allow hex floating-point literals. /** Allow hex floating-point literals.
*/ */

View file

@ -1336,7 +1336,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
return nodes; return nodes;
} }
private static TreeScanner treeCleaner = new TreeScanner() { private static final TreeScanner treeCleaner = new TreeScanner() {
public void scan(JCTree node) { public void scan(JCTree node) {
super.scan(node); super.scan(node);
if (node != null) if (node != null)

View file

@ -340,15 +340,17 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
*/ */
LETEXPR; // ala scheme LETEXPR; // ala scheme
private Tag noAssignTag; private final Tag noAssignTag;
private static int numberOfOperators = MOD.ordinal() - POS.ordinal() + 1; private static final int numberOfOperators = MOD.ordinal() - POS.ordinal() + 1;
private Tag(Tag noAssignTag) { private Tag(Tag noAssignTag) {
this.noAssignTag = noAssignTag; this.noAssignTag = noAssignTag;
} }
private Tag() { } private Tag() {
this(null);
}
public static int getNumberOfOperators() { public static int getNumberOfOperators() {
return numberOfOperators; return numberOfOperators;
@ -1838,8 +1840,8 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
/** Toplevel # new */ /** Toplevel # new */
TOPLEVEL(ReferenceMode.NEW, false); TOPLEVEL(ReferenceMode.NEW, false);
ReferenceMode mode; final ReferenceMode mode;
boolean unbound; final boolean unbound;
private ReferenceKind(ReferenceMode mode, boolean unbound) { private ReferenceKind(ReferenceMode mode, boolean unbound) {
this.mode = mode; this.mode = mode;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -181,7 +181,7 @@ public abstract class BaseFileManager {
return false; return false;
} }
// where // where
private static Set<Option> javacFileManagerOptions = private static final Set<Option> javacFileManagerOptions =
Option.getJavacFileManagerOptions(); Option.getJavacFileManagerOptions();
public int isSupportedOption(String option) { public int isSupportedOption(String option) {

View file

@ -74,7 +74,7 @@ public class List<A> extends AbstractCollection<A> implements java.util.List<A>
return (List<A>)EMPTY_LIST; return (List<A>)EMPTY_LIST;
} }
private static List<?> EMPTY_LIST = new List<Object>(null,null) { private static final List<?> EMPTY_LIST = new List<Object>(null,null) {
public List<Object> setTail(List<Object> tail) { public List<Object> setTail(List<Object> tail) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@ -391,7 +391,7 @@ public class List<A> extends AbstractCollection<A> implements java.util.List<A>
return (List<T>)list; return (List<T>)list;
} }
private static Iterator<?> EMPTYITERATOR = new Iterator<Object>() { private static final Iterator<?> EMPTYITERATOR = new Iterator<Object>() {
public boolean hasNext() { public boolean hasNext() {
return false; return false;
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -91,7 +91,7 @@ public class MandatoryWarningHandler {
DeferredDiagnosticKind(String v) { value = v; } DeferredDiagnosticKind(String v) { value = v; }
String getKey(String prefix) { return prefix + value; } String getKey(String prefix) { return prefix + value; }
private String value; private final String value;
} }

View file

@ -249,7 +249,7 @@ public class RichDiagnosticFormatter extends
INTERSECTION("where.description.intersection"); INTERSECTION("where.description.intersection");
/** resource key for this where clause kind */ /** resource key for this where clause kind */
private String key; private final String key;
WhereClauseKind(String key) { WhereClauseKind(String key) {
this.key = key; this.key = key;

View file

@ -147,7 +147,7 @@ public class JavahTask implements NativeHeaderTool.NativeHeaderTask {
} }
} }
static Option[] recognizedOptions = { static final Option[] recognizedOptions = {
new Option(true, "-o") { new Option(true, "-o") {
void process(JavahTask task, String opt, String arg) { void process(JavahTask task, String opt, String arg) {
task.ofile = new File(arg); task.ofile = new File(arg);

View file

@ -117,7 +117,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
final String[] aliases; final String[] aliases;
} }
static Option[] recognizedOptions = { static final Option[] recognizedOptions = {
new Option(false, "-help", "--help", "-?") { new Option(false, "-help", "--help", "-?") {
void process(JavapTask task, String opt, String arg) { void process(JavapTask task, String opt, String arg) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -61,16 +61,10 @@ public enum Modifier {
/** The modifier {@code native} */ NATIVE, /** The modifier {@code native} */ NATIVE,
/** The modifier {@code strictfp} */ STRICTFP; /** The modifier {@code strictfp} */ STRICTFP;
private String lowercase = null; // modifier name in lowercase
/** /**
* Returns this modifier's name in lowercase. * Returns this modifier's name in lowercase.
*/ */
public String toString() { public String toString() {
if (lowercase == null) { return name().toLowerCase(java.util.Locale.US);
lowercase = name().toLowerCase(java.util.Locale.US);
}
return lowercase;
} }
} }

View file

@ -66,19 +66,19 @@ import javax.lang.model.element.*;
public class ElementFilter { public class ElementFilter {
private ElementFilter() {} // Do not instantiate. private ElementFilter() {} // Do not instantiate.
private static Set<ElementKind> CONSTRUCTOR_KIND = private static final Set<ElementKind> CONSTRUCTOR_KIND =
Collections.unmodifiableSet(EnumSet.of(ElementKind.CONSTRUCTOR)); Collections.unmodifiableSet(EnumSet.of(ElementKind.CONSTRUCTOR));
private static Set<ElementKind> FIELD_KINDS = private static final Set<ElementKind> FIELD_KINDS =
Collections.unmodifiableSet(EnumSet.of(ElementKind.FIELD, Collections.unmodifiableSet(EnumSet.of(ElementKind.FIELD,
ElementKind.ENUM_CONSTANT)); ElementKind.ENUM_CONSTANT));
private static Set<ElementKind> METHOD_KIND = private static final Set<ElementKind> METHOD_KIND =
Collections.unmodifiableSet(EnumSet.of(ElementKind.METHOD)); Collections.unmodifiableSet(EnumSet.of(ElementKind.METHOD));
private static Set<ElementKind> PACKAGE_KIND = private static final Set<ElementKind> PACKAGE_KIND =
Collections.unmodifiableSet(EnumSet.of(ElementKind.PACKAGE)); Collections.unmodifiableSet(EnumSet.of(ElementKind.PACKAGE));
private static Set<ElementKind> TYPE_KINDS = private static final Set<ElementKind> TYPE_KINDS =
Collections.unmodifiableSet(EnumSet.of(ElementKind.CLASS, Collections.unmodifiableSet(EnumSet.of(ElementKind.CLASS,
ElementKind.ENUM, ElementKind.ENUM,
ElementKind.INTERFACE, ElementKind.INTERFACE,

View file

@ -97,7 +97,7 @@ public enum StandardLocation implements Location {
return locations.get(name); return locations.get(name);
} }
//where //where
private static ConcurrentMap<String,Location> locations private static final ConcurrentMap<String,Location> locations
= new ConcurrentHashMap<String,Location>(); = new ConcurrentHashMap<String,Location>();
public String getName() { return name(); } public String getName() { return name(); }

View file

@ -0,0 +1,242 @@
/*
* Copyright (c) 2006, 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 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 8003967
* @summary detect and remove all mutable implicit static enum fields in langtools
* @run main DetectMutableStaticFields
*/
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.Descriptor;
import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
import com.sun.tools.classfile.Field;
import static javax.tools.JavaFileObject.Kind.CLASS;
import static com.sun.tools.classfile.AccessFlags.ACC_ENUM;
import static com.sun.tools.classfile.AccessFlags.ACC_FINAL;
import static com.sun.tools.classfile.AccessFlags.ACC_STATIC;
public class DetectMutableStaticFields {
private static final String keyResource =
"com/sun/tools/javac/tree/JCTree.class";
private String[] packagesToSeekFor = new String[] {
"javax.tools",
"javax.lang.model",
"com.sun.javadoc",
"com.sun.source",
"com.sun.tools.classfile",
"com.sun.tools.doclets",
"com.sun.tools.javac",
"com.sun.tools.javadoc",
"com.sun.tools.javah",
"com.sun.tools.javap",
};
private static final Map<String, List<String>> classFieldsToIgnoreMap = new HashMap<>();
static {
classFieldsToIgnoreMap.
put("javax/tools/ToolProvider",
Arrays.asList("instance"));
classFieldsToIgnoreMap.
put("com/sun/tools/javah/JavahTask",
Arrays.asList("versionRB"));
classFieldsToIgnoreMap.
put("com/sun/tools/classfile/Dependencies$DefaultFilter",
Arrays.asList("instance"));
classFieldsToIgnoreMap.
put("com/sun/tools/javap/JavapTask",
Arrays.asList("versionRB"));
classFieldsToIgnoreMap.
put("com/sun/tools/doclets/formats/html/HtmlDoclet",
Arrays.asList("docletToStart"));
classFieldsToIgnoreMap.
put("com/sun/tools/javac/util/JCDiagnostic",
Arrays.asList("fragmentFormatter"));
classFieldsToIgnoreMap.
put("com/sun/tools/javac/util/JavacMessages",
Arrays.asList("defaultBundle", "defaultMessages"));
classFieldsToIgnoreMap.
put("com/sun/tools/javac/file/ZipFileIndexCache",
Arrays.asList("sharedInstance"));
classFieldsToIgnoreMap.
put("com/sun/tools/javac/main/JavaCompiler",
Arrays.asList("versionRB"));
classFieldsToIgnoreMap.
put("com/sun/tools/javac/code/Type",
Arrays.asList("moreInfo"));
classFieldsToIgnoreMap.
put("com/sun/tools/javac/util/SharedNameTable",
Arrays.asList("freelist"));
classFieldsToIgnoreMap.
put("com/sun/tools/javac/util/Log",
Arrays.asList("useRawMessages"));
}
private List<String> errors = new ArrayList<>();
public static void main(String[] args) {
try {
new DetectMutableStaticFields().run();
} catch (Exception ex) {
throw new AssertionError(
"Exception during test execution with cause ",
ex.getCause());
}
}
private void run()
throws
IOException,
ConstantPoolException,
InvalidDescriptor,
URISyntaxException {
URI resource = findResource(keyResource);
if (resource == null) {
throw new AssertionError("Resource " + keyResource +
"not found in the class path");
}
analyzeResource(resource);
if (errors.size() > 0) {
for (String error: errors) {
System.err.println(error);
}
throw new AssertionError("There are mutable fields, "
+ "please check output");
}
}
URI findResource(String className) throws URISyntaxException {
URI uri = getClass().getClassLoader().getResource(className).toURI();
if (uri.getScheme().equals("jar")) {
String ssp = uri.getRawSchemeSpecificPart();
int sep = ssp.lastIndexOf("!");
uri = new URI(ssp.substring(0, sep));
} else if (uri.getScheme().equals("file")) {
uri = new URI(uri.getPath().substring(0,
uri.getPath().length() - keyResource.length()));
}
return uri;
}
boolean shouldAnalyzePackage(String packageName) {
for (String aPackage: packagesToSeekFor) {
if (packageName.contains(aPackage)) {
return true;
}
}
return false;
}
void analyzeResource(URI resource)
throws
IOException,
ConstantPoolException,
InvalidDescriptor {
JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
JavaFileManager.Location location =
StandardLocation.locationFor(resource.getPath());
fm.setLocation(location, com.sun.tools.javac.util.List.of(
new File(resource.getPath())));
for (JavaFileObject file : fm.list(location, "", EnumSet.of(CLASS), true)) {
String className = fm.inferBinaryName(location, file);
int index = className.lastIndexOf('.');
String pckName = index == -1 ? "" : className.substring(0, index);
if (shouldAnalyzePackage(pckName)) {
analyzeClassFile(ClassFile.read(file.openInputStream()));
}
}
}
List<String> currentFieldsToIgnore;
boolean ignoreField(String field) {
if (currentFieldsToIgnore != null) {
for (String fieldToIgnore : currentFieldsToIgnore) {
if (field.equals(fieldToIgnore)) {
return true;
}
}
}
return false;
}
void analyzeClassFile(ClassFile classFileToCheck)
throws
IOException,
ConstantPoolException,
Descriptor.InvalidDescriptor {
boolean enumClass =
(classFileToCheck.access_flags.flags & ACC_ENUM) != 0;
boolean nonFinalStaticEnumField;
boolean nonFinalStaticField;
currentFieldsToIgnore =
classFieldsToIgnoreMap.get(classFileToCheck.getName());
for (Field field : classFileToCheck.fields) {
if (ignoreField(field.getName(classFileToCheck.constant_pool))) {
continue;
}
nonFinalStaticEnumField =
(field.access_flags.flags & (ACC_ENUM | ACC_FINAL)) == 0;
nonFinalStaticField =
(field.access_flags.flags & ACC_STATIC) != 0 &&
(field.access_flags.flags & ACC_FINAL) == 0;
if (enumClass ? nonFinalStaticEnumField : nonFinalStaticField) {
errors.add("There is a mutable field named " +
field.getName(classFileToCheck.constant_pool) +
", at class " +
classFileToCheck.getName());
}
}
}
}