MutableFieldsAnalyzer.java revision 3822:d8766c39123a
150476Speter/*
282486Sbde * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
3139761Skrion * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4139761Skrion *
521611Swosch * This code is free software; you can redistribute it and/or modify it
618052Sbde * under the terms of the GNU General Public License version 2 only, as
794940Sru * published by the Free Software Foundation.
894940Sru *
994940Sru * This code is distributed in the hope that it will be useful, but WITHOUT
1094940Sru * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11269648Sbapt * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12269648Sbapt * version 2 for more details (a copy is included in the LICENSE file that
13291327Sbdrewery * accompanied this code).
14291327Sbdrewery *
1536494Sbde * You should have received a copy of the GNU General Public License version
1618052Sbde * 2 along with this work; if not, write to the Free Software Foundation,
17291601Sbdrewery * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1836494Sbde *
19125762Skientzle * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20125255Sbde * or visit www.oracle.com if you need additional information or have any
2139412Sphk * questions.
22186647Srwatson */
23168418Spjd
24135771Strhodespackage crules;
25301226Slidl
26125256Sbdeimport java.util.Arrays;
27117183Sruimport java.util.HashMap;
28155211Srwatsonimport java.util.HashSet;
29122404Shartiimport java.util.List;
3079495Sobrienimport java.util.Map;
3136494Sbdeimport java.util.Set;
3236494Sbde
3339259Sgibbsimport com.sun.source.util.JavacTask;
34296337Sbdreweryimport com.sun.source.util.TaskEvent.Kind;
35296337Sbdreweryimport com.sun.tools.javac.tree.JCTree.JCVariableDecl;
36296337Sbdreweryimport com.sun.tools.javac.tree.TreeScanner;
37296337Sbdrewery
38296337Sbdreweryimport static com.sun.tools.javac.code.Flags.ENUM;
39258838Spjdimport static com.sun.tools.javac.code.Flags.FINAL;
4036494Sbdeimport static com.sun.tools.javac.code.Flags.STATIC;
41260850Sedimport static com.sun.tools.javac.code.Flags.SYNTHETIC;
42292036Sbdreweryimport static com.sun.tools.javac.code.Kinds.Kind.*;
43292036Sbdrewery
4436494Sbde/**This analyzer guards against non-final static fields.*/
45125255Sbdepublic class MutableFieldsAnalyzer extends AbstractCodingRulesAnalyzer {
46179184Sjb
4736494Sbde    public MutableFieldsAnalyzer(JavacTask task) {
48291632Sbdrewery        super(task);
49292037Sbdrewery        treeVisitor = new MutableFieldsVisitor();
50292036Sbdrewery        eventKind = Kind.ANALYZE;
51292036Sbdrewery    }
52278320Sjhb
53300906Sasomers    private boolean ignoreField(String className, String field) {
5476515Sbde        Set<String> fieldsToIgnore = classFieldsToIgnoreMap.get(className);
5539259Sgibbs        return (fieldsToIgnore) != null && fieldsToIgnore.contains(field);
5636494Sbde    }
57135549Sdes
58274116Sdteske    class MutableFieldsVisitor extends TreeScanner {
59179184Sjb
60179184Sjb        @Override
6136494Sbde        public void visitVarDef(JCVariableDecl tree) {
62176439Sru            boolean isJavacPack = tree.sym.outermostClass().fullname.toString()
63255180Semaste                    .contains(packageToCheck);
6474535Sdes            if (isJavacPack &&
65274116Sdteske                (tree.sym.flags() & SYNTHETIC) == 0 &&
6618052Sbde                tree.sym.owner.kind == TYP) {
6776515Sbde                if (!ignoreField(tree.sym.owner.flatName().toString(),
6876515Sbde                        tree.getName().toString())) {
69112461Sru                    boolean enumClass = (tree.sym.owner.flags() & ENUM) != 0;
7036494Sbde                    boolean nonFinalStaticEnumField =
71292036Sbdrewery                            (tree.sym.flags() & (ENUM | FINAL)) == 0;
72125255Sbde                    boolean nonFinalStaticField =
73178828Sdfr                            (tree.sym.flags() & STATIC) != 0 &&
74125255Sbde                            (tree.sym.flags() & FINAL) == 0;
75233294Sstas                    if (enumClass ? nonFinalStaticEnumField : nonFinalStaticField) {
76178828Sdfr                        messages.error(tree, "crules.err.var.must.be.final", tree);
77233294Sstas                    }
78178828Sdfr                }
79292037Sbdrewery            }
80292037Sbdrewery            super.visitVarDef(tree);
81292037Sbdrewery        }
82292037Sbdrewery
83292037Sbdrewery    }
84292037Sbdrewery
8557538Sshin    private static final String packageToCheck = "com.sun.tools.javac";
86194869Sjamie
87125255Sbde    private static final Map<String, Set<String>> classFieldsToIgnoreMap =
88125255Sbde                new HashMap<>();
89125255Sbde
90233294Sstas    private static void ignoreFields(String className, String... fieldNames) {
91104465Sru        classFieldsToIgnoreMap.put(className, new HashSet<>(Arrays.asList(fieldNames)));
92120492Sfjoe    };
93125255Sbde
9436494Sbde    static {
9536494Sbde        ignoreFields("com.sun.tools.javac.util.JCDiagnostic", "fragmentFormatter");
9665916Sache        ignoreFields("com.sun.tools.javac.util.JavacMessages", "defaultBundle", "defaultMessages");
97207842Smm        ignoreFields("com.sun.tools.javac.file.JRTIndex", "sharedInstance");
9836494Sbde        ignoreFields("com.sun.tools.javac.main.JavaCompiler", "versionRB");
99133362Sobrien        ignoreFields("com.sun.tools.javac.code.Type", "moreInfo");
10036494Sbde        ignoreFields("com.sun.tools.javac.util.SharedNameTable", "freelist");
101148100Srwatson        ignoreFields("com.sun.tools.javac.util.Log", "useRawMessages");
10276515Sbde        ignoreFields("com.sun.tools.javac.util.JDK9Wrappers$ModuleFinder",
10390796Sgshapiro                "moduleFinderClass", "ofMethod");
104292037Sbdrewery        ignoreFields("com.sun.tools.javac.util.JDK9Wrappers$Configuration",
10536494Sbde                "configurationClass", "resolveRequiresAndUsesMethod");
106279219Sken        ignoreFields("com.sun.tools.javac.util.JDK9Wrappers$Layer",
107292037Sbdrewery                "layerClass", "bootMethod", "defineModulesWithOneLoaderMethod", "configurationMethod");
108291639Sbdrewery        ignoreFields("com.sun.tools.javac.util.JDK9Wrappers$Module",
10936494Sbde                "addExportsMethod", "addUsesMethod", "getModuleMethod", "getUnnamedModuleMethod");
110167359Srafan        ignoreFields("com.sun.tools.javac.util.JDK9Wrappers$ModuleDescriptor$Version",
11152419Sjulian                "versionClass", "parseMethod");
112121615Sharti        ignoreFields("com.sun.tools.javac.util.JDK9Wrappers$ServiceLoaderHelper",
113258065Spjd                "loadMethod");
114168407Spjd        ignoreFields("com.sun.tools.javac.util.JDK9Wrappers$VMHelper",
115292037Sbdrewery                "vmClass", "getRuntimeArgumentsMethod");
11636494Sbde        ignoreFields("com.sun.tools.javac.util.JDK9Wrappers$JmodFile",
117292037Sbdrewery                "jmodFileClass", "checkMagicMethod");
118292037Sbdrewery    }
11959770Sbde
12076515Sbde}
121291632Sbdrewery