AvoidStaticImportCheck.java

1
////////////////////////////////////////////////////////////////////////////////
2
// checkstyle: Checks Java source code for adherence to a set of rules.
3
// Copyright (C) 2001-2021 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.StatelessCheck;
23
import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
24
import com.puppycrawl.tools.checkstyle.api.DetailAST;
25
import com.puppycrawl.tools.checkstyle.api.FullIdent;
26
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
27
import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
28
29
/**
30
 * <p>
31
 * Checks that there are no static import statements.
32
 * </p>
33
 * <p>
34
 * Rationale: Importing static members can lead to naming conflicts
35
 * between class' members. It may lead to poor code readability since it
36
 * may no longer be clear what class a member resides in (without looking
37
 * at the import statement).
38
 * </p>
39
 * <p>
40
 * If you exclude a starred import on a class this automatically excludes
41
 * each member individually.
42
 * </p>
43
 * <p>
44
 * For example: Excluding {@code java.lang.Math.*}. will allow the import
45
 * of each static member in the Math class individually like
46
 * {@code java.lang.Math.PI, java.lang.Math.cos, ...}.
47
 * </p>
48
 * <ul>
49
 * <li>
50
 * Property {@code excludes} - Control whether to allow for certain classes via
51
 * a star notation to be excluded such as {@code java.lang.Math.*} or specific
52
 * static members to be excluded like {@code java.lang.System.out} for a variable
53
 * or {@code java.lang.Math.random} for a method. See notes section for details.
54
 * Type is {@code java.lang.String[]}.
55
 * Default value is {@code ""}.
56
 * </li>
57
 * </ul>
58
 * <p>
59
 * To configure the check:
60
 * </p>
61
 * <pre>
62
 * &lt;module name="AvoidStaticImport"/&gt;
63
 * </pre>
64
 * <p>Example:</p>
65
 * <pre>
66
 * import static java.lang.Math.pow;          // violation
67
 * import static java.lang.System.*;          // violation
68
 * import java.io.File;                       // OK
69
 * import java.util.*;                        // OK
70
 * </pre>
71
 * <p>
72
 * To configure the check so that the {@code java.lang.System.out} member and all
73
 * members from {@code java.lang.Math} are allowed:
74
 * </p>
75
 * <pre>
76
 * &lt;module name="AvoidStaticImport"&gt;
77
 *   &lt;property name="excludes" value="java.lang.System.out,java.lang.Math.*"/&gt;
78
 * &lt;/module&gt;
79
 * </pre>
80
 * <p>Example:</p>
81
 * <pre>
82
 * import static java.lang.Math.*;            // OK
83
 * import static java.lang.System.out;        // OK
84
 * import static java.lang.Integer.parseInt;  // violation
85
 * import java.io.*;                          // OK
86
 * import java.util.*;                        // OK
87
 * </pre>
88
 * <p>
89
 * Parent is {@code com.puppycrawl.tools.checkstyle.TreeWalker}
90
 * </p>
91
 * <p>
92
 * Violation Message Keys:
93
 * </p>
94
 * <ul>
95
 * <li>
96
 * {@code import.avoidStatic}
97
 * </li>
98
 * </ul>
99
 *
100
 * @since 5.0
101
 */
