code complexity & repetition analysis tool
1# Cyclomatic Complexity
2
3## What is Cyclomatic Complexity?
4
5Cyclomatic Complexity (CC), introduced by Thomas McCabe in 1976, measures the number of independent paths through a program's source code. It provides a quantitative measure of code complexity.
6
7## How It Works
8
9Mccabre uses a simplified formula:
10
11`CC = (number of decision points) + 1`
12
13### Decision Points
14
15A decision point is any control flow statement that creates a branch:
16
17- `if`, `else if`
18- `while`, `for`, `loop`
19- `switch`, `match`, `case`
20- `catch`
21- Logical operators: `&&`, `||`
22- Ternary operator: `?`
23
24### Example
25
26```javascript
27function checkUser(user) { // CC starts at 1
28 if (!user) { // +1 = 2
29 return false;
30 }
31
32 if (user.age > 18 && user.verified) { // +1 (if) +1 (&&) = 4
33 return true;
34 }
35
36 return false;
37}
38// Total CC = 4
39```
40
41## Interpretation
42
43| CC Range | Risk Level | Recommendation |
44|----------|-----------|----------------|
45| 1-10 | Low | Simple, easy to test |
46| 11-20 | Moderate | Consider refactoring |
47| 21-50 | High | Should refactor |
48| 50+ | Very High | Urgent refactoring needed |
49
50## Why It Matters
51
52### Testing Complexity
53
54Higher CC means:
55
56- More test cases needed for full coverage
57- Higher chance of bugs
58- Harder to understand and maintain
59
60A function with CC=10 requires at least 10 test cases to cover all paths.
61
62### Maintenance Burden
63
64Complex functions are:
65
66- Harder to modify without introducing bugs
67- More difficult for new developers to understand
68- More prone to subtle edge cases
69
70## Reducing Complexity
71
72### Extract Methods
73
74**Before (CC=8):**
75
76```javascript
77function processOrder(order) {
78 if (!order.id) throw new Error("No ID");
79 if (order.status === "cancelled") return null;
80 if (order.items.length === 0) throw new Error("No items");
81
82 let total = 0;
83 for (let item of order.items) {
84 if (item.price && item.quantity) {
85 total += item.price * item.quantity;
86 }
87 }
88
89 return total;
90}
91```
92
93**After (CC=3 + 3 = 6 total):**
94
95```javascript
96function processOrder(order) { // CC=3
97 validateOrder(order);
98 return calculateTotal(order);
99}
100
101function validateOrder(order) { // CC=3
102 if (!order.id) throw new Error("No ID");
103 if (order.status === "cancelled") return null;
104 if (order.items.length === 0) throw new Error("No items");
105}
106
107function calculateTotal(order) { // CC=2
108 let total = 0;
109 for (let item of order.items) {
110 if (item.price && item.quantity) {
111 total += item.price * item.quantity;
112 }
113 }
114 return total;
115}
116```
117
118### Use Early Returns
119
120**Before:**
121
122```rust
123fn check(x: i32) -> bool { // CC=3
124 let mut result = false;
125 if x > 0 {
126 if x < 100 {
127 result = true;
128 }
129 }
130 result
131}
132```
133
134**After:**
135
136```rust
137fn check(x: i32) -> bool { // CC=3 (same but cleaner)
138 if x <= 0 { return false; }
139 if x >= 100 { return false; }
140 true
141}
142```
143
144### Replace Complex Conditions
145
146**Before:**
147
148```javascript
149if ((user.role === "admin" || user.role === "moderator") &&
150 user.active && !user.suspended) { // CC contribution: 4
151 // ...
152}
153```
154
155**After:**
156
157```javascript
158function canModerate(user) { // CC=3
159 const isModerator = user.role === "admin" || user.role === "moderator";
160 return isModerator && user.active && !user.suspended;
161}
162
163if (canModerate(user)) { // CC=1
164 // ...
165}
166```
167
168## Using with Mccabre
169
170### Check Specific Files
171
172```bash
173mccabre complexity src/complex.js
174```
175
176### Set Custom Threshold
177
178```bash
179mccabre complexity . --threshold 15
180```
181
182### JSON Output for CI
183
184```bash
185mccabre complexity . --json | jq '.files[] | select(.cyclomatic.file_complexity > 20)'
186```
187
188## References
189
190- [McCabe (1976): "A Complexity Measure"](https://www.literateprogramming.com/mccabe.pdf)
191- [NIST Special Publication 500-235](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication500-235.pdf)
192
193## See Also
194
195- [Lines of Code](./lines-of-code.md)
196- [Clone Detection](./clone-detection.md)
197- [CLI Reference](./cli-reference.md)