AvoidStaticImportCheck.java

1
////////////////////////////////////////////////////////////////////////////////
2
// checkstyle: Checks Java source code for adherence to a set of rules.
3
// Copyright (C) 2001-2020 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
 * Default value is {@code {}}.
55
 * </li>
56
 * </ul>
57
 * <p>
58
 * To configure the check:
59
 * </p>
60
 * <pre>
61
 * &lt;module name="AvoidStaticImport"/&gt;
62
 * </pre>
63
 * <p>
64
 * To configure the check so that the {@code java.lang.System.out} member and all
65
 * members from {@code java.lang.Math} are allowed:
66
 * </p>
67
 * <pre>
68
 * &lt;module name="AvoidStaticImport"&gt;
69
 *   &lt;property name="excludes" value="java.lang.System.out,java.lang.Math.*"/&gt;
70
 * &lt;/module&gt;
71
 * </pre>
72
 *
73
 * @since 5.0
74
 */
75
@StatelessCheck
76
public class AvoidStaticImportCheck
77
    extends AbstractCheck {
78
79
    /**
80
     * A key is pointing to the warning message text in "messages.properties"
81
     * file.
82
     */
83
    public static final String MSG_KEY = "import.avoidStatic";
84
85
    /**
86
     * Control whether to allow for certain classes via a star notation to be
87
     * excluded such as {@code java.lang.Math.*} or specific static members
88
     * to be excluded like {@code java.lang.System.out} for a variable or
89
     * {@code java.lang.Math.random} for a method. See notes section for details.
90
     */
91
    private String[] excludes = CommonUtil.EMPTY_STRING_ARRAY;
92
93
    @Override
94
    public int[] getDefaultTokens() {
95 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();
96
    }
97
98
    @Override
99
    public int[] getAcceptableTokens() {
100 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();
101
    }
102
103
    @Override
104
    public int[] getRequiredTokens() {
105 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};
106
    }
107
108
    /**
109
     * Setter to control whether to allow for certain classes via a star notation
110
     * to be excluded such as {@code java.lang.Math.*} or specific static members
111
     * to be excluded like {@code java.lang.System.out} for a variable or
112
     * {@code java.lang.Math.random} for a method. See notes section for details.
113
     *
114
     * @param excludes a list of fully-qualified class names/specific
115
     *     static members where static imports are ok
116
     */
117
    public void setExcludes(String... excludes) {
118
        this.excludes = excludes.clone();
119
    }
120
121
    @Override
122
    public void visitToken(final DetailAST ast) {
123
        final DetailAST startingDot =
124
            ast.getFirstChild().getNextSibling();
125
        final FullIdent name = FullIdent.createFullIdent(startingDot);
126
127 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())) {
128 1 1. visitToken : removed call to com/puppycrawl/tools/checkstyle/checks/imports/AvoidStaticImportCheck::log → KILLED
            log(startingDot.getLineNo(), MSG_KEY, name.getText());
129
        }
130
    }
131
132
    /**
133
     * Checks if a class or static member is exempt from known excludes.
134
     *
135
     * @param classOrStaticMember
136
     *                the class or static member
137
     * @return true if except false if not
138
     */
139
    private boolean isExempt(String classOrStaticMember) {
140
        boolean exempt = false;
141
142
        for (String exclude : excludes) {
143 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)
144 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)) {
145
                exempt = true;
146
                break;
147
            }
148
        }
149 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;
150
    }
151
152
    /**
153
     * Returns true if classOrStaticMember is a starred name of package,
154
     *  not just member name.
155
     * @param classOrStaticMember - full name of member
156
     * @param exclude - current exclusion
157
     * @return true if member in exclusion list
158
     */
159
    private static boolean isStarImportOfPackage(String classOrStaticMember, String exclude) {
160
        boolean result = false;
161 3 1. isStarImportOfPackage : removed conditional - replaced equality check with true → SURVIVED
2. isStarImportOfPackage : negated conditional → KILLED
3. isStarImportOfPackage : removed conditional - replaced equality check with false → KILLED
        if (exclude.endsWith(".*")) {
162
            // this section allows explicit imports
163
            // to be exempt when configured using
164
            // a starred import
165
            final String excludeMinusDotStar =
166 1 1. isStarImportOfPackage : Replaced integer subtraction with addition → KILLED
                exclude.substring(0, exclude.length() - 2);
167 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)
168 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)) {
169
                final String member = classOrStaticMember.substring(
170 1 1. isStarImportOfPackage : Replaced integer addition with subtraction → KILLED
                        excludeMinusDotStar.length() + 1);
171
                // if it contains a dot then it is not a member but a package
172 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) {
173
                    result = true;
174
                }
175
            }
176
        }
177 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;
178
    }
179
180
}

Mutations

95

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

100

1.1
Location : getAcceptableTokens
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.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

105

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

127

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

2.2
Location : visitToken
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testMemberExcludes()
removed conditional - replaced equality check with false → KILLED

3.3
Location : visitToken
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testMemberExcludes()
removed conditional - replaced equality check with true → KILLED

128

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

143

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

2.2
Location : isExempt
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testMemberExcludes()
removed conditional - replaced equality check with false → KILLED

3.3
Location : isExempt
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testMemberExcludes()
removed conditional - replaced equality check with true → KILLED

144

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

2.2
Location : isExempt
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testStarExcludes()
removed conditional - replaced equality check with false → KILLED

3.3
Location : isExempt
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testMemberExcludes()
removed conditional - replaced equality check with true → KILLED

149

1.1
Location : isExempt
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.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.testMemberExcludes()
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.testMemberExcludes()
replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED

161

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

2.2
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testStarExcludes()
removed conditional - replaced equality check with false → KILLED

3.3
Location : isStarImportOfPackage
Killed by : none
removed conditional - replaced equality check with true → SURVIVED

166

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

167

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

2.2
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testStarExcludes()
removed conditional - replaced equality check with false → KILLED

3.3
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testStarExcludes()
removed conditional - replaced equality check with true → KILLED

168

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

2.2
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testStarExcludes()
removed conditional - replaced equality check with false → KILLED

3.3
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testInnerClassMemberExcludesStar()
removed conditional - replaced equality check with true → KILLED

170

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

172

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

2.2
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testStarExcludes()
removed conditional - replaced equality check with false → KILLED

3.3
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.testBogusMemberExcludes()
removed conditional - replaced equality check with true → KILLED

177

1.1
Location : isStarImportOfPackage
Killed by : com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheckTest.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.testMemberExcludes()
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.testMemberExcludes()
replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED

Active mutators

Tests examined


Report generated by PIT 1.4.9