102
@StatelessCheck
103
public class AvoidStaticImportCheck
104
    extends AbstractCheck {
105
106
    /**
107
     * A key is pointing to the warning message text in "messages.properties"
108
     * file.
109
     */
110
    public static final String MSG_KEY = "import.avoidStatic";
111
112
    /**
113
     * Control whether to allow for certain classes via a star notation to be
114
     * excluded such as {@code java.lang.Math.*} or specific static members
115
     * to be excluded like {@code java.lang.System.out} for a variable or
116
     * {@code java.lang.Math.random} for a method. See notes section for details.
117
     */
118
    private String[] excludes = CommonUtil.EMPTY_STRING_ARRAY;
119
120
    @Override
121
    public int[] getDefaultTokens() {
122 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 getRequiredTokens();
123
    }
124
125
    @Override
126
    public int[] getAcceptableTokens() {
127 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 getRequiredTokens();
128
    }
129
130
    @Override
131
    public int[] getRequiredTokens() {
132 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 new int[] {TokenTypes.STATIC_IMPORT};
133
    }
134
135
    /**
136
     * Setter to control whether to allow for certain classes via a star notation
137
     * to be excluded such as {@code java.lang.Math.*} or specific static members
138
     * to be excluded like {@code java.lang.System.out} for a variable or
139
     * {@code java.lang.Math.random} for a method. See notes section for details.
140
     *
141
     * @param excludes a list of fully-qualified class names/specific
142
     *     static members where static imports are ok
143
     */
144
    public void setExcludes(String... excludes) {
145
        this.excludes = excludes.clone();
146
    }
147
148
    @Override
149
    public void visitToken(final DetailAST ast) {
150
        final DetailAST startingDot =
151
            ast.getFirstChild().getNextSibling();
152
        final FullIdent name = FullIdent.createFullIdent(startingDot);
153
154 3 1. visitToken : negated conditional → KILLED
2. visitToken : removed conditional - replaced equality check with false → KILLED
3. visitToken : removed conditional - replaced equality check with true → KILLED
        if (!isExempt(name.getText())) {
155 1 1. visitToken : removed call to com/puppycrawl/tools/checkstyle/checks/imports/AvoidStaticImportCheck::log → KILLED
            log(startingDot, MSG_KEY, name.getText());
156
        }
157
    }
158
159
    /**
160
     * Checks if a class or static member is exempt from known excludes.
161
     *
162
     * @param classOrStaticMember
163
     *                the class or static member
164
     * @return true if except false if not
165
     */
166
    private boolean isExempt(String classOrStaticMember) {
167
        boolean exempt = false;
168
169
        for (String exclude : excludes) {
170 3 1. isExempt : negated conditional → KILLED
2. isExempt : removed conditional - replaced equality check with false → KILLED
3. isExempt : removed conditional - replaced equality check with true → KILLED
            if (classOrStaticMember.equals(exclude)
171 3 1. isExempt : negated conditional → KILLED
2. isExempt : removed conditional - replaced equality check with false → KILLED
3. isExempt : removed conditional - replaced equality check with true → KILLED
                    || isStarImportOfPackage(classOrStaticMember, exclude)) {
172
                exempt = true;
173
                break;
174
            }
175
        }
176 3 1. isExempt : replaced boolean return with false for com/puppycrawl/tools/checkstyle/checks/imports/AvoidStaticImportCheck::isExempt → KILLED
2. isExempt : replaced boolean return with true for com/puppycrawl/tools/checkstyle/checks/imports/AvoidStaticImportCheck::isExempt → KILLED
3. isExempt : replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED
        return exempt;
177
    }
178
179
    /**
180
     * Returns true if classOrStaticMember is a starred name of package,
181
     *  not just member name.
182
     *
183
     * @param classOrStaticMember - full name of member
184
     * @param exclude - current exclusion
185
     * @return true if member in exclusion list
186
     */
187
    private static boolean isStarImportOfPackage(String classOrStaticMember, String exclude) {
188
        boolean result = false;
189 3 1. isStarImportOfPackage : negated conditional → KILLED
2. isStarImportOfPackage : removed conditional - replaced equality check with false → KILLED
3. isStarImportOfPackage : removed conditional - replaced equality check with true → KILLED
        if (exclude.endsWith(".*")) {
190
            // this section allows explicit imports
191
            // to be exempt when configured using
192
            // a starred import
193
            final String excludeMinusDotStar =
194 1 1. isStarImportOfPackage : Replaced integer subtraction with addition → KILLED
                exclude.substring(0, exclude.length() - 2);
195 3 1. isStarImportOfPackage : negated conditional → KILLED
2. isStarImportOfPackage : removed conditional - replaced equality check with false → KILLED
3. isStarImportOfPackage : removed conditional - replaced equality check with true → KILLED
            if (classOrStaticMember.startsWith(excludeMinusDotStar)
196 3 1. isStarImportOfPackage : negated conditional → KILLED
2. isStarImportOfPackage : removed conditional - replaced equality check with false → KILLED
3. isStarImportOfPackage : removed conditional - replaced equality check with true → KILLED
                    && !classOrStaticMember.equals(excludeMinusDotStar)) {
197
                final String member = classOrStaticMember.substring(
198 1 1. isStarImportOfPackage : Replaced integer addition with subtraction → KILLED
                        excludeMinusDotStar.length() + 1);
199
                // if it contains a dot then it is not a member but a package
200 3 1. isStarImportOfPackage : negated conditional → KILLED
2. isStarImportOfPackage : removed conditional - replaced equality check with false → KILLED
3. isStarImportOfPackage : removed conditional - replaced equality check with true → KILLED
                if (member.indexOf('.') == -1) {
201
                    result = true;
202
                }
203
            }
204
        }
205 3 1. isStarImportOfPackage : replaced boolean return with false for com/puppycrawl/tools/checkstyle/checks/imports/AvoidStaticImportCheck::isStarImportOfPackage → KILLED
2. isStarImportOfPackage : replaced boolean return with true for com/puppycrawl/tools/checkstyle/checks/imports/AvoidStaticImportCheck::isStarImportOfPackage → KILLED
3. isStarImportOfPackage : replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED
        return result;
206
    }
207
208
}

