AvoidStaticImportCheck.java

1
////////////////////////////////////////////////////////////////////////////////
2
// checkstyle: Checks Java source code for adherence to a set of rules.
3
// Copyright (C) 2001-2017 the original author or authors.
4
//
5
// This library is free software; you can redistribute it and/or
6
// modify it under the terms of the GNU Lesser General Public
7
// License as published by the Free Software Foundation; either
8
// version 2.1 of the License, or (at your option) any later version.
9
//
10
// This library is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
// Lesser General Public License for more details.
14
//
15
// You should have received a copy of the GNU Lesser General Public
16
// License along with this library; if not, write to the Free Software
17
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
////////////////////////////////////////////////////////////////////////////////
19
20
package com.puppycrawl.tools.checkstyle.checks.imports;
21
22
import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
23
import com.puppycrawl.tools.checkstyle.api.DetailAST;
24
import com.puppycrawl.tools.checkstyle.api.FullIdent;
25
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
26
import com.puppycrawl.tools.checkstyle.utils.CommonUtils;
27
28
/**
29
 * <p>
30
 * Check that finds static imports.
31
 * </p>
32
 * <p>
33
 * Rationale: Importing static members can lead to naming conflicts
34
 * between class' members. It may lead to poor code readability since it
35
 * may no longer be clear what class a member resides (without looking
36
 * at the import statement).
37
 * </p>
38
 * <p>
39
 * An example of how to configure the check is:
40
 * </p>
41
 * <pre>
42
 * &lt;module name="AvoidStaticImport"&gt;
43
 *   &lt;property name="excludes"
44
 *       value="java.lang.System.out,java.lang.Math.*"/&gt;
45
 * &lt;/module&gt;
46
 * </pre>
47
 * The optional "excludes" property allows for certain classes via a star
48
 * notation to be excluded such as java.lang.Math.* or specific
49
 * static members to be excluded like java.lang.System.out for a variable
50
 * or java.lang.Math.random for a method.
51
 *
52
 * <p>
53
 * If you exclude a starred import on a class this automatically
54
 * excludes each member individually.
55
 * </p>
56
 *
57
 * <p>
58
 * For example:
59
 * Excluding java.lang.Math.* will allow the import of
60
 * each static member in the Math class individually like
61
 * java.lang.Math.PI
62
 * </p>
63
 * @author Travis Schneeberger
64
 */
65
public class AvoidStaticImportCheck
66
    extends AbstractCheck {
67
68
    /**
69
     * A key is pointing to the warning message text in "messages.properties"
70
     * file.
71
     */
72
    public static final String MSG_KEY = "import.avoidStatic";
73
74
    /** The classes/static members to exempt from this check. */
75
    private String[] excludes = CommonUtils.EMPTY_STRING_ARRAY;
76
77
    @Override
78
    public int[] getDefaultTokens() {
79 1 1. getDefaultTokens : mutated return of Object value for com/puppycrawl/tools/checkstyle/checks/imports/AvoidStaticImportCheck::getDefaultTokens to ( if (x != null) null else throw new RuntimeException ) → KILLED
        return getAcceptableTokens();
80
    }
81
82
    @Override
83
    public int[] getAcceptableTokens() {
84 1 1. getAcceptableTokens : mutated return of Object value for com/puppycrawl/tools/checkstyle/checks/imports/AvoidStaticImportCheck::getAcceptableTokens to ( if (x != null) null else throw new RuntimeException ) → KILLED
        return new int[] {TokenTypes.STATIC_IMPORT};
85
    }
86
87
    @Override
88
    public int[] getRequiredTokens() {
89 1 1. getRequiredTokens : mutated return of Object value for com/puppycrawl/tools/checkstyle/checks/imports/AvoidStaticImportCheck::getRequiredTokens to ( if (x != null) null else throw new RuntimeException ) → KILLED
        return getAcceptableTokens();
90
    }
91
92
    /**
93
     * Sets the list of classes or static members to be exempt from the check.
94
     * @param excludes a list of fully-qualified class names/specific
95
     *     static members where static imports are ok
96
     */
97
    public void setExcludes(String... excludes) {
98
        this.excludes = excludes.clone();
99
    }
100
101
    @Override
102
    public void visitToken(final DetailAST ast) {
103
        final DetailAST startingDot =
104
            ast.getFirstChild().getNextSibling();
105
        final FullIdent name = FullIdent.createFullIdent(startingDot);
106
107 1 1. visitToken : negated conditional → KILLED
        if (!isExempt(name.getText())) {
108 1 1. visitToken : removed call to com/puppycrawl/tools/checkstyle/checks/imports/AvoidStaticImportCheck::log → KILLED
            log(startingDot.getLineNo(), MSG_KEY, name.getText());
109
        }
110
    }
111
112
    /**
113
     * Checks if a class or static member is exempt from known excludes.
114
     *
115
     * @param classOrStaticMember
116
     *                the class or static member
117
     * @return true if except false if not
118
     */
119
    private boolean isExempt(String classOrStaticMember) {
120
        boolean exempt = false;
121
122 3 1. isExempt : changed conditional boundary → KILLED
2. isExempt : Changed increment from 1 to -1 → KILLED
3. isExempt : negated conditional → KILLED
        for (String exclude : excludes) {
123 1 1. isExempt : negated conditional → KILLED
            if (classOrStaticMember.equals(exclude)
124 1 1. isExempt : negated conditional → KILLED
                    || isStarImportOfPackage(classOrStaticMember, exclude)) {
125
                exempt = true;
126
                break;
127
            }
128
        }
129 1 1. isExempt : replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED
        return exempt;
130
    }
131
132
    /**
133
     * Returns true if classOrStaticMember is a starred name of package,
134
     *  not just member name.
135
     * @param classOrStaticMember - full name of member
136
     * @param exclude - current exclusion
137
     * @return true if member in exclusion list
138
     */
139
    private static boolean isStarImportOfPackage(String classOrStaticMember, String exclude) {
140
        boolean result = false;
141 1 1. isStarImportOfPackage : negated conditional → KILLED
        if (exclude.endsWith(".*")) {
142
            //this section allows explicit imports
143
            //to be exempt when configured using
144
            //a starred import
145
            final String excludeMinusDotStar =
146 1 1. isStarImportOfPackage : Replaced integer subtraction with addition → KILLED
                exclude.substring(0, exclude.length() - 2);
147 1 1. isStarImportOfPackage : negated conditional → KILLED
            if (classOrStaticMember.startsWith(excludeMinusDotStar)
148 1 1. isStarImportOfPackage : negated conditional → KILLED
                    && !classOrStaticMember.equals(excludeMinusDotStar)) {
149
                final String member = classOrStaticMember.substring(
150 1 1. isStarImportOfPackage : Replaced integer addition with subtraction → KILLED
                        excludeMinusDotStar.length() + 1);
151
                //if it contains a dot then it is not a member but a package
152 1 1. isStarImportOfPackage : negated conditional → KILLED
                if (member.indexOf('.') == -1) {
153
                    result = true;
154
                }
155
            }
156
        }
157 1 1. isStarImportOfPackage : replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED
        return result;
158
    }
159
}

