/** * @name Long switch case * @description A switch statement with too much code in its cases can make the control flow hard to follow. Consider wrapping the code for each case in a function and just using the switch statement to invoke the appropriate function in each case. * @kind problem * @problem.severity recommendation * @precision high * @id cpp/long-switch * @tags maintainability * readability */ import cpp predicate switchCaseStartLine(SwitchCase sc, int start) { sc.getLocation().getStartLine() = start } predicate switchStmtEndLine(SwitchStmt s, int start) { s.getLocation().getEndLine() = start } predicate switchCaseLength(SwitchCase sc, int length) { exists(SwitchCase next, int l1, int l2 | next = sc.getNextSwitchCase() and switchCaseStartLine(next, l1) and switchCaseStartLine(sc, l2) and length = l1 - l2 - 1 ) or not exists(sc.getNextSwitchCase()) and exists(int l1, int l2 | switchStmtEndLine(sc.getSwitchStmt(), l1) and switchCaseStartLine(sc, l2) and length = l1 - l2 - 1 ) } predicate tooLong(SwitchCase sc) { exists(int n | switchCaseLength(sc, n) and n > 30) } from SwitchStmt switch, SwitchCase sc, int lines where sc = switch.getASwitchCase() and tooLong(sc) and switchCaseLength(sc, lines) select switch, "Switch has at least one case that is too long: $@.", sc, sc.getExpr().toString() + " (" + lines.toString() + " lines)"