• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pmd / pmd / 19

29 May 2025 04:22PM UTC coverage: 77.723% (-0.03%) from 77.757%
19

push

github

adangel
Fix #5621: [java] Fix FPs with UnusedPrivateMethod (#5727)

Merge pull request #5727 from oowekyala:issue5621-unusedprivatemethod

17705 of 23734 branches covered (74.6%)

Branch coverage included in aggregate %.

50 of 52 new or added lines in 9 files covered. (96.15%)

81 existing lines in 6 files now uncovered.

38845 of 49024 relevant lines covered (79.24%)

0.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/internal/NpathBaseVisitor.java
1
/*
2
 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3
 */
4

5
package net.sourceforge.pmd.lang.java.metrics.internal;
6

7
import java.math.BigInteger;
8

9
import net.sourceforge.pmd.lang.ast.NodeStream;
10
import net.sourceforge.pmd.lang.java.ast.ASTConditionalExpression;
11
import net.sourceforge.pmd.lang.java.ast.ASTDoStatement;
12
import net.sourceforge.pmd.lang.java.ast.ASTExecutableDeclaration;
13
import net.sourceforge.pmd.lang.java.ast.ASTExpression;
14
import net.sourceforge.pmd.lang.java.ast.ASTForStatement;
15
import net.sourceforge.pmd.lang.java.ast.ASTForeachStatement;
16
import net.sourceforge.pmd.lang.java.ast.ASTIfStatement;
17
import net.sourceforge.pmd.lang.java.ast.ASTReturnStatement;
18
import net.sourceforge.pmd.lang.java.ast.ASTStatement;
19
import net.sourceforge.pmd.lang.java.ast.ASTSwitchArrowBranch;
20
import net.sourceforge.pmd.lang.java.ast.ASTSwitchBranch;
21
import net.sourceforge.pmd.lang.java.ast.ASTSwitchExpression;
22
import net.sourceforge.pmd.lang.java.ast.ASTSwitchFallthroughBranch;
23
import net.sourceforge.pmd.lang.java.ast.ASTSwitchLabel;
24
import net.sourceforge.pmd.lang.java.ast.ASTSwitchLike;
25
import net.sourceforge.pmd.lang.java.ast.ASTSwitchStatement;
26
import net.sourceforge.pmd.lang.java.ast.ASTTryStatement;
27
import net.sourceforge.pmd.lang.java.ast.ASTWhileStatement;
28
import net.sourceforge.pmd.lang.java.ast.JavaNode;
29
import net.sourceforge.pmd.lang.java.ast.JavaVisitorBase;
30
import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils;
31

32

33
/**
34
 * Visitor for the default n-path complexity version.
35
 *
36
 * @author Clément Fournier
37
 * @author Jason Bennett
38
 * @deprecated Since 7.14.0. Has been replaced by {@link NPathMetricCalculator}
39
 */
