Non-emptiness tested through length instead of isNotEmpty
ID |
dart.performance.prefer_is_not_empty |
Severity |
info |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Idiom |
Language |
Dart |
Description
Reports a non-emptiness test written as a comparison on length - length > 0, length != 0, 0 != length or length >= 1 - on a collection, String or any other object exposing length.
Rationale
length is not a stored field on every Iterable. For a lazy sequence - the result of map, where, expand or a synchronous generator - reading it iterates and materialises the whole sequence, when the question asked only needs to know whether a first element exists. isNotEmpty answers that after one step, and on an unbounded generator it is the difference between an answer and a hang. The comparison form also hides its intent: four different spellings mean "not empty", and a reviewer has to check which side of the operator the count is on before trusting any of them.
The following code illustrates the pattern detected by this rule:
class Inbox {
final List<String> messages;
final Map<String, String> headers;
Inbox(this.messages, this.headers);
bool get hasMail {
// FLAGGED: Non-emptiness tested through length instead of isNotEmpty
return messages.length > 0;
}
}