8003967: detect and remove all mutable implicit static enum fields in langtools
authorvromero
Mon, 10 Dec 2012 16:21:26 +0000
changeset 14801 d66cab4ef397
parent 14800 4bed1223fdf2
child 14802 969e90f68ac5
8003967: detect and remove all mutable implicit static enum fields in langtools Reviewed-by: jjg
langtools/src/share/classes/com/sun/tools/classfile/Opcode.java
langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFileFactory.java
langtools/src/share/classes/com/sun/tools/javac/Server.java
langtools/src/share/classes/com/sun/tools/javac/code/Flags.java
langtools/src/share/classes/com/sun/tools/javac/code/Kinds.java
langtools/src/share/classes/com/sun/tools/javac/code/Lint.java
langtools/src/share/classes/com/sun/tools/javac/code/Source.java
langtools/src/share/classes/com/sun/tools/javac/code/TargetType.java
langtools/src/share/classes/com/sun/tools/javac/code/TypeTag.java
langtools/src/share/classes/com/sun/tools/javac/code/Types.java
langtools/src/share/classes/com/sun/tools/javac/comp/ConstFold.java
langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java
langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java
langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java
langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java
langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java
langtools/src/share/classes/com/sun/tools/javac/main/Option.java
langtools/src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java
langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java
langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java
langtools/src/share/classes/com/sun/tools/javac/util/BaseFileManager.java
langtools/src/share/classes/com/sun/tools/javac/util/List.java
langtools/src/share/classes/com/sun/tools/javac/util/MandatoryWarningHandler.java
langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java
langtools/src/share/classes/com/sun/tools/javah/JavahTask.java
langtools/src/share/classes/com/sun/tools/javap/JavapTask.java
langtools/src/share/classes/javax/lang/model/element/Modifier.java
langtools/src/share/classes/javax/lang/model/util/ElementFilter.java
langtools/src/share/classes/javax/tools/StandardLocation.java
langtools/test/tools/javac/T8003967/DetectMutableStaticFields.java
--- a/langtools/src/share/classes/com/sun/tools/classfile/Opcode.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/classfile/Opcode.java	Mon Dec 10 16:21:26 2012 +0000
@@ -448,10 +448,10 @@
 
     }
 
