null-closures
Same as null_closures in Dart lints
- Group
- Correctness
- Path
lint/correctness/null-closures- Default
- On (recommended)
- Origin
- Dart lints
- Rule
- 302 of 512
Reject literal null in the closure slots of curated SDK APIs.
Mirrors the official null_closures lists: the constructors Future(),
Future.microtask, Future.sync, Timer(), Timer.periodic, and
List.generate; statics on classes named Future (doWhile, forEach,
wait(cleanUp:)) and Timer (run), regardless of their library; and
instance methods of Iterable, Map, List, Set, Queue, String, and Future invoked
on a receiver whose static type is, or has as a supertype, that SDK class
(project overrides of those methods included). Invocations without an
explicit target — the top-level scheduleMicrotask, implicit-this calls,
and cascade sections — are never checked, as in the official lint.
Parenthesized nulls do not match. Named arguments are reported as a whole;
positional indexes count named arguments too, matching analyzer source order.
Static callback APIs match the receiver's class name, even outside the SDK.
Invalid
import 'dart:async';
import 'dart:collection';
Iterable<int> getValues() => [];
void bad(
Iterable<int> values,
Map<String, int> map,
List<int> list,
Set<int> set,
Queue<int> queue,
String text,
Future<int> future,
) {
values.any(null);
getValues().any(null);
values.firstWhere(null, orElse: null);
values.fold(0, null);
map.putIfAbsent('x', null);
list.removeWhere(null);
set.retainWhere(null);
queue.removeWhere(null);
text.replaceAllMapped('x', null);
text.splitMapJoin('x', onMatch: null);
future.then(null, onError: null);
Future.microtask(null);
Future.doWhile(null);
Timer.run(null);
List.generate(2, null);
new Future.sync(null);
}
extension UnrelatedMap on int {
Object? map(Object? callback) => null;
}
void unrelatedExtensionDoesNotSuppress(List<int> values) {
values.map(null);
}
class ConstructorBase {
ConstructorBase(Object? value);
}
class ConstructorInitializers extends ConstructorBase {
ConstructorInitializers(List<int> values)
: field = values.map(null),
assert(values.any(null)),
super(values.where(null));
ConstructorInitializers.redirect(List<int> values)
: this(values.map(null));
final Iterable<int> field;
}
// The official lint checks the static type and all its supertypes, so a
// project override of an SDK callback method is flagged too.
abstract class CustomIterable implements Iterable<int> {
@override
bool any(Object? callback) => false;
}
void overrides(CustomIterable values) {
values.any(null);
}) { values.any(null); values.any(null); getValues().any(null); getValues().any(null); values.firstWhere(null, orElse: null); getValues().any(null); values.firstWhere(null, orElse: null); values.firstWhere(null, orElse: null); values.fold(0, null); values.fold(0, null); map.putIfAbsent('x', null); map.putIfAbsent('x', null); list.removeWhere(null); list.removeWhere(null); set.retainWhere(null); set.retainWhere(null); queue.removeWhere(null); queue.removeWhere(null); text.replaceAllMapped('x', null); text.replaceAllMapped('x', null); text.splitMapJoin('x', onMatch: null); text.splitMapJoin('x', onMatch: null); future.then(null, onError: null); text.splitMapJoin('x', onMatch: null); future.then(null, onError: null); future.then(null, onError: null); Future.microtask(null); Future.microtask(null); Future.doWhile(null); Future.doWhile(null); Timer.run(null); Timer.run(null); List.generate(2, null); List.generate(2, null); new Future.sync(null);void unrelatedExtensionDoesNotSuppress(List<int> values) { values.map(null); ConstructorInitializers(List<int> values) : field = values.map(null), : field = values.map(null), assert(values.any(null)), assert(values.any(null)), super(values.where(null)); ConstructorInitializers.redirect(List<int> values) : this(values.map(null));void overrides(CustomIterable values) { values.any(null);Valid
import 'dart:async';
void good(
Iterable<int> values,
Future<int> future,
Completer<int> completer,
dynamic maybeNull,
) {
values.any((value) => value > 0);
values.firstWhere((value) => true, orElse: () => 0);
future.then((value) => value + 1, onError: (error) => 0);
completer.complete(null);
Future.microtask(() => 1);
scheduleMicrotask(() {});
values.any(maybeNull);
}
class Iterable<T> {
bool any(Object? callback) => false;
}
void shadowed(Iterable<int> values) {
values.any(null);
}
extension CustomAny on String {
bool any(Object? callback) => false;
}
void overrides(String text) {
text.any(null);
}
// Neither `Future.delayed` nor the top-level `scheduleMicrotask` is on the
// official list, and cascaded calls have no target to check.
void unlisted(List<int> list) {
Future.delayed(Duration.zero, null);
scheduleMicrotask(null);
list..removeWhere(null);
}
class AsyncShadow {
final FutureFactory Future = FutureFactory();
}
class FutureFactory {
void microtask(Object? callback) {}
}
void prefixedSdkShadow(AsyncShadow async) {
async.Future.microtask(null);
}Configure null-closures
Set its severity in falcon.json. See the configuration guide.
{
"linter": {
"rules": {
"correctness": {
"null-closures": "error"
}
}
}
}Or silence one occurrence with a suppression comment; the reason is required.
// falcon-ignore lint/correctness/null-closures: <reason>More correctness rules
- prefer-correct-json-casts
Decode JSON containers using their actual runtime generic types.
- prefer-define-hero-tagflutter
Require an explicit heroTag on Flutter
FloatingActionButtonconstructors. - prefer-expect-latertest
Requires expectLater when a canonical expect call receives an unawaited Future.
- prefer-immutable-bloc-eventsrecommendedbloc
Flags Bloc event classes without an explicit @immutable annotation.
- prefer-immutable-bloc-staterecommendedbloc
Flags Bloc state classes without an explicit @immutable annotation.
- prefer-immutable-provider-argumentsriverpod
Requires stable value equality for freshly created Riverpod family keys.
- prefer-read-for-methodsrecommendedprovider
Flags void method actions on a listening Provider lookup during build.
- prefer-ref-read-for-methodsrecommendedriverpod
Flags watching a Riverpod notifier solely to invoke one of its methods.