The 3 new lints in Dart 2.18
Dart 2.18 is out on Aug 30, and here you can read what it brings. What that article is missing is that is has some new lints.
discarded_futures
If a method is asynchronous, its future is meant to notify your code that some change has happened. The linter documentation has a good example when this is vital:
void recreateDir(String path) {
deleteDir(path);
createDir(path);
}
Future<void> deleteDir(String path) async { /* ... */ }
Future<void> createDir(String path) async { /* ... */ }
If the future of the first call is not awaited, then the second call will throw an error.
Dart already had unawaited_futures
lint that was flagging such issues in async
functions, but the example above was not covered by it because recreateDir
is synchronous.
The new discarded_futures lint fills the missing gap and covers synchronous code.
It is not a replacement of the older lint, you should enable both of them.
Ideally, you should await or return all futures so that the client code has a chance to decide if it wants to await the result, but this is not always possible. For instance, a state of a StatefulWidget
in Flutter has a synchronous dispose()
method, so all futures created there are discarded. In this case use unawaited function like this:
@override
void dispose() {
unawaited(_streamController.close());
}
unnecessary_to_list_in_spreads
This code works:
final list = [
1,
2,
...[-1, 3, 4].where((n) => n > 0).toList(),
];
However, toList()
is useless in this case, because where
returns an Iterable
, and the spread operator ...
also accepts a Iterable
. The list is thus created just to be disposed.
The new unnecessary_to_list_in_spreads
lint flags such code.
unnecessary_null_aware_operator_on_extension_on_nullable
Now this one reveals a feature of Dart you likely did not know about. You can write an extension
on a nullable type, call its method on a null
and witness this
being null
:
void main() {
int? n;
n.printThis();
}extension on int? {
void printThis() {
print(this); // Prints 'null'
}
}
If you change the call to this,
n?.printThis(); // Added '?'
… then the method will not be called, and nothing will be printed.
The new unnecessary_null_aware_operator_on_extension_on_nullable
lint forces you to call such methods without ?
and to move the null
check into the method.
Why? Well, since you put it into an extension on nullable, you must have a point of calling it on null
. Otherwise you should just add a similar extension on a non-nullable type.
Calling methods on null
is actually useful in Dart. The most common example is this:
final a = null;
final str = a.toString(); // 'null'
Here is one real-world example:
extension on String? {
bool get isNullOrEmpty {
var self = this;
return self == null || self.isEmpty;
}
}
Enabling the New Lints
Read this article on how to enable those new lints manually.
Alternatively, you can use my package total_lints which enables most of the lints for your project. I use it to avoid repeating the linter configuration for my projects.