Rules / Complexity / cyclomatic-complexity

cyclomatic-complexity

lint/complexity/cyclomatic-complexity
recommended
Same as cyclomatic_complexity · Pyramid Lint

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"
      }
    }
  }
}