Nested Switch Statement
ID |
swift.no_nested_switch |
Severity |
high |
Remediation Complexity |
medium |
Remediation Risk |
low |
Remediation Effort |
medium |
Resource |
Code Smell |
Language |
Swift |
Tags |
code-style, control-flow, switch |
Description
Reports a switch written inside another switch, at any nesting depth. Both Swift switch forms
are matched — the statement and the Swift 5.9 switch expression — and either form nested in
either form is reported. The inner switch is what gets reported: it is the one to pull out into its
own function.
Rationale
A nested switch forces the reader to track two independent subject values and two sets of case
patterns at once, and an inner break or fallthrough reads as if it might act on the outer
switch. The code still runs exactly as written; the cost is entirely in how hard it is to follow,
and in how easily a case of the inner switch gets read as a case of the outer one.
switch region {
case .north:
switch tier { // two subjects to track at once
case .gold:
applyDiscount()
case .silver:
applyRebate()
}
case .south:
print("south")
}
The trigger is a genuine lexical switch-inside-switch. Nesting is scoped to the enclosing unit of code: a switch inside a closure body, a nested function, an initializer or a type declaration is not reported even when that body sits inside an outer switch case, because such a body is read on its own terms.
Remediation
Move the inner switch into its own function and call it from the case that needs it. Each switch then reads with a single subject in view, and the pattern coverage of each is checked independently.
switch region {
case .north:
applyTierBenefit(tier)
case .south:
print("south")
}
func applyTierBenefit(_ tier: Tier) {
switch tier {
case .gold:
applyDiscount()
case .silver:
applyRebate()
}
}