Complexity Density measures how much decision-making is packed into each line of code. It’s the ratio of a method’s cyclomatic complexity to its length in lines.
A method with complexity 10 in 100 lines (density 0.10) is long but straightforward. A method with complexity 5 in 10 lines (density 0.50) is short but extremely dense — every line is a decision.
For each concrete method, we compute density = (1 + total_branches) / body_lines. Branches include if, elseif, case, catch, and loops (for, foreach, while, do-while). If the density exceeds the threshold (default 0.30), the method’s logic is too tightly packed.
Short but impossible to follow — every line branches.
public function resolve($a, $b, $c): int
{
if ($a) { if ($b) { return 1; } else { if ($c) { return 2; } } }
if ($a && $b || $c) { return 3; }
if (!$a) { return 4; }
return 0;
}
Same logic, but spread out so each branch has room to breathe.
public function resolve($a, $b, $c): int
{
if ($a && $b) {
return 1;
}
if ($a && $c) {
return 2;
}
if ($a || $c) {
return 3;
}
if (!$a) {
return 4;
}
return 0;
}
rules:
E0030:
max_density: 0.3
If Phanalist flags a method for high complexity density, your code is too clever per line. Don’t try to write the shortest code — write the most readable code. Spread branches across lines and use early returns.