Mutations

79

1.1
Location : getDefaultTokens
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testStarExcludes(com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest)
mutated return of Object value for com/puppycrawl/tools/checkstyle/checks/imports/AvoidStaticImportCheck::getDefaultTokens to ( if (x != null) null else throw new RuntimeException ) → KILLED

84

1.1
Location : getAcceptableTokens
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testGetAcceptableTokens(com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest)
mutated return of Object value for com/puppycrawl/tools/checkstyle/checks/imports/AvoidStaticImportCheck::getAcceptableTokens to ( if (x != null) null else throw new RuntimeException ) → KILLED

89

1.1
Location : getRequiredTokens
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testGetRequiredTokens(com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest)
mutated return of Object value for com/puppycrawl/tools/checkstyle/checks/imports/AvoidStaticImportCheck::getRequiredTokens to ( if (x != null) null else throw new RuntimeException ) → KILLED

107

1.1
Location : visitToken
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testStarExcludes(com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest)
negated conditional → KILLED

108

1.1
Location : visitToken
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testStarExcludes(com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest)
removed call to com/puppycrawl/tools/checkstyle/checks/imports/AvoidStaticImportCheck::log → KILLED

122

1.1
Location : isExempt
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testStarExcludes(com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest)
changed conditional boundary → KILLED

2.2
Location : isExempt
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testStarExcludes(com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest)
Changed increment from 1 to -1 → KILLED

3.3
Location : isExempt
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testStarExcludes(com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest)
negated conditional → KILLED

123

1.1
Location : isExempt
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testStarExcludes(com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest)
negated conditional → KILLED

124

1.1
Location : isExempt
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testStarExcludes(com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest)
negated conditional → KILLED

129

1.1
Location : isExempt
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testStarExcludes(com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest)
replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED

141

1.1
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testStarExcludes(com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest)
negated conditional → KILLED

146

1.1
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testStarExcludes(com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest)
Replaced integer subtraction with addition → KILLED

147

1.1
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testStarExcludes(com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest)
negated conditional → KILLED

148

1.1
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testStarExcludes(com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest)
negated conditional → KILLED

150

1.1
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testStarExcludes(com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest)
Replaced integer addition with subtraction → KILLED

152

1.1
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testStarExcludes(com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest)
negated conditional → KILLED

157

1.1
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testStarExcludes(com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest)
replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED

Active mutators

Tests examined


Report generated by PIT 1.2.2