MultipleVariableDeclarationsCheck.java

1
////////////////////////////////////////////////////////////////////////////////
2
// checkstyle: Checks Java source code for adherence to a set of rules.
3
// Copyright (C) 2001-2018 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.coding;
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.TokenTypes;
26
import com.puppycrawl.tools.checkstyle.utils.CheckUtils;
27
28
/**
29
 * <p>
30
 * Checks that each variable declaration is in its own statement
31
 * and on its own line.
32
 * </p>
33
 * <p>
34
 * Rationale: <a
35
 * href="http://www.oracle.com/technetwork/java/javase/documentation/codeconventions-141270.html">
36
 * the SUN Code conventions chapter 6.1</a> recommends that
37
 * declarations should be one per line.
38
 * </p>
39
 * <p>
40
 * An example of how to configure the check is:
41
 * </p>
42
 * <pre>
43
 * &lt;module name="MultipleVariableDeclarations"/&gt;
44
 * </pre>
45
 * @author o_sukhodolsky
46
 */
47
@StatelessCheck
48
public class MultipleVariableDeclarationsCheck extends AbstractCheck {
49
50
    /**
51
     * A key is pointing to the warning message text in "messages.properties"
52
     * file.
53
     */
54
    public static final String MSG_MULTIPLE = "multiple.variable.declarations";
55
56
    /**
57
     * A key is pointing to the warning message text in "messages.properties"
58
     * file.
59
     */
60
    public static final String MSG_MULTIPLE_COMMA = "multiple.variable.declarations.comma";
61
62
    @Override
63
    public int[] getAcceptableTokens() {
64 1 1. getAcceptableTokens : mutated return of Object value for com/puppycrawl/tools/checkstyle/checks/coding/MultipleVariableDeclarationsCheck::getAcceptableTokens to ( if (x != null) null else throw new RuntimeException ) → KILLED
        return getRequiredTokens();
65
    }
66
67
    @Override
68
    public int[] getDefaultTokens() {
69 1 1. getDefaultTokens : mutated return of Object value for com/puppycrawl/tools/checkstyle/checks/coding/MultipleVariableDeclarationsCheck::getDefaultTokens to ( if (x != null) null else throw new RuntimeException ) → KILLED
        return getRequiredTokens();
70
    }
71
72
    @Override
73
    public int[] getRequiredTokens() {
74 1 1. getRequiredTokens : mutated return of Object value for com/puppycrawl/tools/checkstyle/checks/coding/MultipleVariableDeclarationsCheck::getRequiredTokens to ( if (x != null) null else throw new RuntimeException ) → KILLED
        return new int[] {TokenTypes.VARIABLE_DEF};
75
    }
76
77
    @Override
78
    public void visitToken(DetailAST ast) {
79
        DetailAST nextNode = ast.getNextSibling();
80
81 1 1. visitToken : negated conditional → KILLED
        if (nextNode != null) {
82 1 1. visitToken : negated conditional → KILLED
            final boolean isCommaSeparated = nextNode.getType() == TokenTypes.COMMA;
83
84 1 1. visitToken : negated conditional → KILLED
            if (isCommaSeparated
85 1 1. visitToken : negated conditional → KILLED
                || nextNode.getType() == TokenTypes.SEMI) {
86
                nextNode = nextNode.getNextSibling();
87
            }
88
89 1 1. visitToken : negated conditional → KILLED
            if (nextNode != null
90 1 1. visitToken : negated conditional → KILLED
                    && nextNode.getType() == TokenTypes.VARIABLE_DEF) {
91
                final DetailAST firstNode = CheckUtils.getFirstNode(ast);
92 1 1. visitToken : negated conditional → KILLED
                if (isCommaSeparated) {
93
                    // Check if the multiple variable declarations are in a
94
                    // for loop initializer. If they are, then no warning
95
                    // should be displayed. Declaring multiple variables in
96
                    // a for loop initializer is a good way to minimize
97
                    // variable scope. Refer Feature Request Id - 2895985
98
                    // for more details
99 1 1. visitToken : negated conditional → KILLED
                    if (ast.getParent().getType() != TokenTypes.FOR_INIT) {
100 1 1. visitToken : removed call to com/puppycrawl/tools/checkstyle/checks/coding/MultipleVariableDeclarationsCheck::log → KILLED
                        log(firstNode, MSG_MULTIPLE_COMMA);
101
                    }
102
                }
103
                else {
104
                    final DetailAST lastNode = getLastNode(ast);
105
                    final DetailAST firstNextNode = CheckUtils.getFirstNode(nextNode);
106
107 1 1. visitToken : negated conditional → KILLED
                    if (firstNextNode.getLineNo() == lastNode.getLineNo()) {
108 1 1. visitToken : removed call to com/puppycrawl/tools/checkstyle/checks/coding/MultipleVariableDeclarationsCheck::log → KILLED
                        log(firstNode, MSG_MULTIPLE);
109
                    }
110
                }
111
            }
112
        }
113
    }
114
115
    /**
116
     * Finds sub-node for given node maximum (line, column) pair.
117
     * @param node the root of tree for search.
118
     * @return sub-node with maximum (line, column) pair.
119
     */
120
    private static DetailAST getLastNode(final DetailAST node) {
121
        DetailAST currentNode = node;
122
        DetailAST child = node.getFirstChild();
123 1 1. getLastNode : negated conditional → KILLED
        while (child != null) {
124
            final DetailAST newNode = getLastNode(child);
125 2 1. getLastNode : changed conditional boundary → SURVIVED
2. getLastNode : negated conditional → KILLED
            if (newNode.getLineNo() > currentNode.getLineNo()
126 1 1. getLastNode : negated conditional → SURVIVED
                || newNode.getLineNo() == currentNode.getLineNo()
127 2 1. getLastNode : changed conditional boundary → SURVIVED
2. getLastNode : negated conditional → SURVIVED
                    && newNode.getColumnNo() > currentNode.getColumnNo()) {
128
                currentNode = newNode;
129
            }
130
            child = child.getNextSibling();
131
        }
132
133 1 1. getLastNode : mutated return of Object value for com/puppycrawl/tools/checkstyle/checks/coding/MultipleVariableDeclarationsCheck::getLastNode to ( if (x != null) null else throw new RuntimeException ) → KILLED
        return currentNode;
134
    }
135
136
}