40
@Deprecated
UNCOV
41
public class NpathBaseVisitor extends JavaVisitorBase<Void, BigInteger> {
×
42

43
    /** Instance. */
UNCOV
44
    public static final NpathBaseVisitor INSTANCE = new NpathBaseVisitor();
×
45

46

47
    /* Multiplies the complexity of the children of this node. */
48
    private BigInteger multiplyChildrenComplexities(JavaNode node) {
UNCOV
49
        return multiplyComplexities(node.children());
×
50
    }
51

52
    private BigInteger multiplyComplexities(NodeStream<? extends JavaNode> nodes) {
UNCOV
53
        return nodes.reduce(BigInteger.ONE, (acc, n) -> acc.multiply(n.acceptVisitor(this, null)));
×
54
    }
55

56

57
    /* Sums the complexity of the children of the node. */
58
    private BigInteger sumChildrenComplexities(JavaNode node, Void data) {
UNCOV
59
        BigInteger sum = BigInteger.ZERO;
×
60

UNCOV
61
        for (JavaNode child : node.children()) {
×
UNCOV
62
            BigInteger childComplexity = child.acceptVisitor(this, data);
×
UNCOV
63
            sum = sum.add(childComplexity);
×
UNCOV
64
        }
×
65

UNCOV
66
        return sum;
×
67
    }
68

69

70
    @Override
71
    public BigInteger visitMethodOrCtor(ASTExecutableDeclaration node, Void data) {
UNCOV
72
        return multiplyChildrenComplexities(node);
×
73
    }
74

75

76
    @Override
77
    public BigInteger visitJavaNode(JavaNode node, Void data) {
UNCOV
78
        return multiplyChildrenComplexities(node);
×
79
    }
80

81

82
    @Override
83
    public BigInteger visit(ASTIfStatement node, Void data) {
84
        // (npath of if + npath of else (or 1) + bool_comp of if) * npath of next
85

UNCOV
86
        int boolCompIf = CycloVisitor.booleanExpressionComplexity(node.getCondition());
×
87

UNCOV
88
        BigInteger thenResult = node.getThenBranch().acceptVisitor(this, data);
×
UNCOV
89
        ASTStatement elseBranch = node.getElseBranch();
×
UNCOV
90
        BigInteger elseResult = elseBranch != null ? elseBranch.acceptVisitor(this, data) : BigInteger.ONE;
×
91

UNCOV
92
        return thenResult.add(BigInteger.valueOf(boolCompIf)).add(elseResult);
×
93
    }
94

95

96
    @Override
97
    public BigInteger visit(ASTWhileStatement node, Void data) {
98
        // (npath of while + bool_comp of while + 1) * npath of next
99

UNCOV
100
        int boolComp = CycloVisitor.booleanExpressionComplexity(node.getCondition());
×
UNCOV
101
        BigInteger nPathBody = node.getBody().acceptVisitor(this, data);
×
UNCOV
102
        return nPathBody.add(BigInteger.valueOf(boolComp + 1));
×
103
    }
104

105

106
    @Override
107
    public BigInteger visit(ASTDoStatement node, Void data) {
108
        // (npath of do + bool_comp of do + 1) * npath of next
109

UNCOV
110
        int boolComp = CycloVisitor.booleanExpressionComplexity(node.getCondition());
×
UNCOV
111
        BigInteger nPathBody = node.getBody().acceptVisitor(this, data);
×
UNCOV
112
        return nPathBody.add(BigInteger.valueOf(boolComp + 1));
×
113
    }
114

115

116
    @Override
117
    public BigInteger visit(ASTForStatement node, Void data) {
118
        // (npath of for + bool_comp of for + 1) * npath of next
119

UNCOV
120
        int boolComp = CycloVisitor.booleanExpressionComplexity(node.getCondition());
×
UNCOV
121
        BigInteger nPathBody = node.getBody().acceptVisitor(this, data);
×
UNCOV
122
        return nPathBody.add(BigInteger.valueOf(boolComp + 1));
×
123
    }
124

125
    @Override
126
    public BigInteger visit(ASTForeachStatement node, Void data) {
127
        // (npath of for + 1) * npath of next
128

UNCOV
129
        BigInteger nPathBody = node.getBody().acceptVisitor(this, data);
×
UNCOV
130
        return nPathBody.add(BigInteger.ONE);
×
131
    }
132

133

134
    @Override
135
    public BigInteger visit(ASTReturnStatement node, Void data) {
136
        // return statements are valued at 1, or the value of the boolean expression
137

UNCOV
138
        ASTExpression expr = node.getExpr();
×
139

UNCOV
140
        if (expr == null) {
×
UNCOV
141
            return BigInteger.ONE;
×
142
        }
143

UNCOV
144
        int boolCompReturn = CycloVisitor.booleanExpressionComplexity(expr);
×
UNCOV
145
        BigInteger conditionalExpressionComplexity = multiplyChildrenComplexities(expr);
×
146

UNCOV
147
        return conditionalExpressionComplexity.add(BigInteger.valueOf(boolCompReturn));
×
148
    }
149

150

151
    @Override
152
    public BigInteger visit(ASTSwitchExpression node, Void data) {
UNCOV
153
        return handleSwitch(node, data);
×
154
    }
155

156
    @Override
157
    public BigInteger visit(ASTSwitchStatement node, Void data) {
UNCOV
158
        return handleSwitch(node, data);
×
159
    }
160

161
    public BigInteger handleSwitch(ASTSwitchLike node, Void data) {
162
        // bool_comp of switch + sum(npath(case_range))
163

UNCOV
164
        int boolCompSwitch = CycloVisitor.booleanExpressionComplexity(node.getTestedExpression());
×
165

UNCOV
166
        BigInteger npath = BigInteger.ZERO;
×
UNCOV
167
        int caseRange = 0;
×
168

UNCOV
169
        for (ASTSwitchBranch n : node) {
×
170

171
            // Fall-through labels count as 1 for complexity
UNCOV
172
            if (n instanceof ASTSwitchFallthroughBranch) {
×
UNCOV
173
                caseRange += JavaAstUtils.numAlternatives(n);
×
UNCOV
174
                NodeStream<ASTStatement> statements = ((ASTSwitchFallthroughBranch) n).getStatements();
×
UNCOV
175
                if (statements.nonEmpty()) {
×
UNCOV
176
                    BigInteger branchNpath = multiplyComplexities(statements);
×
UNCOV
177
                    npath = npath.add(branchNpath.multiply(BigInteger.valueOf(caseRange)));
×
UNCOV
178
                    caseRange = 0;
×
179
                }
UNCOV
180
            } else if (n instanceof ASTSwitchArrowBranch) {
×
UNCOV
181
                int numAlts = JavaAstUtils.numAlternatives(n);
×
UNCOV
182
                BigInteger branchNpath = ((ASTSwitchArrowBranch) n).getRightHandSide().acceptVisitor(this, data);
×
UNCOV
183
                npath = npath.add(branchNpath.multiply(BigInteger.valueOf(numAlts)));
×
184
            }
UNCOV
185
        }
×
186
        // add in npath of last label
UNCOV
187
        return npath.add(BigInteger.valueOf(boolCompSwitch));
×
188
    }
189

190
    @Override
191
    public BigInteger visit(ASTSwitchLabel node, Void data) {
UNCOV
192
        if (node.isDefault()) {
×
UNCOV
193
            return BigInteger.ONE;
×
194
        }
UNCOV
195
        return BigInteger.valueOf(node.children(ASTExpression.class).count());
×
196
    }
197

198
    @Override
199
    public BigInteger visit(ASTConditionalExpression node, Void data) {
200
        // bool comp of guard clause + complexity of last two children (= total - 1)
201

UNCOV
202
        int boolCompTernary = CycloVisitor.booleanExpressionComplexity(node.getCondition());
×
203

UNCOV
204
        return sumChildrenComplexities(node, data).add(BigInteger.valueOf(boolCompTernary - 1));
×
205
    }
206

207

208
    @Override
209
    public BigInteger visit(ASTTryStatement node, Void data) {
210
        /*
211
         * This scenario was not addressed by the original paper. Based on the
212
         * principles outlined in the paper, as well as the Checkstyle NPath
213
         * implementation, this code will add the complexity of the try to the
214
         * complexities of the catch and finally blocks.
215
         */
UNCOV
216
        return sumChildrenComplexities(node, data);
×
217
    }
218
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc