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

Mon, 10 Dec 2012 16:21:26 +0000

author
vromero
date
Mon, 10 Dec 2012 16:21:26 +0000
changeset 1442
fcf89720ae71
parent 1441
c78acf6c2f3e
child 1443
cfde9737131e

8003967: detect and remove all mutable implicit static enum fields in langtools
Reviewed-by: jjg

src/share/classes/com/sun/tools/classfile/Opcode.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFileFactory.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/Server.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/code/Flags.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/code/Kinds.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/code/Lint.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/code/Source.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/code/TargetType.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/code/TypeTag.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/code/Types.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/ConstFold.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/Flow.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/Resolve.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/jvm/Code.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/jvm/Target.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/main/JavaCompiler.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/main/Option.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/tree/JCTree.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/util/BaseFileManager.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/util/List.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/util/MandatoryWarningHandler.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javah/JavahTask.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javap/JavapTask.java file | annotate | diff | comparison | revisions
src/share/classes/javax/lang/model/element/Modifier.java file | annotate | diff | comparison | revisions
src/share/classes/javax/lang/model/util/ElementFilter.java file | annotate | diff | comparison | revisions
src/share/classes/javax/tools/StandardLocation.java file | annotate | diff | comparison | revisions
test/tools/javac/T8003967/DetectMutableStaticFields.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/classfile/Opcode.java	Mon Dec 10 12:10:50 2012 +0000
     1.2 +++ b/src/share/classes/com/sun/tools/classfile/Opcode.java	Mon Dec 10 16:21:26 2012 +0000
     1.3 @@ -448,10 +448,10 @@
     1.4  
     1.5      }
     1.6  
     1.7 -    private static Opcode[] stdOpcodes = new Opcode[256];
     1.8 -    private static Opcode[] wideOpcodes = new Opcode[256];
     1.9 -    private static Opcode[] nonPrivOpcodes = new Opcode[256];
    1.10 -    private static Opcode[] privOpcodes = new Opcode[256];
    1.11 +    private static final Opcode[] stdOpcodes = new Opcode[256];
    1.12 +    private static final Opcode[] wideOpcodes = new Opcode[256];
    1.13 +    private static final Opcode[] nonPrivOpcodes = new Opcode[256];
    1.14 +    private static final Opcode[] privOpcodes = new Opcode[256];
    1.15      static {
    1.16          for (Opcode o: values())
    1.17              getOpcodeBlock(o.opcode >> 8)[o.opcode & 0xff] = o;
     2.1 --- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFileFactory.java	Mon Dec 10 12:10:50 2012 +0000
     2.2 +++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFileFactory.java	Mon Dec 10 16:21:26 2012 +0000
     2.3 @@ -46,7 +46,7 @@
     2.4   * @since 1.8
     2.5   */
     2.6  abstract class DocFileFactory {
     2.7 -    private static Map<Configuration, DocFileFactory> factories =
     2.8 +    private static final Map<Configuration, DocFileFactory> factories =
     2.9              new WeakHashMap<Configuration, DocFileFactory>();
    2.10  
    2.11      /**
     3.1 --- a/src/share/classes/com/sun/tools/javac/Server.java	Mon Dec 10 12:10:50 2012 +0000
     3.2 +++ b/src/share/classes/com/sun/tools/javac/Server.java	Mon Dec 10 16:21:26 2012 +0000
     3.3 @@ -1,5 +1,5 @@
     3.4  /*
     3.5 - * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
     3.6 + * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
     3.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.8   *
     3.9   * This code is free software; you can redistribute it and/or modify it
    3.10 @@ -49,7 +49,7 @@
    3.11      private final OutputStream out;
    3.12      private final boolean isSocket;
    3.13      private static final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
    3.14 -    private static Logger logger = Logger.getLogger("com.sun.tools.javac");
    3.15 +    private static final Logger logger = Logger.getLogger("com.sun.tools.javac");
    3.16      static class CwdFileManager extends ForwardingJavaFileManager<JavaFileManager> {
    3.17          String cwd;
    3.18          CwdFileManager(JavaFileManager fileManager) {
    3.19 @@ -69,7 +69,7 @@
    3.20  //      }
    3.21      }
    3.22      // static CwdFileManager fm = new CwdFileManager(tool.getStandardFileManager());
    3.23 -    static StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
    3.24 +    static final StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
    3.25      static {
    3.26          // Use the same file manager for all compilations.  This will
    3.27          // cache jar files in the standard file manager.  Use
     4.1 --- a/src/share/classes/com/sun/tools/javac/code/Flags.java	Mon Dec 10 12:10:50 2012 +0000
     4.2 +++ b/src/share/classes/com/sun/tools/javac/code/Flags.java	Mon Dec 10 16:21:26 2012 +0000
     4.3 @@ -307,7 +307,7 @@
     4.4      }
     4.5  
     4.6      // Cache of modifier sets.
     4.7 -    private static Map<Long, Set<Modifier>> modifierSets =
     4.8 +    private static final Map<Long, Set<Modifier>> modifierSets =
     4.9          new java.util.concurrent.ConcurrentHashMap<Long, Set<Modifier>>(64);
    4.10  
    4.11      public static boolean isStatic(Symbol symbol) {
    4.12 @@ -356,7 +356,7 @@
    4.13          VARARGS("varargs"),
    4.14          PACKAGE("package");
    4.15  
    4.16 -        String name;
    4.17 +        private final String name;
    4.18  
    4.19          Flag(String name) {
    4.20              this.name = name;
     5.1 --- a/src/share/classes/com/sun/tools/javac/code/Kinds.java	Mon Dec 10 12:10:50 2012 +0000
     5.2 +++ b/src/share/classes/com/sun/tools/javac/code/Kinds.java	Mon Dec 10 16:21:26 2012 +0000
     5.3 @@ -110,7 +110,7 @@
     5.4          INSTANCE_INIT("kindname.instance.init"),
     5.5          PACKAGE("kindname.package");
     5.6  
     5.7 -        private String name;
     5.8 +        private final String name;
     5.9  
    5.10          KindName(String name) {
    5.11              this.name = name;
     6.1 --- a/src/share/classes/com/sun/tools/javac/code/Lint.java	Mon Dec 10 12:10:50 2012 +0000
     6.2 +++ b/src/share/classes/com/sun/tools/javac/code/Lint.java	Mon Dec 10 16:21:26 2012 +0000
     6.3 @@ -28,11 +28,14 @@
     6.4  import java.util.EnumSet;
     6.5  import java.util.HashMap;
     6.6  import java.util.Map;
     6.7 +import java.util.Set;
     6.8 +import javax.lang.model.element.Modifier;
     6.9  import com.sun.tools.javac.code.Symbol.*;
    6.10  import com.sun.tools.javac.util.Context;
    6.11  import com.sun.tools.javac.util.List;
    6.12  import com.sun.tools.javac.util.Options;
    6.13  import com.sun.tools.javac.util.Pair;
    6.14 +
    6.15  import static com.sun.tools.javac.code.Flags.*;
    6.16  
    6.17  
    6.18 @@ -95,7 +98,8 @@
    6.19      private final EnumSet<LintCategory> values;
    6.20      private final EnumSet<LintCategory> suppressedValues;
    6.21  
    6.22 -    private static Map<String, LintCategory> map = new HashMap<String,LintCategory>();
    6.23 +    private static final Map<String, LintCategory> map =
    6.24 +            new java.util.concurrent.ConcurrentHashMap<String, LintCategory>(20);
    6.25  
    6.26  
    6.27      protected Lint(Context context) {
     7.1 --- a/src/share/classes/com/sun/tools/javac/code/Source.java	Mon Dec 10 12:10:50 2012 +0000
     7.2 +++ b/src/share/classes/com/sun/tools/javac/code/Source.java	Mon Dec 10 16:21:26 2012 +0000
     7.3 @@ -87,7 +87,7 @@
     7.4  
     7.5      public final String name;
     7.6  
     7.7 -    private static Map<String,Source> tab = new HashMap<String,Source>();
     7.8 +    private static final Map<String,Source> tab = new HashMap<String,Source>();
     7.9      static {
    7.10          for (Source s : values()) {
    7.11              tab.put(s.name, s);
     8.1 --- a/src/share/classes/com/sun/tools/javac/code/TargetType.java	Mon Dec 10 12:10:50 2012 +0000
     8.2 +++ b/src/share/classes/com/sun/tools/javac/code/TargetType.java	Mon Dec 10 16:21:26 2012 +0000
     8.3 @@ -166,7 +166,7 @@
     8.4      static final int MAXIMUM_TARGET_TYPE_VALUE = 0x22;
     8.5  
     8.6      private final int targetTypeValue;
     8.7 -    private Set<TargetAttribute> flags;
     8.8 +    private final Set<TargetAttribute> flags;
     8.9  
    8.10      TargetType(int targetTypeValue, TargetAttribute... attributes) {
    8.11          if (targetTypeValue < Byte.MIN_VALUE
    8.12 @@ -233,10 +233,10 @@
    8.13          return this.targetTypeValue;
    8.14      }
    8.15  
    8.16 -    private static TargetType[] targets = null;
    8.17 +    private static final TargetType[] targets;
    8.18  
    8.19 -    private static TargetType[] buildTargets() {
    8.20 -        TargetType[] targets = new TargetType[MAXIMUM_TARGET_TYPE_VALUE + 1];
    8.21 +    static {
    8.22 +        targets = new TargetType[MAXIMUM_TARGET_TYPE_VALUE + 1];
    8.23          TargetType[] alltargets = values();
    8.24          for (TargetType target : alltargets) {
    8.25              if (target.targetTypeValue >= 0)
    8.26 @@ -246,13 +246,9 @@
    8.27              if (targets[i] == null)
    8.28                  targets[i] = UNKNOWN;
    8.29          }
    8.30 -        return targets;
    8.31      }
    8.32  
    8.33      public static boolean isValidTargetTypeValue(int tag) {
    8.34 -        if (targets == null)
    8.35 -            targets = buildTargets();
    8.36 -
    8.37          if (((byte)tag) == ((byte)UNKNOWN.targetTypeValue))
    8.38              return true;
    8.39  
    8.40 @@ -260,9 +256,6 @@
    8.41      }
    8.42  
    8.43      public static TargetType fromTargetTypeValue(int tag) {
    8.44 -        if (targets == null)
    8.45 -            targets = buildTargets();
    8.46 -
    8.47          if (((byte)tag) == ((byte)UNKNOWN.targetTypeValue))
    8.48              return UNKNOWN;
    8.49  
     9.1 --- a/src/share/classes/com/sun/tools/javac/code/TypeTag.java	Mon Dec 10 12:10:50 2012 +0000
     9.2 +++ b/src/share/classes/com/sun/tools/javac/code/TypeTag.java	Mon Dec 10 16:21:26 2012 +0000
     9.3 @@ -135,9 +135,11 @@
     9.4      /** This field will only be used for tags related with numeric types for
     9.5       *  optimization reasons.
     9.6       */
     9.7 -    private int order = 0;
     9.8 +    private final int order;
     9.9  
    9.10 -    private TypeTag() {}
    9.11 +    private TypeTag() {
    9.12 +        this(0);
    9.13 +    }
    9.14  
    9.15      private TypeTag(int order) {
    9.16          this.order = order;
    10.1 --- a/src/share/classes/com/sun/tools/javac/code/Types.java	Mon Dec 10 12:10:50 2012 +0000
    10.2 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Mon Dec 10 16:21:26 2012 +0000
    10.3 @@ -2849,7 +2849,7 @@
    10.4          }
    10.5          return tvars1;
    10.6      }
    10.7 -    static private Mapping newInstanceFun = new Mapping("newInstanceFun") {
    10.8 +    private static final Mapping newInstanceFun = new Mapping("newInstanceFun") {
    10.9              public Type apply(Type t) { return new TypeVar(t.tsym, t.getUpperBound(), t.getLowerBound()); }
   10.10          };
   10.11      // </editor-fold>
    11.1 --- a/src/share/classes/com/sun/tools/javac/comp/ConstFold.java	Mon Dec 10 12:10:50 2012 +0000
    11.2 +++ b/src/share/classes/com/sun/tools/javac/comp/ConstFold.java	Mon Dec 10 16:21:26 2012 +0000
    11.3 @@ -62,9 +62,9 @@
    11.4          syms = Symtab.instance(context);
    11.5      }
    11.6  
    11.7 -    static Integer minusOne = -1;
    11.8 -    static Integer zero     = 0;
    11.9 -    static Integer one      = 1;
   11.10 +    static final Integer minusOne = -1;
   11.11 +    static final Integer zero     = 0;
   11.12 +    static final Integer one      = 1;
   11.13  
   11.14     /** Convert boolean to integer (true = 1, false = 0).
   11.15      */
    12.1 --- a/src/share/classes/com/sun/tools/javac/comp/Flow.java	Mon Dec 10 12:10:50 2012 +0000
    12.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Flow.java	Mon Dec 10 16:21:26 2012 +0000
    12.3 @@ -246,8 +246,8 @@
    12.4           */
    12.5          SPECULATIVE_LOOP("var.might.be.assigned.in.loop", true);
    12.6  
    12.7 -        String errKey;
    12.8 -        boolean isFinal;
    12.9 +        final String errKey;
   12.10 +        final boolean isFinal;
   12.11  
   12.12          FlowKind(String errKey, boolean isFinal) {
   12.13              this.errKey = errKey;
   12.14 @@ -295,7 +295,7 @@
   12.15                  }
   12.16              };
   12.17  
   12.18 -            JCTree.Tag treeTag;
   12.19 +            final JCTree.Tag treeTag;
   12.20  
   12.21              private JumpKind(Tag treeTag) {
   12.22                  this.treeTag = treeTag;
    13.1 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Mon Dec 10 12:10:50 2012 +0000
    13.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Mon Dec 10 16:21:26 2012 +0000
    13.3 @@ -156,7 +156,7 @@
    13.4          OBJECT_INIT("object-init"),
    13.5          INTERNAL("internal");
    13.6  
    13.7 -        String opt;
    13.8 +        final String opt;
    13.9  
   13.10          private VerboseResolutionMode(String opt) {
   13.11              this.opt = opt;
   13.12 @@ -3381,8 +3381,8 @@
   13.13              }
   13.14          };
   13.15  
   13.16 -        boolean isBoxingRequired;
   13.17 -        boolean isVarargsRequired;
   13.18 +        final boolean isBoxingRequired;
   13.19 +        final boolean isVarargsRequired;
   13.20  
   13.21          MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) {
   13.22             this.isBoxingRequired = isBoxingRequired;
    14.1 --- a/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java	Mon Dec 10 12:10:50 2012 +0000
    14.2 +++ b/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java	Mon Dec 10 16:21:26 2012 +0000
    14.3 @@ -83,7 +83,7 @@
    14.4      public final static long NOT_MODIFIED = Long.MIN_VALUE;
    14.5  
    14.6  
    14.7 -    private static boolean NON_BATCH_MODE = System.getProperty("nonBatchMode") != null;// TODO: Use -XD compiler switch for this.
    14.8 +    private static final boolean NON_BATCH_MODE = System.getProperty("nonBatchMode") != null;// TODO: Use -XD compiler switch for this.
    14.9  
   14.10      private Map<RelativeDirectory, DirectoryEntry> directories =
   14.11              Collections.<RelativeDirectory, DirectoryEntry>emptyMap();
    15.1 --- a/src/share/classes/com/sun/tools/javac/jvm/Code.java	Mon Dec 10 12:10:50 2012 +0000
    15.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/Code.java	Mon Dec 10 16:21:26 2012 +0000
    15.3 @@ -1825,7 +1825,7 @@
    15.4          }
    15.5      }
    15.6  
    15.7 -    static Type jsrReturnValue = new Type(INT, null);
    15.8 +    static final Type jsrReturnValue = new Type(INT, null);
    15.9  
   15.10  
   15.11  /* **************************************************************************
    16.1 --- a/src/share/classes/com/sun/tools/javac/jvm/Target.java	Mon Dec 10 12:10:50 2012 +0000
    16.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/Target.java	Mon Dec 10 16:21:26 2012 +0000
    16.3 @@ -86,17 +86,15 @@
    16.4          return instance;
    16.5      }
    16.6  
    16.7 -    private static Target MIN;
    16.8 +    private static final Target MIN = values()[0];
    16.9      public static Target MIN() { return MIN; }
   16.10  
   16.11 -    private static Target MAX;
   16.12 +    private static final Target MAX = values()[values().length - 1];
   16.13      public static Target MAX() { return MAX; }
   16.14  
   16.15 -    private static Map<String,Target> tab = new HashMap<String,Target>();
   16.16 +    private static final Map<String,Target> tab = new HashMap<String,Target>();
   16.17      static {
   16.18          for (Target t : values()) {
   16.19 -            if (MIN == null) MIN = t;
   16.20 -            MAX = t;
   16.21              tab.put(t.name, t);
   16.22          }
   16.23          tab.put("5", JDK1_5);
    17.1 --- a/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Mon Dec 10 12:10:50 2012 +0000
    17.2 +++ b/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Mon Dec 10 16:21:26 2012 +0000
    17.3 @@ -189,7 +189,7 @@
    17.4          }
    17.5      }
    17.6  
    17.7 -    private static CompilePolicy DEFAULT_COMPILE_POLICY = CompilePolicy.BY_TODO;
    17.8 +    private static final CompilePolicy DEFAULT_COMPILE_POLICY = CompilePolicy.BY_TODO;
    17.9  
   17.10      protected static enum ImplicitSourcePolicy {
   17.11          /** Don't generate or process implicitly read source files. */
   17.12 @@ -543,7 +543,7 @@
   17.13          public static CompileState max(CompileState a, CompileState b) {
   17.14              return a.value > b.value ? a : b;
   17.15          }
   17.16 -        private int value;
   17.17 +        private final int value;
   17.18      };
   17.19      /** Partial map to record which compiler phases have been executed
   17.20       * for each compilation unit. Used for ATTR and FLOW phases.
    18.1 --- a/src/share/classes/com/sun/tools/javac/main/Option.java	Mon Dec 10 12:10:50 2012 +0000
    18.2 +++ b/src/share/classes/com/sun/tools/javac/main/Option.java	Mon Dec 10 16:21:26 2012 +0000
    18.3 @@ -167,7 +167,6 @@
    18.4      ENCODING("-encoding", "opt.arg.encoding", "opt.encoding", STANDARD, FILEMANAGER) {
    18.5          @Override
    18.6          public boolean process(OptionHelper helper, String option, String operand) {
    18.7 -//            System.err.println("process encoding " + operand);
    18.8              return super.process(helper, option, operand);
    18.9          }
   18.10  
   18.11 @@ -246,9 +245,7 @@
   18.12          }
   18.13      },
   18.14  
   18.15 -    A("-A", "opt.arg.key.equals.value", "opt.A", STANDARD, BASIC) {
   18.16 -        { hasSuffix = true; }
   18.17 -
   18.18 +    A("-A", "opt.arg.key.equals.value", "opt.A", STANDARD, BASIC, true) {
   18.19          @Override
   18.20          public boolean matches(String arg) {
   18.21              return arg.startsWith("-A");
   18.22 @@ -293,8 +290,6 @@
   18.23      // This option exists only for the purpose of documenting itself.
   18.24      // It's actually implemented by the launcher.
   18.25      J("-J", "opt.arg.flag", "opt.J", STANDARD, INFO) {
   18.26 -        { hasSuffix = true; }
   18.27 -
   18.28          @Override
   18.29          public boolean process(OptionHelper helper, String option) {
   18.30              throw new AssertionError
   18.31 @@ -302,10 +297,6 @@
   18.32          }
   18.33      },
   18.34  
   18.35 -    // stop after parsing and attributing.
   18.36 -    // new HiddenOption("-attrparseonly"),
   18.37 -
   18.38 -    // new Option("-moreinfo",                                      "opt.moreinfo") {
   18.39      MOREINFO("-moreinfo", null, HIDDEN, BASIC) {
   18.40          @Override
   18.41          public boolean process(OptionHelper helper, String option) {
   18.42 @@ -317,23 +308,6 @@
   18.43      // treat warnings as errors
   18.44      WERROR("-Werror", "opt.Werror", STANDARD, BASIC),
   18.45  
   18.46 -//    // use complex inference from context in the position of a method call argument
   18.47 -//    COMPLEXINFERENCE("-complexinference", null, HIDDEN, BASIC),
   18.48 -
   18.49 -    // generare source stubs
   18.50 -    // new HiddenOption("-stubs"),
   18.51 -
   18.52 -    // relax some constraints to allow compiling from stubs
   18.53 -    // new HiddenOption("-relax"),
   18.54 -
   18.55 -    // output source after translating away inner classes
   18.56 -    // new Option("-printflat",                             "opt.printflat"),
   18.57 -    // new HiddenOption("-printflat"),
   18.58 -
   18.59 -    // display scope search details
   18.60 -    // new Option("-printsearch",                           "opt.printsearch"),
   18.61 -    // new HiddenOption("-printsearch"),
   18.62 -
   18.63      // prompt after each error
   18.64      // new Option("-prompt",                                        "opt.prompt"),
   18.65      PROMPT("-prompt", null, HIDDEN, BASIC),
   18.66 @@ -342,13 +316,8 @@
   18.67      DOE("-doe", null, HIDDEN, BASIC),
   18.68  
   18.69      // output source after type erasure
   18.70 -    // new Option("-s",                                     "opt.s"),
   18.71      PRINTSOURCE("-printsource", null, HIDDEN, BASIC),
   18.72  
   18.73 -    // output shrouded class files
   18.74 -    // new Option("-scramble",                              "opt.scramble"),
   18.75 -    // new Option("-scrambleall",                           "opt.scrambleall"),
   18.76 -
   18.77      // display warnings for generic unchecked operations
   18.78      WARNUNCHECKED("-warnunchecked", null, HIDDEN, BASIC) {
   18.79          @Override
   18.80 @@ -408,18 +377,16 @@
   18.81       * -XDx sets the option x to the value x.
   18.82       */
   18.83      XD("-XD", null, HIDDEN, BASIC) {
   18.84 -        String s;
   18.85          @Override
   18.86          public boolean matches(String s) {
   18.87 -            this.s = s;
   18.88              return s.startsWith(text);
   18.89          }
   18.90          @Override
   18.91          public boolean process(OptionHelper helper, String option) {
   18.92 -            s = s.substring(text.length());
   18.93 -            int eq = s.indexOf('=');
   18.94 -            String key = (eq < 0) ? s : s.substring(0, eq);
   18.95 -            String value = (eq < 0) ? s : s.substring(eq+1);
   18.96 +            option = option.substring(text.length());
   18.97 +            int eq = option.indexOf('=');
   18.98 +            String key = (eq < 0) ? option : option.substring(0, eq);
   18.99 +            String value = (eq < 0) ? option : option.substring(eq+1);
  18.100              helper.put(key, value);
  18.101              return false;
  18.102          }
  18.103 @@ -428,8 +395,6 @@
  18.104      // This option exists only for the purpose of documenting itself.
  18.105      // It's actually implemented by the CommandLine class.
  18.106      AT("@", "opt.arg.file", "opt.AT", STANDARD, INFO) {
  18.107 -        { hasSuffix = true; }
  18.108 -
  18.109          @Override
  18.110          public boolean process(OptionHelper helper, String option) {
  18.111              throw new AssertionError("the @ flag should be caught by CommandLine.");
  18.112 @@ -445,17 +410,15 @@
  18.113       * name to a separate list.
  18.114       */
  18.115      SOURCEFILE("sourcefile", null, HIDDEN, INFO) {
  18.116 -        String s;
  18.117          @Override
  18.118          public boolean matches(String s) {
  18.119 -            this.s = s;
  18.120              return s.endsWith(".java")  // Java source file
  18.121                  || SourceVersion.isName(s);   // Legal type name
  18.122          }
  18.123          @Override
  18.124          public boolean process(OptionHelper helper, String option) {
  18.125 -            if (s.endsWith(".java") ) {
  18.126 -                File f = new File(s);
  18.127 +            if (option.endsWith(".java") ) {
  18.128 +                File f = new File(option);
  18.129                  if (!f.exists()) {
  18.130                      helper.error("err.file.not.found", f);
  18.131                      return true;
  18.132 @@ -465,9 +428,9 @@
  18.133                      return true;
  18.134                  }
  18.135                  helper.addFile(f);
  18.136 +            } else {
  18.137 +                helper.addClassName(option);
  18.138              }
  18.139 -            else
  18.140 -                helper.addClassName(s);
  18.141              return false;
  18.142          }
  18.143      };
  18.144 @@ -521,7 +484,7 @@
  18.145  
  18.146      /** Suffix option (-foo=bar or -foo:bar)
  18.147       */
  18.148 -    boolean hasSuffix;
  18.149 +    final boolean hasSuffix;
  18.150  
  18.151      /** The kind of choices for this option, if any.
  18.152       */
  18.153 @@ -535,24 +498,30 @@
  18.154  
  18.155      Option(String text, String descrKey,
  18.156              OptionKind kind, OptionGroup group) {
  18.157 -        this(text, null, descrKey, kind, group, null, null);
  18.158 +        this(text, null, descrKey, kind, group, null, null, false);
  18.159      }
  18.160  
  18.161      Option(String text, String argsNameKey, String descrKey,
  18.162              OptionKind kind, OptionGroup group) {
  18.163 -        this(text, argsNameKey, descrKey, kind, group, null, null);
  18.164 +        this(text, argsNameKey, descrKey, kind, group, null, null, false);
  18.165 +    }
  18.166 +
  18.167 +    Option(String text, String argsNameKey, String descrKey,
  18.168 +            OptionKind kind, OptionGroup group, boolean doHasSuffix) {
  18.169 +        this(text, argsNameKey, descrKey, kind, group, null, null, doHasSuffix);
  18.170      }
  18.171  
  18.172      Option(String text, String descrKey,
  18.173              OptionKind kind, OptionGroup group,
  18.174              ChoiceKind choiceKind, Map<String,Boolean> choices) {
  18.175 -        this(text, null, descrKey, kind, group, choiceKind, choices);
  18.176 +        this(text, null, descrKey, kind, group, choiceKind, choices, false);
  18.177      }
  18.178  
  18.179      Option(String text, String descrKey,
  18.180              OptionKind kind, OptionGroup group,
  18.181              ChoiceKind choiceKind, String... choices) {
  18.182 -        this(text, null, descrKey, kind, group, choiceKind, createChoices(choices));
  18.183 +        this(text, null, descrKey, kind, group, choiceKind,
  18.184 +                createChoices(choices), false);
  18.185      }
  18.186      // where
  18.187          private static Map<String,Boolean> createChoices(String... choices) {
  18.188 @@ -564,7 +533,8 @@
  18.189  
  18.190      private Option(String text, String argsNameKey, String descrKey,
  18.191              OptionKind kind, OptionGroup group,
  18.192 -            ChoiceKind choiceKind, Map<String,Boolean> choices) {
  18.193 +            ChoiceKind choiceKind, Map<String,Boolean> choices,
  18.194 +            boolean doHasSuffix) {
  18.195          this.text = text;
  18.196          this.argsNameKey = argsNameKey;
  18.197          this.descrKey = descrKey;
  18.198 @@ -573,7 +543,7 @@
  18.199          this.choiceKind = choiceKind;
  18.200          this.choices = choices;
  18.201          char lastChar = text.charAt(text.length()-1);
  18.202 -        hasSuffix = lastChar == ':' || lastChar == '=';
  18.203 +        this.hasSuffix = doHasSuffix || lastChar == ':' || lastChar == '=';
  18.204      }
  18.205  
  18.206      public String getText() {
    19.1 --- a/src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java	Mon Dec 10 12:10:50 2012 +0000
    19.2 +++ b/src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java	Mon Dec 10 16:21:26 2012 +0000
    19.3 @@ -44,7 +44,7 @@
    19.4   */
    19.5  public class JavaTokenizer {
    19.6  
    19.7 -    private static boolean scannerDebug = false;
    19.8 +    private static final boolean scannerDebug = false;
    19.9  
   19.10      /** Allow hex floating-point literals.
   19.11       */
    20.1 --- a/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Mon Dec 10 12:10:50 2012 +0000
    20.2 +++ b/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Mon Dec 10 16:21:26 2012 +0000
    20.3 @@ -1336,7 +1336,7 @@
    20.4          return nodes;
    20.5      }
    20.6  
    20.7 -    private static TreeScanner treeCleaner = new TreeScanner() {
    20.8 +    private static final TreeScanner treeCleaner = new TreeScanner() {
    20.9              public void scan(JCTree node) {
   20.10                  super.scan(node);
   20.11                  if (node != null)
    21.1 --- a/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Mon Dec 10 12:10:50 2012 +0000
    21.2 +++ b/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Mon Dec 10 16:21:26 2012 +0000
    21.3 @@ -340,15 +340,17 @@
    21.4           */
    21.5          LETEXPR;                         // ala scheme
    21.6  
    21.7 -        private Tag noAssignTag;
    21.8 +        private final Tag noAssignTag;
    21.9  
   21.10 -        private static int numberOfOperators = MOD.ordinal() - POS.ordinal() + 1;
   21.11 +        private static final int numberOfOperators = MOD.ordinal() - POS.ordinal() + 1;
   21.12  
   21.13          private Tag(Tag noAssignTag) {
   21.14              this.noAssignTag = noAssignTag;
   21.15          }
   21.16  
   21.17 -        private Tag() { }
   21.18 +        private Tag() {
   21.19 +            this(null);
   21.20 +        }
   21.21  
   21.22          public static int getNumberOfOperators() {
   21.23              return numberOfOperators;
   21.24 @@ -1838,8 +1840,8 @@
   21.25              /** Toplevel # new */
   21.26              TOPLEVEL(ReferenceMode.NEW, false);
   21.27  
   21.28 -            ReferenceMode mode;
   21.29 -            boolean unbound;
   21.30 +            final ReferenceMode mode;
   21.31 +            final boolean unbound;
   21.32  
   21.33              private ReferenceKind(ReferenceMode mode, boolean unbound) {
   21.34                  this.mode = mode;
    22.1 --- a/src/share/classes/com/sun/tools/javac/util/BaseFileManager.java	Mon Dec 10 12:10:50 2012 +0000
    22.2 +++ b/src/share/classes/com/sun/tools/javac/util/BaseFileManager.java	Mon Dec 10 16:21:26 2012 +0000
    22.3 @@ -1,5 +1,5 @@
    22.4  /*
    22.5 - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
    22.6 + * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
    22.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    22.8   *
    22.9   * This code is free software; you can redistribute it and/or modify it
   22.10 @@ -181,7 +181,7 @@
   22.11          return false;
   22.12      }
   22.13      // where
   22.14 -        private static Set<Option> javacFileManagerOptions =
   22.15 +        private static final Set<Option> javacFileManagerOptions =
   22.16              Option.getJavacFileManagerOptions();
   22.17  
   22.18      public int isSupportedOption(String option) {
    23.1 --- a/src/share/classes/com/sun/tools/javac/util/List.java	Mon Dec 10 12:10:50 2012 +0000
    23.2 +++ b/src/share/classes/com/sun/tools/javac/util/List.java	Mon Dec 10 16:21:26 2012 +0000
    23.3 @@ -74,7 +74,7 @@
    23.4          return (List<A>)EMPTY_LIST;
    23.5      }
    23.6  
    23.7 -    private static List<?> EMPTY_LIST = new List<Object>(null,null) {
    23.8 +    private static final List<?> EMPTY_LIST = new List<Object>(null,null) {
    23.9          public List<Object> setTail(List<Object> tail) {
   23.10              throw new UnsupportedOperationException();
   23.11          }
   23.12 @@ -391,7 +391,7 @@
   23.13          return (List<T>)list;
   23.14      }
   23.15  
   23.16 -    private static Iterator<?> EMPTYITERATOR = new Iterator<Object>() {
   23.17 +    private static final Iterator<?> EMPTYITERATOR = new Iterator<Object>() {
   23.18              public boolean hasNext() {
   23.19                  return false;
   23.20              }
    24.1 --- a/src/share/classes/com/sun/tools/javac/util/MandatoryWarningHandler.java	Mon Dec 10 12:10:50 2012 +0000
    24.2 +++ b/src/share/classes/com/sun/tools/javac/util/MandatoryWarningHandler.java	Mon Dec 10 16:21:26 2012 +0000
    24.3 @@ -1,5 +1,5 @@
    24.4  /*
    24.5 - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
    24.6 + * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
    24.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    24.8   *
    24.9   * This code is free software; you can redistribute it and/or modify it
   24.10 @@ -91,7 +91,7 @@
   24.11          DeferredDiagnosticKind(String v) { value = v; }
   24.12          String getKey(String prefix) { return prefix + value; }
   24.13  
   24.14 -        private String value;
   24.15 +        private final String value;
   24.16      }
   24.17  
   24.18  
    25.1 --- a/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java	Mon Dec 10 12:10:50 2012 +0000
    25.2 +++ b/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java	Mon Dec 10 16:21:26 2012 +0000
    25.3 @@ -249,7 +249,7 @@
    25.4          INTERSECTION("where.description.intersection");
    25.5  
    25.6          /** resource key for this where clause kind */
    25.7 -        private String key;
    25.8 +        private final String key;
    25.9  
   25.10          WhereClauseKind(String key) {
   25.11              this.key = key;
    26.1 --- a/src/share/classes/com/sun/tools/javah/JavahTask.java	Mon Dec 10 12:10:50 2012 +0000
    26.2 +++ b/src/share/classes/com/sun/tools/javah/JavahTask.java	Mon Dec 10 16:21:26 2012 +0000
    26.3 @@ -147,7 +147,7 @@
    26.4          }
    26.5      }
    26.6  
    26.7 -    static Option[] recognizedOptions = {
    26.8 +    static final Option[] recognizedOptions = {
    26.9          new Option(true, "-o") {
   26.10              void process(JavahTask task, String opt, String arg) {
   26.11                  task.ofile = new File(arg);
    27.1 --- a/src/share/classes/com/sun/tools/javap/JavapTask.java	Mon Dec 10 12:10:50 2012 +0000
    27.2 +++ b/src/share/classes/com/sun/tools/javap/JavapTask.java	Mon Dec 10 16:21:26 2012 +0000
    27.3 @@ -117,7 +117,7 @@
    27.4          final String[] aliases;
    27.5      }
    27.6  
    27.7 -    static Option[] recognizedOptions = {
    27.8 +    static final Option[] recognizedOptions = {
    27.9  
   27.10          new Option(false, "-help", "--help", "-?") {
   27.11              void process(JavapTask task, String opt, String arg) {
    28.1 --- a/src/share/classes/javax/lang/model/element/Modifier.java	Mon Dec 10 12:10:50 2012 +0000
    28.2 +++ b/src/share/classes/javax/lang/model/element/Modifier.java	Mon Dec 10 16:21:26 2012 +0000
    28.3 @@ -1,5 +1,5 @@
    28.4  /*
    28.5 - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
    28.6 + * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
    28.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    28.8   *
    28.9   * This code is free software; you can redistribute it and/or modify it
   28.10 @@ -61,16 +61,10 @@
   28.11      /** The modifier {@code native} */          NATIVE,
   28.12      /** The modifier {@code strictfp} */        STRICTFP;
   28.13  
   28.14 -
   28.15 -    private String lowercase = null;    // modifier name in lowercase
   28.16 -
   28.17      /**
   28.18       * Returns this modifier's name in lowercase.
   28.19       */
   28.20      public String toString() {
   28.21 -        if (lowercase == null) {
   28.22 -           lowercase = name().toLowerCase(java.util.Locale.US);
   28.23 -        }
   28.24 -        return lowercase;
   28.25 +        return name().toLowerCase(java.util.Locale.US);
   28.26      }
   28.27  }
    29.1 --- a/src/share/classes/javax/lang/model/util/ElementFilter.java	Mon Dec 10 12:10:50 2012 +0000
    29.2 +++ b/src/share/classes/javax/lang/model/util/ElementFilter.java	Mon Dec 10 16:21:26 2012 +0000
    29.3 @@ -66,19 +66,19 @@
    29.4  public class ElementFilter {
    29.5      private ElementFilter() {} // Do not instantiate.
    29.6  
    29.7 -    private static Set<ElementKind> CONSTRUCTOR_KIND =
    29.8 +    private static final Set<ElementKind> CONSTRUCTOR_KIND =
    29.9          Collections.unmodifiableSet(EnumSet.of(ElementKind.CONSTRUCTOR));
   29.10  
   29.11 -    private static Set<ElementKind> FIELD_KINDS =
   29.12 +    private static final Set<ElementKind> FIELD_KINDS =
   29.13          Collections.unmodifiableSet(EnumSet.of(ElementKind.FIELD,
   29.14                                                 ElementKind.ENUM_CONSTANT));
   29.15 -    private static Set<ElementKind> METHOD_KIND =
   29.16 +    private static final Set<ElementKind> METHOD_KIND =
   29.17          Collections.unmodifiableSet(EnumSet.of(ElementKind.METHOD));
   29.18  
   29.19 -    private static Set<ElementKind> PACKAGE_KIND =
   29.20 +    private static final Set<ElementKind> PACKAGE_KIND =
   29.21          Collections.unmodifiableSet(EnumSet.of(ElementKind.PACKAGE));
   29.22  
   29.23 -    private static Set<ElementKind> TYPE_KINDS =
   29.24 +    private static final Set<ElementKind> TYPE_KINDS =
   29.25          Collections.unmodifiableSet(EnumSet.of(ElementKind.CLASS,
   29.26                                                 ElementKind.ENUM,
   29.27                                                 ElementKind.INTERFACE,
    30.1 --- a/src/share/classes/javax/tools/StandardLocation.java	Mon Dec 10 12:10:50 2012 +0000
    30.2 +++ b/src/share/classes/javax/tools/StandardLocation.java	Mon Dec 10 16:21:26 2012 +0000
    30.3 @@ -97,7 +97,7 @@
    30.4          return locations.get(name);
    30.5      }
    30.6      //where
    30.7 -        private static ConcurrentMap<String,Location> locations
    30.8 +        private static final ConcurrentMap<String,Location> locations
    30.9              = new ConcurrentHashMap<String,Location>();
   30.10  
   30.11      public String getName() { return name(); }
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/test/tools/javac/T8003967/DetectMutableStaticFields.java	Mon Dec 10 16:21:26 2012 +0000
    31.3 @@ -0,0 +1,242 @@
    31.4 +/*
    31.5 + * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
    31.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    31.7 + *
    31.8 + * This code is free software; you can redistribute it and/or modify it
    31.9 + * under the terms of the GNU General Public License version 2 only, as
   31.10 + * published by the Free Software Foundation.  Oracle designates this
   31.11 + * particular file as subject to the "Classpath" exception as provided
   31.12 + * by Oracle in the LICENSE file that accompanied this code.
   31.13 + *
   31.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   31.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   31.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   31.17 + * version 2 for more details (a copy is included in the LICENSE file that
   31.18 + * accompanied this code).
   31.19 + *
   31.20 + * You should have received a copy of the GNU General Public License version
   31.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   31.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   31.23 + *
   31.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   31.25 + * or visit www.oracle.com if you need additional information or have any
   31.26 + * questions.
   31.27 + */
   31.28 +
   31.29 +/*
   31.30 + * @test
   31.31 + * @bug 8003967
   31.32 + * @summary detect and remove all mutable implicit static enum fields in langtools
   31.33 + * @run main DetectMutableStaticFields
   31.34 + */
   31.35 +
   31.36 +import java.io.File;
   31.37 +import java.io.IOException;
   31.38 +import java.net.URI;
   31.39 +import java.net.URISyntaxException;
   31.40 +import java.util.ArrayList;
   31.41 +import java.util.Arrays;
   31.42 +import java.util.EnumSet;
   31.43 +import java.util.HashMap;
   31.44 +import java.util.List;
   31.45 +import java.util.Map;
   31.46 +import javax.tools.JavaCompiler;
   31.47 +import javax.tools.JavaFileManager;
   31.48 +import javax.tools.JavaFileObject;
   31.49 +import javax.tools.StandardJavaFileManager;
   31.50 +import javax.tools.StandardLocation;
   31.51 +import javax.tools.ToolProvider;
   31.52 +import com.sun.tools.classfile.ClassFile;
   31.53 +import com.sun.tools.classfile.ConstantPoolException;
   31.54 +import com.sun.tools.classfile.Descriptor;
   31.55 +import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
   31.56 +import com.sun.tools.classfile.Field;
   31.57 +
   31.58 +import static javax.tools.JavaFileObject.Kind.CLASS;
   31.59 +import static com.sun.tools.classfile.AccessFlags.ACC_ENUM;
   31.60 +import static com.sun.tools.classfile.AccessFlags.ACC_FINAL;
   31.61 +import static com.sun.tools.classfile.AccessFlags.ACC_STATIC;
   31.62 +
   31.63 +public class DetectMutableStaticFields {
   31.64 +
   31.65 +    private static final String keyResource =
   31.66 +            "com/sun/tools/javac/tree/JCTree.class";
   31.67 +
   31.68 +    private String[] packagesToSeekFor = new String[] {
   31.69 +        "javax.tools",
   31.70 +        "javax.lang.model",
   31.71 +        "com.sun.javadoc",
   31.72 +        "com.sun.source",
   31.73 +        "com.sun.tools.classfile",
   31.74 +        "com.sun.tools.doclets",
   31.75 +        "com.sun.tools.javac",
   31.76 +        "com.sun.tools.javadoc",
   31.77 +        "com.sun.tools.javah",
   31.78 +        "com.sun.tools.javap",
   31.79 +    };
   31.80 +
   31.81 +    private static final Map<String, List<String>> classFieldsToIgnoreMap = new HashMap<>();
   31.82 +
   31.83 +    static {
   31.84 +        classFieldsToIgnoreMap.
   31.85 +                put("javax/tools/ToolProvider",
   31.86 +                    Arrays.asList("instance"));
   31.87 +        classFieldsToIgnoreMap.
   31.88 +                put("com/sun/tools/javah/JavahTask",
   31.89 +                    Arrays.asList("versionRB"));
   31.90 +        classFieldsToIgnoreMap.
   31.91 +                put("com/sun/tools/classfile/Dependencies$DefaultFilter",
   31.92 +                    Arrays.asList("instance"));
   31.93 +        classFieldsToIgnoreMap.
   31.94 +                put("com/sun/tools/javap/JavapTask",
   31.95 +                    Arrays.asList("versionRB"));
   31.96 +        classFieldsToIgnoreMap.
   31.97 +                put("com/sun/tools/doclets/formats/html/HtmlDoclet",
   31.98 +                    Arrays.asList("docletToStart"));
   31.99 +        classFieldsToIgnoreMap.
  31.100 +                put("com/sun/tools/javac/util/JCDiagnostic",
  31.101 +                    Arrays.asList("fragmentFormatter"));
  31.102 +        classFieldsToIgnoreMap.
  31.103 +                put("com/sun/tools/javac/util/JavacMessages",
  31.104 +                    Arrays.asList("defaultBundle", "defaultMessages"));
  31.105 +        classFieldsToIgnoreMap.
  31.106 +                put("com/sun/tools/javac/file/ZipFileIndexCache",
  31.107 +                    Arrays.asList("sharedInstance"));
  31.108 +        classFieldsToIgnoreMap.
  31.109 +                put("com/sun/tools/javac/main/JavaCompiler",
  31.110 +                    Arrays.asList("versionRB"));
  31.111 +        classFieldsToIgnoreMap.
  31.112 +                put("com/sun/tools/javac/code/Type",
  31.113 +                    Arrays.asList("moreInfo"));
  31.114 +        classFieldsToIgnoreMap.
  31.115 +                put("com/sun/tools/javac/util/SharedNameTable",
  31.116 +                    Arrays.asList("freelist"));
  31.117 +        classFieldsToIgnoreMap.
  31.118 +                put("com/sun/tools/javac/util/Log",
  31.119 +                    Arrays.asList("useRawMessages"));
  31.120 +    }
  31.121 +
  31.122 +    private List<String> errors = new ArrayList<>();
  31.123 +
  31.124 +    public static void main(String[] args) {
  31.125 +        try {
  31.126 +            new DetectMutableStaticFields().run();
  31.127 +        } catch (Exception ex) {
  31.128 +            throw new AssertionError(
  31.129 +                    "Exception during test execution with cause ",
  31.130 +                    ex.getCause());
  31.131 +        }
  31.132 +    }
  31.133 +
  31.134 +    private void run()
  31.135 +        throws
  31.136 +            IOException,
  31.137 +            ConstantPoolException,
  31.138 +            InvalidDescriptor,
  31.139 +            URISyntaxException {
  31.140 +
  31.141 +        URI resource = findResource(keyResource);
  31.142 +        if (resource == null) {
  31.143 +            throw new AssertionError("Resource " + keyResource +
  31.144 +                "not found in the class path");
  31.145 +        }
  31.146 +        analyzeResource(resource);
  31.147 +
  31.148 +        if (errors.size() > 0) {
  31.149 +            for (String error: errors) {
  31.150 +                System.err.println(error);
  31.151 +            }
  31.152 +            throw new AssertionError("There are mutable fields, "
  31.153 +                + "please check output");
  31.154 +        }
  31.155 +    }
  31.156 +
  31.157 +    URI findResource(String className) throws URISyntaxException {
  31.158 +        URI uri = getClass().getClassLoader().getResource(className).toURI();
  31.159 +        if (uri.getScheme().equals("jar")) {
  31.160 +            String ssp = uri.getRawSchemeSpecificPart();
  31.161 +            int sep = ssp.lastIndexOf("!");
  31.162 +            uri = new URI(ssp.substring(0, sep));
  31.163 +        } else if (uri.getScheme().equals("file")) {
  31.164 +            uri = new URI(uri.getPath().substring(0,
  31.165 +                    uri.getPath().length() - keyResource.length()));
  31.166 +        }
  31.167 +        return uri;
  31.168 +    }
  31.169 +
  31.170 +    boolean shouldAnalyzePackage(String packageName) {
  31.171 +        for (String aPackage: packagesToSeekFor) {
  31.172 +            if (packageName.contains(aPackage)) {
  31.173 +                return true;
  31.174 +            }
  31.175 +        }
  31.176 +        return false;
  31.177 +    }
  31.178 +
  31.179 +    void analyzeResource(URI resource)
  31.180 +        throws
  31.181 +            IOException,
  31.182 +            ConstantPoolException,
  31.183 +            InvalidDescriptor {
  31.184 +        JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
  31.185 +        StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
  31.186 +        JavaFileManager.Location location =
  31.187 +                StandardLocation.locationFor(resource.getPath());
  31.188 +        fm.setLocation(location, com.sun.tools.javac.util.List.of(
  31.189 +                new File(resource.getPath())));
  31.190 +
  31.191 +        for (JavaFileObject file : fm.list(location, "", EnumSet.of(CLASS), true)) {
  31.192 +            String className = fm.inferBinaryName(location, file);
  31.193 +            int index = className.lastIndexOf('.');
  31.194 +            String pckName = index == -1 ? "" : className.substring(0, index);
  31.195 +            if (shouldAnalyzePackage(pckName)) {
  31.196 +                analyzeClassFile(ClassFile.read(file.openInputStream()));
  31.197 +            }
  31.198 +        }
  31.199 +    }
  31.200 +
  31.201 +    List<String> currentFieldsToIgnore;
  31.202 +
  31.203 +    boolean ignoreField(String field) {
  31.204 +        if (currentFieldsToIgnore != null) {
  31.205 +            for (String fieldToIgnore : currentFieldsToIgnore) {
  31.206 +                if (field.equals(fieldToIgnore)) {
  31.207 +                    return true;
  31.208 +                }
  31.209 +            }
  31.210 +        }
  31.211 +        return false;
  31.212 +    }
  31.213 +
  31.214 +    void analyzeClassFile(ClassFile classFileToCheck)
  31.215 +        throws
  31.216 +            IOException,
  31.217 +            ConstantPoolException,
  31.218 +            Descriptor.InvalidDescriptor {
  31.219 +        boolean enumClass =
  31.220 +                (classFileToCheck.access_flags.flags & ACC_ENUM) != 0;
  31.221 +        boolean nonFinalStaticEnumField;
  31.222 +        boolean nonFinalStaticField;
  31.223 +
  31.224 +        currentFieldsToIgnore =
  31.225 +                classFieldsToIgnoreMap.get(classFileToCheck.getName());
  31.226 +
  31.227 +        for (Field field : classFileToCheck.fields) {
  31.228 +            if (ignoreField(field.getName(classFileToCheck.constant_pool))) {
  31.229 +                continue;
  31.230 +            }
  31.231 +            nonFinalStaticEnumField =
  31.232 +                    (field.access_flags.flags & (ACC_ENUM | ACC_FINAL)) == 0;
  31.233 +            nonFinalStaticField =
  31.234 +                    (field.access_flags.flags & ACC_STATIC) != 0 &&
  31.235 +                    (field.access_flags.flags & ACC_FINAL) == 0;
  31.236 +            if (enumClass ? nonFinalStaticEnumField : nonFinalStaticField) {
  31.237 +                errors.add("There is a mutable field named " +
  31.238 +                        field.getName(classFileToCheck.constant_pool) +
  31.239 +                        ", at class " +
  31.240 +                        classFileToCheck.getName());
  31.241 +            }
  31.242 +        }
  31.243 +    }
  31.244 +
  31.245 +}

mercurial