Cyclomatic Complexity
ID |
swift.cyclomatic_complexity |
Severity |
low |
Remediation Complexity |
medium |
Remediation Risk |
low |
Remediation Effort |
medium |
Resource |
Complexity |
Language |
Swift |
Tags |
complexity |
Description
Reports a function (function, initializer, subscript, computed-property
getter or setter) whose cyclomatic complexity exceeds a configurable
threshold. CCN approximates the number of linearly-independent paths
through the body and is the canonical way to capture nested branching,
long if/else chains, compound boolean conditions, switch arms and deep
loops as a single number.
Rationale
CCN captures, in one number, the structural decisions that drive test
case count, defect density and refactoring difficulty. The metric is
computed structurally from the AST: base 1, plus 1 for each if,
guard, non-default case label, for-in / while / repeat-while
loop, catch clause, ternary expression, and each && / || / ??
operator. Nested closures and nested functions are counted within the
enclosing function — the metric tracks the cognitive load of the body
as written.
Remediation
Extract independent branches into helper functions, replace deeply
nested ternary chains with switch, lift guard ladders out of
loops, or split the function along its decision boundaries.
// Too much for one function — many independent decisions.
func classify(_ x: Int) -> String {
if x > 0 && x < 10 {
switch x {
case 1: return "one"
case 2: return "two"
default: return "small"
}
} else if x > 100 {
for i in 0..<x {
if i % 2 == 0 { ... }
}
}
return "other"
}
// Split into pieces — each has its own, bounded complexity.
func classify(_ x: Int) -> String {
if x > 0 && x < 10 {
return small(x)
}
if x > 100 {
return large(x)
}
return "other"
}