FinalParametersCheck.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;
21
22
import java.util.Arrays;
23
import java.util.Collections;
24
import java.util.Set;
25
import java.util.stream.Collectors;
26
27
import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
28
import com.puppycrawl.tools.checkstyle.api.DetailAST;
29
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
30
import com.puppycrawl.tools.checkstyle.utils.CheckUtils;
31
import com.puppycrawl.tools.checkstyle.utils.CommonUtils;
32
33
/**
34
 * Check that method/constructor/catch/foreach parameters are final.
35
 * The user can set the token set to METHOD_DEF, CONSTRUCTOR_DEF,
36
 * LITERAL_CATCH, FOR_EACH_CLAUSE or any combination of these token
37
 * types, to control the scope of this check.
38
 * Default scope is both METHOD_DEF and CONSTRUCTOR_DEF.
39
 * <p>
40
 * Check has an option <b>ignorePrimitiveTypes</b> which allows ignoring lack of
41
 * final modifier at
42
 * <a href="http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html">
43
 *  primitive data type</a> parameter. Default value <b>false</b>.
44
 * </p>
45
 * E.g.:
46
 * <p>
47
 * {@code
48
 * private void foo(int x) { ... } //parameter is of primitive type
49
 * }
50
 * </p>
51
 *
52
 * @author lkuehne
53
 * @author o_sukhodolsky
54
 * @author Michael Studman
55
 * @author <a href="mailto:nesterenko-aleksey@list.ru">Aleksey Nesterenko</a>
56
 */
