Rules / Complexity / no-boolean-literal-compare

no-boolean-literal-compare

lint/complexity/no-boolean-literal-compare
recommended
Same as no-boolean-literal-compare · Dart Code Metrics

Flags a comparison between a boolean value and a boolean literal, e.g. x == true.

Comparing a known boolean to true/false is redundant: x == true is just x, and x == false is !x. The rule flags an ==/!= where one side is a boolean literal and the other is provably a non-nullable boolean — either syntactically (a literal, !, an is check, or a comparison/logical operator) or a local or parameter whose inferred static type is a non-nullable bool. A bool? operand is deliberately left alone, because x == true is the correct null-safe way to test a nullable boolean.

Invalid

example.dartdart
// Test cases for no-boolean-literal-compare.
// Only comparisons whose non-literal operand is PROVABLY boolean are flagged.

void knownBooleanComparisons(bool a, bool b, Object o) {
  if (true == false) {}
  if (!a == true) {}
  if ((a && b) == true) {}
  if ((a || b) != false) {}
  if ((a == b) == true) {}
  if ((o is String) == true) {}
}

// The type-resolution layer widens the check to locals/params whose inferred
// static type is a non-nullable `bool`, not just syntactically-boolean operands.
void resolvedNonNullableBooleans(bool flag) {
  if (flag == true) {}
  bool ready = flag;
  if (ready != false) {}
  final bool done = flag && ready;
  if (done == false) {}
}
Avoid comparing boolean values to boolean literals
4void knownBooleanComparisons(bool a, bool b, Object o) {
5 if (true == false) {}
Avoid comparing boolean values to boolean literals
5 if (true == false) {}
6 if (!a == true) {}
Avoid comparing boolean values to boolean literals
6 if (!a == true) {}
7 if ((a && b) == true) {}
Avoid comparing boolean values to boolean literals
7 if ((a && b) == true) {}
8 if ((a || b) != false) {}
Avoid comparing boolean values to boolean literals
8 if ((a || b) != false) {}
9 if ((a == b) == true) {}
Avoid comparing boolean values to boolean literals
9 if ((a == b) == true) {}
10 if ((o is String) == true) {}
Avoid comparing boolean values to boolean literals
15void resolvedNonNullableBooleans(bool flag) {
16 if (flag == true) {}
Avoid comparing boolean values to boolean literals
17 bool ready = flag;
18 if (ready != false) {}
Avoid comparing boolean values to boolean literals
19 final bool done = flag && ready;
20 if (done == false) {}

Valid

example.dartdart
// Good cases for no-boolean-literal-compare rule
// No violations expected

void testBooleanDirect() {
  if (isValid) {}
  if (!isActive) {}
  if (hasError) {}
  if (!isEmpty) {}
}

void testBooleanNegation() {
  if (!isReady) {}
  if (!isDone) {}
}

void testInWhile() {
  while (isRunning) {}
  while (!shouldContinue) {}
}

bool checkStatus() {
  return isInitialized;
}

void assertConditions() {
  assert(isValid);
  assert(!isDisabled);
}

class Widget {
  bool isEnabled = true;

  void setState() {
    if (isEnabled) {
      activate();
    }
  }

  bool canRender() => isEnabled;
}

void ternaryWithBoolean() {
  final status = isActive ? "on" : "off";
  final result = !isValid ? "error" : "ok";
}

void multipleComparisons() {
  if (flag1 && !flag2) {}
}

void methodCall(bool condition) {
  process(condition);
}

void complexLogic(bool a, bool b, bool c) {
  if (a && (b || !c)) {
    print('condition met');
  }
}

bool canAccess(bool isAuthenticated, bool isAuthorized) {
  return isAuthenticated && isAuthorized;
}

void toggleState(bool current) {
  final newState = !current;
  update(newState);
}

class FeatureFlag {
  bool isEnabled = false;

  void check() {
    if (!isEnabled) {
      enable();
    }
  }
}

// `x == true` / `x != false` on an identifier, member access or call is exempt:
// nullability is unknowable without type resolution, and this is the correct
// null-safe idiom for a `bool?`.
void nullableIdiom(bool? maybe, Widget foo) {
  if (maybe == true) {}
  if (maybe != false) {}
  if (foo.isEnabled == true) {}
  if (checkStatus() == false) {}
}

// A `bool?` local/param resolves to a *nullable* bool, so the resolver leaves
// `== true` alone — it is the idiomatic null-safe form, not a redundant compare.
void resolvedNullableBoolean(bool? maybe) {
  bool? nb = maybe;
  if (nb == true) {}
  if (maybe != false) {}
}

How to configure

Set the severity of no-boolean-literal-compare in your falcon.json:

falcon.jsonjson
{
  "linter": {
    "rules": {
      "complexity": {
        "no-boolean-literal-compare": "error"
      }
    }
  }
}