code complexity & repetition analysis tool
at main 197 lines 4.0 kB view raw view rendered
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)