Mutations

64

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

69

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

74

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

81

1.1
Location : visitToken
Killed by : com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest.testIt(com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest)
negated conditional → KILLED

82

1.1
Location : visitToken
Killed by : com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest.testIt(com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest)
negated conditional → KILLED

84

1.1
Location : visitToken
Killed by : com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest.testIt(com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest)
negated conditional → KILLED

85

1.1
Location : visitToken
Killed by : com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest.testIt(com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest)
negated conditional → KILLED

89

1.1
Location : visitToken
Killed by : com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest.testIt(com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest)
negated conditional → KILLED

90

1.1
Location : visitToken
Killed by : com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest.testIt(com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest)
negated conditional → KILLED

92

1.1
Location : visitToken
Killed by : com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest.testIt(com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest)
negated conditional → KILLED

99

1.1
Location : visitToken
Killed by : com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest.testIt(com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest)
negated conditional → KILLED

100

1.1
Location : visitToken
Killed by : com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest.testIt(com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest)
removed call to com/puppycrawl/tools/checkstyle/checks/coding/MultipleVariableDeclarationsCheck::log → KILLED

107

1.1
Location : visitToken
Killed by : com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest.testIt(com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest)
negated conditional → KILLED

108

1.1
Location : visitToken
Killed by : com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest.testIt(com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest)
removed call to com/puppycrawl/tools/checkstyle/checks/coding/MultipleVariableDeclarationsCheck::log → KILLED

123

1.1
Location : getLastNode
Killed by : com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest.testIt(com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest)
negated conditional → KILLED

125

1.1
Location : getLastNode
Killed by : none
changed conditional boundary → SURVIVED

2.2
Location : getLastNode
Killed by : com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest.testIt(com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest)
negated conditional → KILLED

126

1.1
Location : getLastNode
Killed by : none
negated conditional → SURVIVED

127

1.1
Location : getLastNode
Killed by : none
changed conditional boundary → SURVIVED

2.2
Location : getLastNode
Killed by : none
negated conditional → SURVIVED

133

1.1
Location : getLastNode
Killed by : com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest.testIt(com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheckTest)
mutated return of Object value for com/puppycrawl/tools/checkstyle/checks/coding/MultipleVariableDeclarationsCheck::getLastNode to ( if (x != null) null else throw new RuntimeException ) → KILLED

Active mutators

Tests examined


Report generated by PIT 1.3.1