Rules / Complexity / cyclomatic-complexity
cyclomatic-complexity
Flags a function whose cyclomatic complexity exceeds the configured threshold.
Cyclomatic complexity counts the independent paths through a function; a high
value means many branches to understand and test. The rule computes
complexity as one plus each decision point — if, ternary, &&, ||, ??,
loops (for/while/do), catch clauses, non-default cases, and pattern
when guards — counted across the whole body tree, so decision points inside
nested closures and local functions count toward the enclosing function. It
reports at the function name when the total exceeds the threshold.
Options
max_complexity (integer, default: 20) — flag when the computed complexity
exceeds this.
Invalid
example.dartdart
// Each function below exceeds the configured max_complexity of 3.
// Complexity = 1 + decision points (if / && / || / ?? / for / while / case / catch / ternary).
int classifyNumber(int a, int b) {
if (a > 0) return 1;
if (b > 0) return 2;
if (a > b && b > 0) return 3;
return 0;
}
int loopScan(List<int> xs, int limit) {
var total = 0;
for (final x in xs) total += x;
while (total > limit) total -= 1;
final capped = total > 0 || limit < 0;
final safe = total ?? limit;
return capped ? safe : 0;
}
int nestedTernary(int a, int b, int c) {
final first = a > 0 ? 1 : (b > 0 ? 2 : 3);
final second = c > 0 && a > 0 ? 4 : 5;
return first + second;
}
String describe(int code) {
switch (code) {
case 1:
return 'one';
case 2:
return 'two';
case 3:
return 'three';
default:
return 'other';
}
}
int guarded(Object value) {
try {
if (value == null) return -1;
} on FormatException {
return -2;
} on StateError {
return -3;
}
return value.hashCode > 0 && value.hashCode < 100 ? 1 : 0;
}
class Calculator {
int compute(int a, int b) {
if (a > b) return a - b;
if (a < b) return b - a;
if (a == 0 || b == 0) return 0;
return a + b;
}
}
Function has a cyclomatic complexity of 5 (max 3).
3
4int classifyNumber(int a, int b) {
∙
Function has a cyclomatic complexity of 6 (max 3).
10
11int loopScan(List<int> xs, int limit) {
∙
Function has a cyclomatic complexity of 5 (max 3).
19
20int nestedTernary(int a, int b, int c) {
∙
Function has a cyclomatic complexity of 4 (max 3).
25
26String describe(int code) {
∙
Function has a cyclomatic complexity of 6 (max 3).
38
39int guarded(Object value) {
∙
Function has a cyclomatic complexity of 5 (max 3).
50class Calculator {
51 int compute(int a, int b) {
∙
Valid
example.dartdart
// Each function stays at or below a cyclomatic complexity of 3
// (at most two decision points), so none trigger the rule.
int addTwo(int a, int b) {
return a + b;
}
int atMostOne(int a) {
if (a > 0) return a;
return 0;
}
int clamp(int a, int max) {
final over = a > max;
return over ? max : a;
}
int fallback(int? a, int b) {
return a ?? b;
}
int sumList(List<int> xs) {
var total = 0;
for (final x in xs) total += x;
return total;
}
class Counter {
int value = 0;
int increment() {
value += 1;
return value;
}
}
How to configure
Set the severity of cyclomatic-complexity in your falcon.json:
falcon.jsonjson
{
"linter": {
"rules": {
"complexity": {
"cyclomatic-complexity": "error"
}
}
}
}