prefer-is-not-empty

Same as prefer_is_not_empty in Dart lints

Group
Style
Path
lint/style/prefer-is-not-empty
Default
On (recommended)
Origin
Dart lints
Rule
377 of 512
recommended

Flags .length comparisons equivalent to a .isNotEmpty check.

Collections and strings expose an isNotEmpty getter that reads as plain intent and, for lazy iterables, can avoid computing the full length. Comparing length against a constant makes the reader infer the meaning, so list.isNotEmpty should replace forms such as length != 0, length > 0, and length >= 1, along with their operand-swapped mirrors (0 != length, 0 < length, 1 <= length).

Only a plain .length property access matches against the relevant integer literal. A null-aware receiver?.length is deliberately left alone: that comparison also has to account for a null receiver, so isNotEmpty is not a drop-in replacement.

Semantic analysis requires declaration identities. Once available, an unknown receiver still triggers the lint. A TypeIndex can suppress it only when the receiver is proven to have no isNotEmpty member and not to be an Iterable, String, or Map; source-resolved members and subtypes take precedence. Without a type index, those negative proofs are unavailable, but source-derived receiver types are still inferred.

Invalid

example.dartdart
void bad() {
  if (list.length != 0) return;
  if (0 != items.length) return;
  if (str.length > 0) return;
  if (0 < map.length) return;
  if (set.length >= 1) return;
  if (1 <= names.length) return;
}

// A class implementing a core collection still inherits `isNotEmpty` (from
// Iterable), so the suggestion is valid and the diagnostic keeps firing.
class Bag implements Iterable<int> {
  int get length => 0;
}

// A class whose supertype chain leaves the project is `Unknown`, never
// `ProvenAbsent` — an unresolved ancestor could contribute `isNotEmpty` — so the
// diagnostic keeps firing (type knowledge suppresses only on positive proof).
class Offsite extends Frobnicator {
  int get length => 0;
}

void typedReceivers(Bag b, Offsite o) {
  if (b.length != 0) return;
  if (o.length != 0) return;
}
Use `isNotEmpty` instead of comparing `length` to 0.
1void bad() {
2 if (list.length != 0) return;
Use `isNotEmpty` instead of comparing `length` to 0.
2 if (list.length != 0) return;
3 if (0 != items.length) return;
Use `isNotEmpty` instead of comparing `length` to 0.
3 if (0 != items.length) return;
4 if (str.length > 0) return;
Use `isNotEmpty` instead of comparing `length` to 0.
4 if (str.length > 0) return;
5 if (0 < map.length) return;
Use `isNotEmpty` instead of comparing `length` to 0.
5 if (0 < map.length) return;
6 if (set.length >= 1) return;
Use `isNotEmpty` instead of comparing `length` to 0.
6 if (set.length >= 1) return;
7 if (1 <= names.length) return;
Use `isNotEmpty` instead of comparing `length` to 0.
23void typedReceivers(Bag b, Offsite o) {
24 if (b.length != 0) return;
Use `isNotEmpty` instead of comparing `length` to 0.
24 if (b.length != 0) return;
25 if (o.length != 0) return;

Valid

example.dartdart
void good() {
  if (list.isNotEmpty) return;
  if (items.length == 0) return;
  if (str.length < 1) return;
  if (map.length == 3) return;
  if (set.length > 5) return;
  if (count != 0) return;
}

// A user class with only a `length` getter — no `isNotEmpty`, and not a core
// collection/string. Its receiver type is positively proven, so `length != 0`
// is SUPPRESSED: suggesting `isNotEmpty` would reference a member it lacks.
// (Requires the corpus harness to attach a TypeIndex for this rule; without one
// the receiver is Unknown and this line would fire.)
class Ruler {
  int get length => 3;
}

void suppressed(Ruler r) {
  if (r.length != 0) return;
}

Configure prefer-is-not-empty

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

falcon.jsonjson
{
  "linter": {
    "rules": {
      "style": {
        "prefer-is-not-empty": "error"
      }
    }
  }
}

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

example.dartdart
// falcon-ignore lint/style/prefer-is-not-empty: <reason>
  • prefer-is-not-operatorprefer_is_not_operatorrecommended

    Flags a negated type test !(x is T) that should use the is! operator.

  • prefer-iterable-ofprefer-iterable-ofrecommended

    Flags .from collection constructors in favor of the .of constructor.

  • prefer-iterable-where-typeprefer_iterable_whereTyperecommended

    Flags .where((e) => e is T), which .whereType<T>() expresses directly.

  • prefer-lastprefer-last

    Flags manual last-element indexing in favor of the .last getter.

  • prefer-match-file-name

    Match a file's sole class or enum name to its snake-case basename.

  • prefer-mixinprefer_mixinrecommended

    Flags with clauses that mix in a plain class instead of a mixin.

  • prefer-multi-bloc-providerbloc

    Flatten directly nested package:flutter_bloc BlocProviders with MultiBlocProvider.

  • prefer-multi-providerprovider

    Prefer a flat MultiProvider to directly nested provider widgets.