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

pmd / pmd / 558

28 May 2026 07:27AM UTC coverage: 79.05% (+0.001%) from 79.049%
558

push

github

adangel
[java] UnnecessaryBooleanAssertion: Use InvocationMatcher to find assertions (#6712)

18977 of 24933 branches covered (76.11%)

Branch coverage included in aggregate %.

5 of 5 new or added lines in 1 file covered. (100.0%)

11 existing lines in 4 files now uncovered.

41273 of 51285 relevant lines covered (80.48%)

0.81 hits per line

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

91.8
/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/CyclomaticComplexityRule.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.rule.design;
6

7
import static net.sourceforge.pmd.properties.NumericConstraints.positive;
8

9
import java.util.List;
10

11
import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration;
12
import net.sourceforge.pmd.lang.java.ast.ASTExecutableDeclaration;
13
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
14
import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration;
15
import net.sourceforge.pmd.lang.java.ast.JavaNode;
16
import net.sourceforge.pmd.lang.java.ast.internal.PrettyPrintingUtil;
17
import net.sourceforge.pmd.lang.java.metrics.JavaMetrics;
18
import net.sourceforge.pmd.lang.java.metrics.JavaMetrics.CycloOption;
19
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule;
20
import net.sourceforge.pmd.lang.metrics.MetricOptions;
21
import net.sourceforge.pmd.lang.metrics.MetricsUtil;
22
import net.sourceforge.pmd.properties.PropertyDescriptor;
23
import net.sourceforge.pmd.properties.PropertyFactory;
24
import net.sourceforge.pmd.reporting.RuleContext;
25

26

27
/**
28
 * Cyclomatic complexity rule using metrics.
29
 *
30
 * @author Clément Fournier, based on work by Alan Hohn and Donald A. Leckie
31
 * @version 6.0.0
32
 */
33
public class CyclomaticComplexityRule extends AbstractJavaRulechainRule {
34

35
    private static final PropertyDescriptor<Integer> CLASS_LEVEL_DESCRIPTOR
1✔
36
        = PropertyFactory.intProperty("classReportLevel")
1✔
37
                         .desc("Total class complexity reporting threshold")
1✔
38
                         .require(positive()).defaultValue(80).build();
1✔
39

40
    private static final PropertyDescriptor<Integer> METHOD_LEVEL_DESCRIPTOR
1✔
41
        = PropertyFactory.intProperty("methodReportLevel")
1✔
42
                         .desc("Cyclomatic complexity reporting threshold")
1✔
43
                         .require(positive()).defaultValue(10).build();
1✔
44

45
    private static final PropertyDescriptor<List<CycloOption>> CYCLO_OPTIONS_DESCRIPTOR
1✔
46
            = PropertyFactory.conventionalEnumListProperty("cycloOptions", CycloOption.class)
1✔
47
                             .desc("Choose options for the computation of Cyclo")
1✔
48
                             .emptyDefaultValue()
1✔
49
                             .build();
1✔
50

51

52
    public CyclomaticComplexityRule() {
53
        super(ASTExecutableDeclaration.class, ASTTypeDeclaration.class);
1✔
54
        definePropertyDescriptor(CLASS_LEVEL_DESCRIPTOR);
1✔
55
        definePropertyDescriptor(METHOD_LEVEL_DESCRIPTOR);
1✔
56
        definePropertyDescriptor(CYCLO_OPTIONS_DESCRIPTOR);
1✔
57
    }
1✔
58

59

60
    @Override
61
    public Object visitJavaNode(JavaNode node, Object param) {
62
        if (node instanceof ASTTypeDeclaration) {
1!
63
            ASTTypeDeclaration typeDeclaration = (ASTTypeDeclaration) node;
1✔
64
            RuleContext ctx = (RuleContext) param;
1✔
65

66
            visitTypeDecl(typeDeclaration, ctx);
1✔
67
        }
68
        return null;
1✔
69
    }
70

71
    /**
72
     * @deprecated since 7.25.0. This method should have never been public.
73
     */
74
    @Deprecated
75
    public Object visitTypeDecl(ASTTypeDeclaration node, Object data) {
UNCOV
76
        RuleContext ctx = (RuleContext) data;
×
77

UNCOV
78
        visitTypeDecl(node, ctx);
×
79

UNCOV
80
        return null;
×
81

82
    }
83

84
    private void visitTypeDecl(ASTTypeDeclaration node, RuleContext ctx) {
85
        MetricOptions cycloOptions = MetricOptions.ofOptions(getProperty(CYCLO_OPTIONS_DESCRIPTOR));
1✔
86

87
        if (JavaMetrics.WEIGHED_METHOD_COUNT.supports(node)) {
1✔
88
            int classWmc = MetricsUtil.computeMetric(JavaMetrics.WEIGHED_METHOD_COUNT, node, cycloOptions);
1✔
89

90
            if (classWmc >= getProperty(CLASS_LEVEL_DESCRIPTOR)) {
1✔
91
                int classHighest = (int) MetricsUtil.computeStatistics(JavaMetrics.CYCLO, node.getOperations(), cycloOptions).getMax();
1✔
92

93
                String[] messageParams = {PrettyPrintingUtil.getPrintableNodeKind(node),
1✔
94
                                          node.getSimpleName(),
1✔
95
                                          " total",
96
                                          classWmc + " (highest " + classHighest + ")", };
97

98
                ctx.addViolation(node, (Object[]) messageParams);
1✔
99
            }
100
        }
101
    }
1✔
102

103

104
    @Override
105
    public final Object visit(ASTMethodDeclaration node, Object data) {
106
        RuleContext ctx = (RuleContext) data;
1✔
107

108
        visitMethodLike(node, ctx);
1✔
109

110
        return null;
1✔
111
    }
112

113
    @Override
114
    public final Object visit(ASTConstructorDeclaration node, Object data) {
115
        RuleContext ctx = (RuleContext) data;
1✔
116

117
        visitMethodLike(node, ctx);
1✔
118

119
        return null;
1✔
120
    }
121

122
    private void visitMethodLike(ASTExecutableDeclaration node, RuleContext ctx) {
123
        MetricOptions cycloOptions = MetricOptions.ofOptions(getProperty(CYCLO_OPTIONS_DESCRIPTOR));
1✔
124

125
        if (JavaMetrics.CYCLO.supports(node)) {
1!
126
            int cyclo = MetricsUtil.computeMetric(JavaMetrics.CYCLO, node, cycloOptions);
1✔
127
            if (cyclo >= getProperty(METHOD_LEVEL_DESCRIPTOR)) {
1✔
128

129

130
                String opname = PrettyPrintingUtil.displaySignature(node);
1✔
131

132
                String kindname = node instanceof ASTConstructorDeclaration ? "constructor" : "method";
1✔
133

134
                ctx.addViolation(node, kindname, opname, "", "" + cyclo);
1✔
135
            }
136
        }
137
    }
1✔
138

139
}
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