Membership tested by comparing indexOf against 0 or -1

ID

dart.performance.prefer_contains

Severity

info

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Idiom

Language

Dart

Description

Reports a membership test written as a comparison of a single-argument indexOf call against 0 or -1 - indexOf(x) >= 0, != -1, == -1, < 0 and the mirrored operand orders. Calls that pass a start index are left alone, since they are not a plain membership test.

Rationale

indexOf on a List is a linear scan that keeps going in order to compute the position, and the position is then thrown away by the comparison. contains can stop at the first match and, on a Set, Map or any collection with a better lookup, is not a scan at all, so replacing the call can change the cost class of the expression rather than shave a constant. The comparison is also easy to get wrong: > 0 silently misses a match at index zero, and that off-by-one reads as intentional next to the correct >= 0 spellings.

The following code illustrates the pattern detected by this rule:

class Router {
  final List<String> allowedHosts;

  Router(this.allowedHosts);

  bool isAllowed(String host) {
    // FLAGGED: Membership tested by comparing indexOf against 0 or -1
    return allowedHosts.indexOf(host) >= 0;
  }
    }

Remediation

Replace the comparison with contains - hosts.contains(host) for the positive test and !hosts.contains(host) for the negative one. Keep indexOf only where the position itself is used afterwards.

Configuration

This detector does not need any configuration.

© 2026 Xygeni. All rights reserved