avoid-nested-conditional-expressions

Same as avoid-nested-conditional-expressions in Dart Code Metrics

Path
lint/complexity/avoid-nested-conditional-expressions
Default
Off, opt in
Origin
Dart Code Metrics
Rule
98 of 512

Flags a ternary conditional expression nested inside another ternary.

Stacked conditionals like a ? b : c ? d : e are hard to read and easy to misparse; an if/else chain, a switch expression, or an extracted variable makes the branching explicit. The rule reports any conditional expression that has another conditional as an ancestor (nesting level two or deeper), matching dart_code_linter's default acceptable level of one. Closure bodies restart the nesting count.

Invalid

example.dartdart
// Each conditional nested inside another conditional is flagged (the inner
// conditional, matching dart_code_linter's nesting-level reporting).

void doubleNesting() {
  final x = a ? (b ? c : d) : e;
  final y = condition ? (isValid ? "yes" : "no") : "default";
  final z = (first ? (second ? 1 : 2) : 3) + 4;
}

// Triple nesting flags both inner conditionals (nesting levels 2 and 3).
String getStatus() {
  return active ? (verified ? (premium ? "premium" : "standard") : "unverified") : "inactive";
}

class StatusHelper {
  String describe(bool a, bool b, bool c) {
    return a ? (b ? (c ? "all" : "a,b") : "a") : "none";
  }
}

int calculate(bool x, bool y) {
  return x ? (y ? (100) : (50)) : (0);
}

List<String> getItems(bool filter) {
  return filter ? (items.isNotEmpty ? (items.toList()) : []) : items;
}

// Regression: the violation must still be found inside Dart 3 containers
// (pattern declaration, labeled statement, switch expression and subject,
// collection if/spread, record field).
void containersRegression(int rcount) {
  final (ra, _) = ((rcount > 0 ? (rcount > 1 ? 1 : 2) : 3), 0);
  lbl: {
    final rb = (rcount > 0 ? (rcount > 1 ? 1 : 2) : 3);
    print(rb);
  }
  final rc = switch (rcount) {
    0 => (rcount > 0 ? (rcount > 1 ? 1 : 2) : 3),
    _ => null,
  };
  final rd = switch ((rcount > 0 ? (rcount > 1 ? 1 : 2) : 3)) {
    _ => 0,
  };
  final re = [if (rcount > 0) (rcount > 0 ? (rcount > 1 ? 1 : 2) : 3)];
  final rf = [...[(rcount > 0 ? (rcount > 1 ? 1 : 2) : 3)]];
  final rg = (p: (rcount > 0 ? (rcount > 1 ? 1 : 2) : 3), q: 0);
  print([ra, rc, rd, re, rf, rg]);
}
Avoid nested conditional expressions.
4void doubleNesting() {
5 final x = a ? (b ? c : d) : e;
Avoid nested conditional expressions.
5 final x = a ? (b ? c : d) : e;
6 final y = condition ? (isValid ? "yes" : "no") : "default";
Avoid nested conditional expressions.
6 final y = condition ? (isValid ? "yes" : "no") : "default";
7 final z = (first ? (second ? 1 : 2) : 3) + 4;
Avoid nested conditional expressions.
11String getStatus() {
12 return active ? (verified ? (premium ? "premium" : "standard") : "unverified") : "inactive";
Avoid nested conditional expressions.
11String getStatus() {
12 return active ? (verified ? (premium ? "premium" : "standard") : "unverified") : "inactive";
Avoid nested conditional expressions.
16 String describe(bool a, bool b, bool c) {
17 return a ? (b ? (c ? "all" : "a,b") : "a") : "none";
Avoid nested conditional expressions.
16 String describe(bool a, bool b, bool c) {
17 return a ? (b ? (c ? "all" : "a,b") : "a") : "none";
Avoid nested conditional expressions.
21int calculate(bool x, bool y) {
22 return x ? (y ? (100) : (50)) : (0);
Avoid nested conditional expressions.
25List<String> getItems(bool filter) {
26 return filter ? (items.isNotEmpty ? (items.toList()) : []) : items;
Avoid nested conditional expressions.
32void containersRegression(int rcount) {
33 final (ra, _) = ((rcount > 0 ? (rcount > 1 ? 1 : 2) : 3), 0);
Avoid nested conditional expressions.
34 lbl: {
35 final rb = (rcount > 0 ? (rcount > 1 ? 1 : 2) : 3);
Avoid nested conditional expressions.
38 final rc = switch (rcount) {
39 0 => (rcount > 0 ? (rcount > 1 ? 1 : 2) : 3),
Avoid nested conditional expressions.
41 };
42 final rd = switch ((rcount > 0 ? (rcount > 1 ? 1 : 2) : 3)) {
Avoid nested conditional expressions.
44 };
45 final re = [if (rcount > 0) (rcount > 0 ? (rcount > 1 ? 1 : 2) : 3)];
Avoid nested conditional expressions.
45 final re = [if (rcount > 0) (rcount > 0 ? (rcount > 1 ? 1 : 2) : 3)];
46 final rf = [...[(rcount > 0 ? (rcount > 1 ? 1 : 2) : 3)]];
Avoid nested conditional expressions.
46 final rf = [...[(rcount > 0 ? (rcount > 1 ? 1 : 2) : 3)]];
47 final rg = (p: (rcount > 0 ? (rcount > 1 ? 1 : 2) : 3), q: 0);

Valid

example.dartdart
// Good cases for avoid-nested-conditional-expressions rule
// No violations expected

void testSingleLevelTernary() {
  final x = a ? b : c;
  final y = condition ? "yes" : "no";
  final z = isValid ? 10 : 20;
}

String getStatus() {
  if (!active) return "inactive";
  if (!verified) return "unverified";
  return premium ? "premium" : "standard";
}

class StatusHelper {
  String describe(bool a, bool b, bool c) {
    if (!a) return "none";
    if (!b) return "a";
    return c ? "all" : "a,b";
  }
}

int calculate(bool x, bool y) {
  if (!x) return 0;
  return y ? 100 : 50;
}

void cleanNesting() {
  if (!condition1) {
    return "none";
  }
  if (!condition2) {
    return "shallow";
  }
  return condition3 ? "deep" : "mid";
}

List<String> getItems(bool filter) {
  if (!filter) return items;
  return items.isNotEmpty ? items : [];
}

void mixedApproach(bool condition) {
  final result = condition ? "active" : "inactive";
  print(result);
}

bool isEligible(bool verified, bool premium) {
  return verified && premium;
}

// A ternary inside a closure body is read on its own, so it is not "nested"
// in the ternary the closure sits in.
List<int> closureInsideConditional(bool flag, List<int> items) {
  return flag ? items.map((x) => x > 0 ? 1 : 0).toList() : const [];
}

Configure avoid-nested-conditional-expressions

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

falcon.jsonjson
{
  "linter": {
    "rules": {
      "complexity": {
        "avoid-nested-conditional-expressions": "error"
      }
    }
  }
}

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

example.dartdart
// falcon-ignore lint/complexity/avoid-nested-conditional-expressions: <reason>