prefer_any_or_every
v0.1.0 Warning Fix Collection & Type
Flags .where(predicate).isNotEmpty and .where(predicate).isEmpty. Both build a lazy Iterable only to ask a yes/no question that any and every answer directly, stopping at the first decisive element. The quick fix rewrites it.
isNotEmpty after a where is any written out:
class Invoice { const Invoice({required this.isOverdue, required this.isPaid});
final bool isOverdue; final bool isPaid;}
bool hasOverdueInvoice(List<Invoice> invoices) { return invoices.where((invoice) => invoice.isOverdue).isNotEmpty;}class Invoice { const Invoice({required this.isOverdue, required this.isPaid});
final bool isOverdue; final bool isPaid;}
bool hasOverdueInvoice(List<Invoice> invoices) { return invoices.any((invoice) => invoice.isOverdue);}any returns as soon as one invoice matches. The where form still has to build the iterable and ask it whether it produced anything.
isEmpty is every, with the predicate flipped
Section titled “isEmpty is every, with the predicate flipped”This is where the rewrite needs care: “nothing matches p” is “everything matches not p”, so the predicate has to be negated, not copied.
// Don't — no invoice is unpaidbool isFullySettled(List<Invoice> invoices) { return invoices.where((invoice) => !invoice.isPaid).isEmpty;}// Dobool isFullySettled(List<Invoice> invoices) { return invoices.every((invoice) => invoice.isPaid);}Known limitations
Section titled “Known limitations”Only where is matched. .map(...).isNotEmpty and .whereType<T>().isNotEmpty are not reported, since neither has an any/every equivalent that keeps the same meaning.
The where must take exactly one argument, and its receiver must resolve to an Iterable. A dynamic receiver is left alone.
length > 0 is not matched. Only the isEmpty and isNotEmpty getters are, so items.where(p).length > 0 passes — though any is the better call there too.
See also: Iterable.any | Iterable.every
Configuration
Section titled “Configuration”This rule is in the recommended preset, so it is on with
preset: recommended or preset: opinionated. Add it to preset: core with
prefer_any_or_every: true.
To turn it off:
rules: prefer_any_or_every: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Related rules
Section titled “Related rules”avoid_accessing_collections_by_constant_index— Avoid accessing a collection by a constant index inside a loop.avoid_collection_equality_checks— Avoid comparing collections with == or != as it checks reference equality, not contents.avoid_collection_methods_with_unrelated_types— Avoid calling collection methods with arguments whose types are unrelated to the collection’s type parameter.avoid_duplicate_collection_elements— Don’t repeat the same element in a collection literal.