-    private static Opcode[] stdOpcodes = new Opcode[256];
-    private static Opcode[] wideOpcodes = new Opcode[256];
-    private static Opcode[] nonPrivOpcodes = new Opcode[256];
-    private static Opcode[] privOpcodes = new Opcode[256];
+    private static final Opcode[] stdOpcodes = new Opcode[256];
+    private static final Opcode[] wideOpcodes = new Opcode[256];
+    private static final Opcode[] nonPrivOpcodes = new Opcode[256];
+    private static final Opcode[] privOpcodes = new Opcode[256];
     static {
         for (Opcode o: values())
             getOpcodeBlock(o.opcode >> 8)[o.opcode & 0xff] = o;
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFileFactory.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFileFactory.java	Mon Dec 10 16:21:26 2012 +0000
@@ -46,7 +46,7 @@
  * @since 1.8
  */
 abstract class DocFileFactory {
-    private static Map<Configuration, DocFileFactory> factories =
+    private static final Map<Configuration, DocFileFactory> factories =
             new WeakHashMap<Configuration, DocFileFactory>();
 
     /**
--- a/langtools/src/share/classes/com/sun/tools/javac/Server.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/Server.java	Mon Dec 10 16:21:26 2012 +0000
@@ -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.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -49,7 +49,7 @@
     private final OutputStream out;
     private final boolean isSocket;
     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> {
         String cwd;
         CwdFileManager(JavaFileManager fileManager) {
@@ -69,7 +69,7 @@
 //      }
     }
     // 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 {
         // Use the same file manager for all compilations.  This will
         // cache jar files in the standard file manager.  Use
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java	Mon Dec 10 16:21:26 2012 +0000
@@ -307,7 +307,7 @@
     }
 
     // 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);
 
     public static boolean isStatic(Symbol symbol) {
@@ -356,7 +356,7 @@
         VARARGS("varargs"),
         PACKAGE("package");
 
-        String name;
+        private final String name;
 
         Flag(String name) {
             this.name = name;
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Kinds.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Kinds.java	Mon Dec 10 16:21:26 2012 +0000
@@ -110,7 +110,7 @@
         INSTANCE_INIT("kindname.instance.init"),
         PACKAGE("kindname.package");
 
-        private String name;
+        private final String name;
 
         KindName(String name) {
             this.name = name;
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java	Mon Dec 10 16:21:26 2012 +0000
@@ -28,11 +28,14 @@
 import java.util.EnumSet;
 import java.util.HashMap;
 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.util.Context;
 import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.util.Options;
 import com.sun.tools.javac.util.Pair;
+
 import static com.sun.tools.javac.code.Flags.*;
 
 
@@ -95,7 +98,8 @@
     private final EnumSet<LintCategory> values;
     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) {
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java	Mon Dec 10 16:21:26 2012 +0000
@@ -87,7 +87,7 @@
 
     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 {
         for (Source s : values()) {
             tab.put(s.name, s);
--- a/langtools/src/share/classes/com/sun/tools/javac/code/TargetType.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/TargetType.java	Mon Dec 10 16:21:26 2012 +0000
@@ -166,7 +166,7 @@
     static final int MAXIMUM_TARGET_TYPE_VALUE = 0x22;
 
     private final int targetTypeValue;
-    private Set<TargetAttribute> flags;
+    private final Set<TargetAttribute> flags;
 
     TargetType(int targetTypeValue, TargetAttribute... attributes) {
         if (targetTypeValue < Byte.MIN_VALUE
@@ -233,10 +233,10 @@
         return this.targetTypeValue;
     }
 
-    private static TargetType[] targets = null;
+    private static final TargetType[] targets;
 
-    private static TargetType[] buildTargets() {
-        TargetType[] targets = new TargetType[MAXIMUM_TARGET_TYPE_VALUE + 1];
+    static {
+        targets = new TargetType[MAXIMUM_TARGET_TYPE_VALUE + 1];
         TargetType[] alltargets = values();
         for (TargetType target : alltargets) {
             if (target.targetTypeValue >= 0)
@@ -246,13 +246,9 @@
             if (targets[i] == null)
                 targets[i] = UNKNOWN;
         }
-        return targets;
     }
 
     public static boolean isValidTargetTypeValue(int tag) {
-        if (targets == null)
-            targets = buildTargets();
-
         if (((byte)tag) == ((byte)UNKNOWN.targetTypeValue))
             return true;
 
@@ -260,9 +256,6 @@
     }
 
     public static TargetType fromTargetTypeValue(int tag) {
-        if (targets == null)
-            targets = buildTargets();
-
         if (((byte)tag) == ((byte)UNKNOWN.targetTypeValue))
             return UNKNOWN;
 
--- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeTag.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeTag.java	Mon Dec 10 16:21:26 2012 +0000
@@ -135,9 +135,11 @@
     /** This field will only be used for tags related with numeric types for
      *  optimization reasons.
      */
-    private int order = 0;
+    private final int order;
 
-    private TypeTag() {}
+    private TypeTag() {
+        this(0);
+    }
 
     private TypeTag(int order) {
         this.order = order;
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Mon Dec 10 16:21:26 2012 +0000
@@ -2849,7 +2849,7 @@
         }
         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()); }
         };
     // </editor-fold>
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/ConstFold.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/ConstFold.java	Mon Dec 10 16:21:26 2012 +0000
@@ -62,9 +62,9 @@
         syms = Symtab.instance(context);
     }
 
-    static Integer minusOne = -1;
-    static Integer zero     = 0;
-    static Integer one      = 1;
+    static final Integer minusOne = -1;
+    static final Integer zero     = 0;
+    static final Integer one      = 1;
 
    /** Convert boolean to integer (true = 1, false = 0).
     */
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java	Mon Dec 10 16:21:26 2012 +0000
@@ -246,8 +246,8 @@
          */
         SPECULATIVE_LOOP("var.might.be.assigned.in.loop", true);
 
-        String errKey;
-        boolean isFinal;
+        final String errKey;
+        final boolean isFinal;
 
         FlowKind(String errKey, boolean isFinal) {
             this.errKey = errKey;
@@ -295,7 +295,7 @@
                 }
             };
 
-            JCTree.Tag treeTag;
+            final JCTree.Tag treeTag;
 
             private JumpKind(Tag treeTag) {
                 this.treeTag = treeTag;
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Mon Dec 10 16:21:26 2012 +0000
@@ -156,7 +156,7 @@
         OBJECT_INIT("object-init"),
         INTERNAL("internal");
 
-        String opt;
+        final String opt;
 
         private VerboseResolutionMode(String opt) {
             this.opt = opt;
@@ -3381,8 +3381,8 @@
             }
         };
 
