avoid-recursive-calls

Path
lint/correctness/avoid-recursive-calls
Default
Off, opt in
Origin
Falcon
Rule
118 of 512

Reports direct self-calls in functions and methods, including guarded recursion.

Local declaration identities exclude shadowed call targets. Calls on another receiver, getters, extension dispatch, and calls inside anonymous closures are deliberately excluded rather than guessed to be recursive.

Invalid

example.dartdart
int forever() => forever();
int recursive(int n) { return recursive(n - 1); }
void again() { again(); }
class Broken {
  int run() => this.run();
  static int staticRun() => staticRun();
}
void outer() {
  int local() => local();
  print(local);
}
int bounded(int n) => n <= 0 ? 0 : bounded(n - 1);
int guarded(int n) { if (n <= 0) return 0; return guarded(n - 1); }
Iterable<int> sequence() sync* { yield* sequence(); }
Future<void> asyncAgain() async => asyncAgain();
Avoid calling the same function recursively; consider an iterative implementation.
1int forever() => forever();
Avoid calling the same function recursively; consider an iterative implementation.
1int forever() => forever();
2int recursive(int n) { return recursive(n - 1); }
Avoid calling the same function recursively; consider an iterative implementation.
2int recursive(int n) { return recursive(n - 1); }
3void again() { again(); }
Avoid calling the same function recursively; consider an iterative implementation.
4class Broken {
5 int run() => this.run();
Avoid calling the same function recursively; consider an iterative implementation.
5 int run() => this.run();
6 static int staticRun() => staticRun();
Avoid calling the same function recursively; consider an iterative implementation.
8void outer() {
9 int local() => local();
Avoid calling the same function recursively; consider an iterative implementation.
11}
12int bounded(int n) => n <= 0 ? 0 : bounded(n - 1);
Avoid calling the same function recursively; consider an iterative implementation.
12int bounded(int n) => n <= 0 ? 0 : bounded(n - 1);
13int guarded(int n) { if (n <= 0) return 0; return guarded(n - 1); }
Avoid calling the same function recursively; consider an iterative implementation.
13int guarded(int n) { if (n <= 0) return 0; return guarded(n - 1); }
14Iterable<int> sequence() sync* { yield* sequence(); }
Avoid calling the same function recursively; consider an iterative implementation.
14Iterable<int> sequence() sync* { yield* sequence(); }
15Future<void> asyncAgain() async => asyncAgain();

Valid

example.dartdart
int delegates(int Function() delegates) => delegates();
int other() => 1;
int wrapper() => other();
class Valid {
  Valid? next;
  int run() => next!.run();
  int shadow(int Function() shadow) => shadow();
  int get recursiveGetter => recursiveGetter; // Covered by recursive-getters.
}
void nested() { void closure() { print('not recursive'); } closure(); }
int iterative(int n) { var result = 0; while (n > 0) { result += n; n--; } return result; }
void shadowed() {
  final shadowed = () => 1;
  print(shadowed());
}
void captured() { final callback = () => captured(); print(callback); }

Configure avoid-recursive-calls

Set its severity in falcon.json. See the configuration guide.

falcon.jsonjson
{
  "linter": {
    "rules": {
      "correctness": {
        "avoid-recursive-calls": "error"
      }
    }
  }
}

Or silence one occurrence with a suppression comment; the reason is required.

example.dartdart
// falcon-ignore lint/correctness/avoid-recursive-calls: <reason>