57
public class FinalParametersCheck extends AbstractCheck {
58
59
    /**
60
     * A key is pointing to the warning message text in "messages.properties"
61
     * file.
62
     */
63
    public static final String MSG_KEY = "final.parameter";
64
65
    /**
66
     * Contains
67
     * <a href="http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html">
68
     * primitive datatypes</a>.
69
     */
70
    private final Set<Integer> primitiveDataTypes = Collections.unmodifiableSet(
71
        Arrays.stream(new Integer[] {
72
            TokenTypes.LITERAL_BYTE,
73
            TokenTypes.LITERAL_SHORT,
74
            TokenTypes.LITERAL_INT,
75
            TokenTypes.LITERAL_LONG,
76
            TokenTypes.LITERAL_FLOAT,
77
            TokenTypes.LITERAL_DOUBLE,
78
            TokenTypes.LITERAL_BOOLEAN,
79
            TokenTypes.LITERAL_CHAR, })
80
        .collect(Collectors.toSet()));
81
82
    /**
83
     * Option to ignore primitive types as params.
84
     */
85
    private boolean ignorePrimitiveTypes;
86
87
    /**
88
     * Sets ignoring primitive types as params.
89
     * @param ignorePrimitiveTypes true or false.
90
     */
91
    public void setIgnorePrimitiveTypes(boolean ignorePrimitiveTypes) {
92
        this.ignorePrimitiveTypes = ignorePrimitiveTypes;
93
    }
94
95
    @Override
96
    public int[] getDefaultTokens() {
97 1 1. getDefaultTokens : mutated return of Object value for com/puppycrawl/tools/checkstyle/checks/FinalParametersCheck::getDefaultTokens to ( if (x != null) null else throw new RuntimeException ) → KILLED
        return new int[] {
98
            TokenTypes.METHOD_DEF,
99
            TokenTypes.CTOR_DEF,
100
        };
101
    }
102
103
    @Override
104
    public int[] getAcceptableTokens() {
105 1 1. getAcceptableTokens : mutated return of Object value for com/puppycrawl/tools/checkstyle/checks/FinalParametersCheck::getAcceptableTokens to ( if (x != null) null else throw new RuntimeException ) → KILLED
        return new int[] {
106
            TokenTypes.METHOD_DEF,
107
            TokenTypes.CTOR_DEF,
108
            TokenTypes.LITERAL_CATCH,
109
            TokenTypes.FOR_EACH_CLAUSE,
110
        };
111
    }
112
113
    @Override
114
    public int[] getRequiredTokens() {
115 1 1. getRequiredTokens : mutated return of Object value for com/puppycrawl/tools/checkstyle/checks/FinalParametersCheck::getRequiredTokens to ( if (x != null) null else throw new RuntimeException ) → KILLED
        return CommonUtils.EMPTY_INT_ARRAY;
116
    }
117
118
    @Override
119
    public void visitToken(DetailAST ast) {
120
        // don't flag interfaces
121
        final DetailAST container = ast.getParent().getParent();
122 1 1. visitToken : negated conditional → KILLED
        if (container.getType() != TokenTypes.INTERFACE_DEF) {
123 1 1. visitToken : negated conditional → KILLED
            if (ast.getType() == TokenTypes.LITERAL_CATCH) {
124 1 1. visitToken : removed call to com/puppycrawl/tools/checkstyle/checks/FinalParametersCheck::visitCatch → KILLED
                visitCatch(ast);
125
            }
126 1 1. visitToken : negated conditional → KILLED
            else if (ast.getType() == TokenTypes.FOR_EACH_CLAUSE) {
127 1 1. visitToken : removed call to com/puppycrawl/tools/checkstyle/checks/FinalParametersCheck::visitForEachClause → KILLED
                visitForEachClause(ast);
128
            }
129
            else {
130 1 1. visitToken : removed call to com/puppycrawl/tools/checkstyle/checks/FinalParametersCheck::visitMethod → KILLED
                visitMethod(ast);
131
            }
132
        }
133
    }
134
135
    /**
136
     * Checks parameters of the method or ctor.
137
     * @param method method or ctor to check.
138
     */
139
    private void visitMethod(final DetailAST method) {
140
        final DetailAST modifiers =
141
            method.findFirstToken(TokenTypes.MODIFIERS);
142
        // exit on fast lane if there is nothing to check here
143
144 1 1. visitMethod : negated conditional → KILLED
        if (method.branchContains(TokenTypes.PARAMETER_DEF)
145
                // ignore abstract and native methods
146 1 1. visitMethod : negated conditional → KILLED
                && !modifiers.branchContains(TokenTypes.ABSTRACT)
147 1 1. visitMethod : negated conditional → KILLED
                && !modifiers.branchContains(TokenTypes.LITERAL_NATIVE)) {
148
            // we can now be sure that there is at least one parameter
149
            final DetailAST parameters =
150
                method.findFirstToken(TokenTypes.PARAMETERS);
151
            DetailAST child = parameters.getFirstChild();
152 1 1. visitMethod : negated conditional → KILLED
            while (child != null) {
153
                // children are PARAMETER_DEF and COMMA
154 1 1. visitMethod : negated conditional → KILLED
                if (child.getType() == TokenTypes.PARAMETER_DEF) {
155 1 1. visitMethod : removed call to com/puppycrawl/tools/checkstyle/checks/FinalParametersCheck::checkParam → KILLED
                    checkParam(child);
156
                }
157
                child = child.getNextSibling();
158
            }
159
        }
160
    }
161
162
    /**
163
     * Checks parameter of the catch block.
164
     * @param catchClause catch block to check.
165
     */
166
    private void visitCatch(final DetailAST catchClause) {
167 1 1. visitCatch : removed call to com/puppycrawl/tools/checkstyle/checks/FinalParametersCheck::checkParam → KILLED
        checkParam(catchClause.findFirstToken(TokenTypes.PARAMETER_DEF));
168
    }
169
170
    /**
171
     * Checks parameter of the for each clause.
172
     * @param forEachClause for each clause to check.
173
     */
174
    private void visitForEachClause(final DetailAST forEachClause) {
175 1 1. visitForEachClause : removed call to com/puppycrawl/tools/checkstyle/checks/FinalParametersCheck::checkParam → KILLED
        checkParam(forEachClause.findFirstToken(TokenTypes.VARIABLE_DEF));
176
    }
177
178
    /**
179
     * Checks if the given parameter is final.
180
     * @param param parameter to check.
181
     */
182
    private void checkParam(final DetailAST param) {
183 2 1. checkParam : negated conditional → KILLED
2. checkParam : negated conditional → KILLED
        if (!param.branchContains(TokenTypes.FINAL) && !isIgnoredParam(param)
184 1 1. checkParam : negated conditional → KILLED
                && !CheckUtils.isReceiverParameter(param)) {
185
            final DetailAST paramName = param.findFirstToken(TokenTypes.IDENT);
186
            final DetailAST firstNode = CheckUtils.getFirstNode(param);
187 1 1. checkParam : removed call to com/puppycrawl/tools/checkstyle/checks/FinalParametersCheck::log → KILLED
            log(firstNode.getLineNo(), firstNode.getColumnNo(),
188
                MSG_KEY, paramName.getText());
189
        }
190
    }
191
192
    /**
193
     * Checks for skip current param due to <b>ignorePrimitiveTypes</b> option.
194
     * @param paramDef {@link TokenTypes#PARAMETER_DEF PARAMETER_DEF}
195
     * @return true if param has to be skipped.
196
     */
197
    private boolean isIgnoredParam(DetailAST paramDef) {
198
        boolean result = false;
199 1 1. isIgnoredParam : negated conditional → KILLED
        if (ignorePrimitiveTypes) {
200
            final DetailAST parameterType = paramDef
201
                .findFirstToken(TokenTypes.TYPE).getFirstChild();
202 1 1. isIgnoredParam : negated conditional → KILLED
            if (primitiveDataTypes.contains(parameterType.getType())) {
203
                result = true;
204
            }
205
        }
206 1 1. isIgnoredParam : replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED
        return result;
207
    }
208
}