-        boolean isBoxingRequired;
-        boolean isVarargsRequired;
+        final boolean isBoxingRequired;
+        final boolean isVarargsRequired;
 
         MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) {
            this.isBoxingRequired = isBoxingRequired;
--- a/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java	Mon Dec 10 16:21:26 2012 +0000
@@ -83,7 +83,7 @@
     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 =
             Collections.<RelativeDirectory, DirectoryEntry>emptyMap();
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java	Mon Dec 10 16:21:26 2012 +0000
@@ -1825,7 +1825,7 @@
         }
     }
 
-    static Type jsrReturnValue = new Type(INT, null);
+    static final Type jsrReturnValue = new Type(INT, null);
 
 
 /* **************************************************************************
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java	Mon Dec 10 16:21:26 2012 +0000
@@ -86,17 +86,15 @@
         return instance;
     }
 
-    private static Target MIN;
+    private static final Target MIN = values()[0];
     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; }
 
-    private static Map<String,Target> tab = new HashMap<String,Target>();
+    private static final Map<String,Target> tab = new HashMap<String,Target>();
     static {
         for (Target t : values()) {
-            if (MIN == null) MIN = t;
-            MAX = t;
             tab.put(t.name, t);
         }
         tab.put("5", JDK1_5);
--- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Mon Dec 10 16:21:26 2012 +0000
@@ -189,7 +189,7 @@
         }
     }
 
-    private static CompilePolicy DEFAULT_COMPILE_POLICY = CompilePolicy.BY_TODO;
+    private static final CompilePolicy DEFAULT_COMPILE_POLICY = CompilePolicy.BY_TODO;
 
     protected static enum ImplicitSourcePolicy {
         /** Don't generate or process implicitly read source files. */
@@ -543,7 +543,7 @@
         public static CompileState max(CompileState a, CompileState 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
      * for each compilation unit. Used for ATTR and FLOW phases.
--- a/langtools/src/share/classes/com/sun/tools/javac/main/Option.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/Option.java	Mon Dec 10 16:21:26 2012 +0000
@@ -167,7 +167,6 @@
     ENCODING("-encoding", "opt.arg.encoding", "opt.encoding", STANDARD, FILEMANAGER) {
         @Override
         public boolean process(OptionHelper helper, String option, String operand) {
-//            System.err.println("process encoding " + operand);
             return super.process(helper, option, operand);
         }
 
@@ -246,9 +245,7 @@
         }
     },
 