Mutations

122

1.1
Location : getDefaultTokens
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testDefaultOperation()]
mutated return of Object value for com/puppycrawl/tools/checkstyle/checks/imports/AvoidStaticImportCheck::getDefaultTokens to ( if (x != null) null else throw new RuntimeException ) → KILLED

127

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

132

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

154

1.1
Location : visitToken
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testDefaultOperation()]
negated conditional → KILLED

2.2
Location : visitToken
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testDefaultOperation()]
removed conditional - replaced equality check with false → KILLED

3.3
Location : visitToken
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testMemberExcludes()]
removed conditional - replaced equality check with true → KILLED

155

1.1
Location : visitToken
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testDefaultOperation()]
removed call to com/puppycrawl/tools/checkstyle/checks/imports/AvoidStaticImportCheck::log → KILLED

170

1.1
Location : isExempt
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testBogusMemberExcludes()]
negated conditional → KILLED

2.2
Location : isExempt
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testBogusMemberExcludes()]
removed conditional - replaced equality check with false → KILLED

3.3
Location : isExempt
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testMemberExcludes()]
removed conditional - replaced equality check with true → KILLED

171

1.1
Location : isExempt
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testBogusMemberExcludes()]
negated conditional → KILLED

2.2
Location : isExempt
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testStarExcludes()]
removed conditional - replaced equality check with false → KILLED

3.3
Location : isExempt
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testBogusMemberExcludes()]
removed conditional - replaced equality check with true → KILLED

176

1.1
Location : isExempt
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testMemberExcludes()]
replaced boolean return with false for com/puppycrawl/tools/checkstyle/checks/imports/AvoidStaticImportCheck::isExempt → KILLED

2.2
Location : isExempt
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testDefaultOperation()]
replaced boolean return with true for com/puppycrawl/tools/checkstyle/checks/imports/AvoidStaticImportCheck::isExempt → KILLED

3.3
Location : isExempt
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testDefaultOperation()]
replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED

189

1.1
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testMemberExcludes()]
negated conditional → KILLED

2.2
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testStarExcludes()]
removed conditional - replaced equality check with false → KILLED

3.3
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testMemberExcludes()]
removed conditional - replaced equality check with true → KILLED

194

1.1
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testBogusMemberExcludes()]
Replaced integer subtraction with addition → KILLED

195

1.1
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testStarExcludes()]
negated conditional → KILLED

2.2
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testStarExcludes()]
removed conditional - replaced equality check with false → KILLED

3.3
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testStarExcludes()]
removed conditional - replaced equality check with true → KILLED

196

1.1
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testStarExcludes()]
negated conditional → KILLED

2.2
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testStarExcludes()]
removed conditional - replaced equality check with false → KILLED

3.3
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testInnerClassMemberExcludesStar()]
removed conditional - replaced equality check with true → KILLED

198

1.1
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testStarExcludes()]
Replaced integer addition with subtraction → KILLED

200

1.1
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testBogusMemberExcludes()]
negated conditional → KILLED

2.2
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testStarExcludes()]
removed conditional - replaced equality check with false → KILLED

3.3
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testBogusMemberExcludes()]
removed conditional - replaced equality check with true → KILLED

205

1.1
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testStarExcludes()]
replaced boolean return with false for com/puppycrawl/tools/checkstyle/checks/imports/AvoidStaticImportCheck::isStarImportOfPackage → KILLED

2.2
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testBogusMemberExcludes()]
replaced boolean return with true for com/puppycrawl/tools/checkstyle/checks/imports/AvoidStaticImportCheck::isStarImportOfPackage → KILLED

3.3
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.[engine:junit-jupiter]/[class:com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest]/[method:testBogusMemberExcludes()]
replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED

Active mutators

Tests examined


Report generated by PIT 1.6.3