Mutations

97

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

105

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

115

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

122

1.1
Location : visitToken
Killed by : com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest.testIgnorePrimitiveTypesParameters(com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest)
negated conditional → KILLED

123

1.1
Location : visitToken
Killed by : com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest.testReceiverParameters(com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest)
negated conditional → KILLED

124

1.1
Location : visitToken
Killed by : com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest.testCatchToken(com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest)
removed call to com/puppycrawl/tools/checkstyle/checks/FinalParametersCheck::visitCatch → KILLED

126

1.1
Location : visitToken
Killed by : com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest.testReceiverParameters(com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest)
negated conditional → KILLED

127

1.1
Location : visitToken
Killed by : com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest.testForEachClauseToken(com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest)
removed call to com/puppycrawl/tools/checkstyle/checks/FinalParametersCheck::visitForEachClause → KILLED

130

1.1
Location : visitToken
Killed by : com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest.testIgnorePrimitiveTypesParameters(com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest)
removed call to com/puppycrawl/tools/checkstyle/checks/FinalParametersCheck::visitMethod → KILLED

144

1.1
Location : visitMethod
Killed by : com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest.testIgnorePrimitiveTypesParameters(com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest)
negated conditional → KILLED

146

1.1
Location : visitMethod
Killed by : com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest.testIgnorePrimitiveTypesParameters(com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest)
negated conditional → KILLED

147

1.1
Location : visitMethod
Killed by : com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest.testIgnorePrimitiveTypesParameters(com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest)
negated conditional → KILLED

152

1.1
Location : visitMethod
Killed by : com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest.testIgnorePrimitiveTypesParameters(com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest)
negated conditional → KILLED

154

1.1
Location : visitMethod
Killed by : com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest.testIgnorePrimitiveTypesParameters(com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest)
negated conditional → KILLED

155

1.1
Location : visitMethod
Killed by : com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest.testIgnorePrimitiveTypesParameters(com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest)
removed call to com/puppycrawl/tools/checkstyle/checks/FinalParametersCheck::checkParam → KILLED

167

1.1
Location : visitCatch
Killed by : com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest.testCatchToken(com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest)
removed call to com/puppycrawl/tools/checkstyle/checks/FinalParametersCheck::checkParam → KILLED

175

1.1
Location : visitForEachClause
Killed by : com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest.testForEachClauseToken(com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest)
removed call to com/puppycrawl/tools/checkstyle/checks/FinalParametersCheck::checkParam → KILLED

183

1.1
Location : checkParam
Killed by : com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest.testIgnorePrimitiveTypesParameters(com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest)
negated conditional → KILLED

2.2
Location : checkParam
Killed by : com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest.testIgnorePrimitiveTypesParameters(com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest)
negated conditional → KILLED

184

1.1
Location : checkParam
Killed by : com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest.testReceiverParameters(com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest)
negated conditional → KILLED

187

1.1
Location : checkParam
Killed by : com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest.testIgnorePrimitiveTypesParameters(com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest)
removed call to com/puppycrawl/tools/checkstyle/checks/FinalParametersCheck::log → KILLED

199

1.1
Location : isIgnoredParam
Killed by : com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest.testIgnorePrimitiveTypesParameters(com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest)
negated conditional → KILLED

202

1.1
Location : isIgnoredParam
Killed by : com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest.testIgnorePrimitiveTypesParameters(com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest)
negated conditional → KILLED

206

1.1
Location : isIgnoredParam
Killed by : com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest.testIgnorePrimitiveTypesParameters(com.puppycrawl.tools.checkstyle.checks.FinalParametersCheckTest)
replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED

Active mutators

Tests examined


Report generated by PIT 1.2.2