-    A("-A", "opt.arg.key.equals.value", "opt.A", STANDARD, BASIC) {
-        { hasSuffix = true; }
-
+    A("-A", "opt.arg.key.equals.value", "opt.A", STANDARD, BASIC, true) {
         @Override
         public boolean matches(String arg) {
             return arg.startsWith("-A");
@@ -293,8 +290,6 @@
     // This option exists only for the purpose of documenting itself.
     // It's actually implemented by the launcher.
     J("-J", "opt.arg.flag", "opt.J", STANDARD, INFO) {
-        { hasSuffix = true; }
-
         @Override
         public boolean process(OptionHelper helper, String option) {
             throw new AssertionError
@@ -302,10 +297,6 @@
         }
     },
 
-    // stop after parsing and attributing.
-    // new HiddenOption("-attrparseonly"),
-
-    // new Option("-moreinfo",                                      "opt.moreinfo") {
     MOREINFO("-moreinfo", null, HIDDEN, BASIC) {
         @Override
         public boolean process(OptionHelper helper, String option) {
@@ -317,23 +308,6 @@
     // treat warnings as errors
     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
     // new Option("-prompt",                                        "opt.prompt"),
     PROMPT("-prompt", null, HIDDEN, BASIC),
@@ -342,13 +316,8 @@
     DOE("-doe", null, HIDDEN, BASIC),
 
     // output source after type erasure
-    // new Option("-s",                                     "opt.s"),
     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
     WARNUNCHECKED("-warnunchecked", null, HIDDEN, BASIC) {
         @Override
@@ -408,18 +377,16 @@
      * -XDx sets the option x to the value x.
      */
     XD("-XD", null, HIDDEN, BASIC) {
-        String s;
         @Override
         public boolean matches(String s) {
-            this.s = s;
             return s.startsWith(text);
         }
         @Override
         public boolean process(OptionHelper helper, String option) {
-            s = s.substring(text.length());
-            int eq = s.indexOf('=');
-            String key = (eq < 0) ? s : s.substring(0, eq);
-            String value = (eq < 0) ? s : s.substring(eq+1);
+            option = option.substring(text.length());
+            int eq = option.indexOf('=');
+            String key = (eq < 0) ? option : option.substring(0, eq);
+            String value = (eq < 0) ? option : option.substring(eq+1);
             helper.put(key, value);
             return false;
         }
@@ -428,8 +395,6 @@
     // This option exists only for the purpose of documenting itself.
     // It's actually implemented by the CommandLine class.
     AT("@", "opt.arg.file", "opt.AT", STANDARD, INFO) {
-        { hasSuffix = true; }
-
         @Override
         public boolean process(OptionHelper helper, String option) {
             throw new AssertionError("the @ flag should be caught by CommandLine.");
@@ -445,17 +410,15 @@
      * name to a separate list.
      */
     SOURCEFILE("sourcefile", null, HIDDEN, INFO) {
-        String s;
         @Override
         public boolean matches(String s) {
-            this.s = s;
             return s.endsWith(".java")  // Java source file
                 || SourceVersion.isName(s);   // Legal type name
         }
         @Override
         public boolean process(OptionHelper helper, String option) {
-            if (s.endsWith(".java") ) {
-                File f = new File(s);
+            if (option.endsWith(".java") ) {
+                File f = new File(option);
                 if (!f.exists()) {
                     helper.error("err.file.not.found", f);
                     return true;
@@ -465,9 +428,9 @@
                     return true;
                 }
                 helper.addFile(f);
+            } else {
+                helper.addClassName(option);
             }
-            else
-                helper.addClassName(s);
             return false;
         }
     };
@@ -521,7 +484,7 @@
 
     /** Suffix option (-foo=bar or -foo:bar)
      */
-    boolean hasSuffix;
+    final boolean hasSuffix;
 
     /** The kind of choices for this option, if any.
      */
@@ -535,24 +498,30 @@
 
     Option(String text, String descrKey,
             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,
             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,
             OptionKind kind, OptionGroup group,
             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,
             OptionKind kind, OptionGroup group,
             ChoiceKind choiceKind, String... choices) {
-        this(text, null, descrKey, kind, group, choiceKind, createChoices(choices));
+        this(text, null, descrKey, kind, group, choiceKind,
+                createChoices(choices), false);
     }
     // where
         private static Map<String,Boolean> createChoices(String... choices) {
@@ -564,7 +533,8 @@
 
     private Option(String text, String argsNameKey, String descrKey,
             OptionKind kind, OptionGroup group,
-            ChoiceKind choiceKind, Map<String,Boolean> choices) {
+            ChoiceKind choiceKind, Map<String,Boolean> choices,
+            boolean doHasSuffix) {
         this.text = text;
         this.argsNameKey = argsNameKey;
         this.descrKey = descrKey;
@@ -573,7 +543,7 @@
         this.choiceKind = choiceKind;
         this.choices = choices;
         char lastChar = text.charAt(text.length()-1);
-        hasSuffix = lastChar == ':' || lastChar == '=';
+        this.hasSuffix = doHasSuffix || lastChar == ':' || lastChar == '=';
     }
 
     public String getText() {
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java	Mon Dec 10 16:21:26 2012 +0000
@@ -44,7 +44,7 @@
  */
 public class JavaTokenizer {
 
-    private static boolean scannerDebug = false;
+    private static final boolean scannerDebug = false;
 
     /** Allow hex floating-point literals.
      */
--- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Mon Dec 10 16:21:26 2012 +0000
@@ -1336,7 +1336,7 @@
         return nodes;
     }
 
-    private static TreeScanner treeCleaner = new TreeScanner() {
+    private static final TreeScanner treeCleaner = new TreeScanner() {
             public void scan(JCTree node) {
                 super.scan(node);
                 if (node != null)
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Mon Dec 10 16:21:26 2012 +0000
@@ -340,15 +340,17 @@
          */
         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) {
             this.noAssignTag = noAssignTag;
         }
 
-        private Tag() { }
+        private Tag() {
+            this(null);
+        }
 
         public static int getNumberOfOperators() {
             return numberOfOperators;
@@ -1838,8 +1840,8 @@
             /** Toplevel # new */
             TOPLEVEL(ReferenceMode.NEW, false);
 
-            ReferenceMode mode;
-            boolean unbound;
+            final ReferenceMode mode;
+            final boolean unbound;
 
             private ReferenceKind(ReferenceMode mode, boolean unbound) {
                 this.mode = mode;
--- a/langtools/src/share/classes/com/sun/tools/javac/util/BaseFileManager.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/BaseFileManager.java	Mon Dec 10 16:21:26 2012 +0000
@@ -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.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -181,7 +181,7 @@
         return false;
     }
     // where
-        private static Set<Option> javacFileManagerOptions =
+        private static final Set<Option> javacFileManagerOptions =
             Option.getJavacFileManagerOptions();
 
     public int isSupportedOption(String option) {
--- a/langtools/src/share/classes/com/sun/tools/javac/util/List.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/List.java	Mon Dec 10 16:21:26 2012 +0000
@@ -74,7 +74,7 @@
         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) {
             throw new UnsupportedOperationException();
         }
@@ -391,7 +391,7 @@
         return (List<T>)list;
     }
 
-    private static Iterator<?> EMPTYITERATOR = new Iterator<Object>() {
+    private static final Iterator<?> EMPTYITERATOR = new Iterator<Object>() {
             public boolean hasNext() {
                 return false;
             }
--- a/langtools/src/share/classes/com/sun/tools/javac/util/MandatoryWarningHandler.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/MandatoryWarningHandler.java	Mon Dec 10 16:21:26 2012 +0000
@@ -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.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -91,7 +91,7 @@
         DeferredDiagnosticKind(String v) { value = v; }
         String getKey(String prefix) { return prefix + value; }
 
-        private String value;
+        private final String value;
     }
 
 
--- a/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java	Mon Dec 10 16:21:26 2012 +0000
@@ -249,7 +249,7 @@
         INTERSECTION("where.description.intersection");
 
         /** resource key for this where clause kind */
-        private String key;
+        private final String key;
 
         WhereClauseKind(String key) {
             this.key = key;
--- a/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java	Mon Dec 10 16:21:26 2012 +0000
@@ -147,7 +147,7 @@
         }
     }
 
-    static Option[] recognizedOptions = {
+    static final Option[] recognizedOptions = {
         new Option(true, "-o") {
             void process(JavahTask task, String opt, String arg) {
                 task.ofile = new File(arg);
--- a/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java	Mon Dec 10 16:21:26 2012 +0000
@@ -117,7 +117,7 @@
         final String[] aliases;
     }
 
-    static Option[] recognizedOptions = {
+    static final Option[] recognizedOptions = {
 
         new Option(false, "-help", "--help", "-?") {
             void process(JavapTask task, String opt, String arg) {
--- a/langtools/src/share/classes/javax/lang/model/element/Modifier.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/javax/lang/model/element/Modifier.java	Mon Dec 10 16:21:26 2012 +0000
@@ -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.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -61,16 +61,10 @@
     /** The modifier {@code native} */          NATIVE,
     /** The modifier {@code strictfp} */        STRICTFP;
 
-
-    private String lowercase = null;    // modifier name in lowercase
-
     /**
      * Returns this modifier's name in lowercase.
      */
     public String toString() {
-        if (lowercase == null) {
-           lowercase = name().toLowerCase(java.util.Locale.US);
-        }
-        return lowercase;
+        return name().toLowerCase(java.util.Locale.US);
     }
 }
--- a/langtools/src/share/classes/javax/lang/model/util/ElementFilter.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/javax/lang/model/util/ElementFilter.java	Mon Dec 10 16:21:26 2012 +0000
@@ -66,19 +66,19 @@
 public class ElementFilter {
     private ElementFilter() {} // Do not instantiate.
 
-    private static Set<ElementKind> CONSTRUCTOR_KIND =
+    private static final Set<ElementKind> CONSTRUCTOR_KIND =
         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,
                                                ElementKind.ENUM_CONSTANT));
-    private static Set<ElementKind> METHOD_KIND =
+    private static final Set<ElementKind> METHOD_KIND =
         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));
 
-    private static Set<ElementKind> TYPE_KINDS =
+    private static final Set<ElementKind> TYPE_KINDS =
         Collections.unmodifiableSet(EnumSet.of(ElementKind.CLASS,
                                                ElementKind.ENUM,
                                                ElementKind.INTERFACE,
--- a/langtools/src/share/classes/javax/tools/StandardLocation.java	Mon Dec 10 12:10:50 2012 +0000
+++ b/langtools/src/share/classes/javax/tools/StandardLocation.java	Mon Dec 10 16:21:26 2012 +0000
@@ -97,7 +97,7 @@
         return locations.get(name);
     }
     //where
-        private static ConcurrentMap<String,Location> locations
+        private static final ConcurrentMap<String,Location> locations
             = new ConcurrentHashMap<String,Location>();
 
     public String getName() { return name(); }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8003967/DetectMutableStaticFields.java	Mon Dec 10 16:21:26 2012 +0000
@@ -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());
+            }
+        }
+    }
+
+}