implicit-call-tearoffs
Same as implicit_call_tearoffs in Dart lints
- Group
- Style
- Path
lint/style/implicit-call-tearoffs- Default
- Off, opt in
- Origin
- Dart lints
- Rule
- 244 of 512
Explicitly tear off callable objects' call methods.
Reports each ImplicitCallReference the analyzer inserts. The coercion
applies to the outermost expression of a conditional, ??, or cascade (and to a type
instantiation, c<int>), so their operands are not reported again.
Invalid
import 'dart:async';
class Callable {
const Callable();
void call() {}
}
class ConstructorExpectedTypes {
final Function callback;
final Function defaultCallback;
const ConstructorExpectedTypes(
Callable callback, {
this.defaultCallback = const Callable(),
}) : callback = callback;
}
void accept(Function callback) {}
void acceptNamed({required Function callback}) {}
Function returnTopLevel() => const Callable();
Function topLevelCallback = const Callable();
set topLevelSetter(Function value) {}
class Receiver {
Receiver(Function callback, {required Function named});
Receiver.named({required Function callback});
Function fieldCallback = const Callable();
static Function staticCallback = const Callable();
set callbackSetter(Function value) {}
static set staticSetter(Function value) {}
void instance(Function callback, {required Function named}) {}
static void staticMethod(Function callback, {required Function named}) {}
Function returnMethod() => const Callable();
void assignments(Callable callback) {
Function localCallback = callback;
localCallback = callback;
fieldCallback = callback;
this.fieldCallback = callback;
Receiver.staticCallback = callback;
topLevelCallback = callback;
callbackSetter = callback;
this.callbackSetter = callback;
Receiver.staticSetter = callback;
topLevelSetter = callback;
}
void methodCalls(Callable callback, Receiver receiver) {
accept(callback);
acceptNamed(callback: callback);
instance(callback, named: callback.call);
instance(callback.call, named: callback);
this.instance(callback, named: callback.call);
receiver.instance(callback.call, named: callback);
Receiver.staticMethod(callback, named: callback.call);
Receiver.staticMethod(callback.call, named: callback);
}
void constructorCalls(Callable callback) {
Receiver(callback, named: callback.call);
Receiver(callback.call, named: callback);
new Receiver(callback, named: callback.call);
Receiver.named(callback: callback);
}
void localCalls(Callable callback) {
void localFunction(Function value, {required Function named}) {}
localFunction(callback, named: callback.call);
localFunction(callback.call, named: callback);
void Function(Function, {required Function named}) functionValue = localFunction;
functionValue(callback, named: callback.call);
final inferredFunctionValue = localFunction;
inferredFunctionValue(callback, named: callback.call);
}
void scoped(List<Callable> callbacks) {
Function localReturn() => const Callable();
localReturn();
for (Callable callback in callbacks) {
accept(callback);
}
try {
throw const Callable();
} on Callable catch (callback) {
accept(callback);
}
final (Callable callback,) = (const Callable(),);
accept(callback);
}
}
class BaseReceiver {
void inherited(Function callback) {}
set inheritedSetter(Function callback) {}
}
class ChildReceiver extends BaseReceiver {
void inheritedCalls(Callable callback) {
inherited(callback);
this.inherited(callback);
inheritedSetter = callback;
this.inheritedSetter = callback;
}
}
void topLevelCalls(Callable callback, Receiver receiver) {
Receiver(callback, named: callback.call);
receiver.instance(callback, named: callback.call);
}
class ObjectReceiver {
void accept(Object value) {}
}
class LexicalLookup extends ObjectReceiver {
// Inherited members are not in lexical scope: the top-level `accept` wins.
void topLevelShadowsInherited(Callable callback) {
accept(callback);
}
}
class MutableCallable {
void call() {}
int value = 0;
}
void outerCoercions(
MutableCallable first,
MutableCallable second,
MutableCallable? nullable,
bool condition,
) {
void Function() conditional = condition ? first : second;
void Function() cascade = first..value = 1;
void Function() coalesced = nullable ?? second;
}
extension type CallableView(Callable value) implements Callable {}
void contextualCoercions(Callable callback, CallableView view) {
void Function() extensionValue = view;
var spread = <void Function()>[...[callback]];
(void Function(), int) positional = (callback, 1);
({void Function() callback}) named = (callback: callback);
}
Future<void Function()> asyncReturn(Callable callback) async => callback;
Iterable<void Function()> generatorReturn(Callable callback) sync* {
yield callback;
}
void boundedCoercion<T extends Callable>(T callback) {
void Function() value = callback;
}
class GenericCallable {
void call<T>(T value) {}
}
void acceptIntCallback(void Function(int) callback) {}
void instantiatedCoercions(GenericCallable callback) {
Function functionContext = callback<int>;
void Function(int) typedContext = callback<int>;
acceptIntCallback(callback<int>);
callback<int>;
Function createdFunctionContext = GenericCallable()<int>;
void Function(int) createdTypedContext = GenericCallable()<int>;
acceptIntCallback(GenericCallable()<int>);
GenericCallable()<int>;
}
void acceptFutureOrCallback(FutureOr<void Function()> callback) {}
void futureOrCoercion(Callable callback) {
acceptFutureOrCallback(callback);
}
Stream<void Function()> asyncGeneratorReturn(Callable callback) async* {
yield callback;
} Callable callback, { this.defaultCallback = const Callable(), this.defaultCallback = const Callable(), }) : callback = callback;void acceptNamed({required Function callback}) {}Function returnTopLevel() => const Callable();Function returnTopLevel() => const Callable();Function topLevelCallback = const Callable(); Function fieldCallback = const Callable(); Function fieldCallback = const Callable(); static Function staticCallback = const Callable(); Function returnMethod() => const Callable(); void assignments(Callable callback) { Function localCallback = callback; Function localCallback = callback; localCallback = callback; localCallback = callback; fieldCallback = callback; fieldCallback = callback; this.fieldCallback = callback; this.fieldCallback = callback; Receiver.staticCallback = callback; Receiver.staticCallback = callback; topLevelCallback = callback; topLevelCallback = callback; callbackSetter = callback; callbackSetter = callback; this.callbackSetter = callback; this.callbackSetter = callback; Receiver.staticSetter = callback; Receiver.staticSetter = callback; topLevelSetter = callback; void methodCalls(Callable callback, Receiver receiver) { accept(callback); accept(callback); acceptNamed(callback: callback); acceptNamed(callback: callback); instance(callback, named: callback.call); instance(callback, named: callback.call); instance(callback.call, named: callback); instance(callback.call, named: callback); this.instance(callback, named: callback.call); this.instance(callback, named: callback.call); receiver.instance(callback.call, named: callback); receiver.instance(callback.call, named: callback); Receiver.staticMethod(callback, named: callback.call); Receiver.staticMethod(callback, named: callback.call); Receiver.staticMethod(callback.call, named: callback); void constructorCalls(Callable callback) { Receiver(callback, named: callback.call); Receiver(callback, named: callback.call); Receiver(callback.call, named: callback); Receiver(callback.call, named: callback); new Receiver(callback, named: callback.call); new Receiver(callback, named: callback.call); Receiver.named(callback: callback); void localFunction(Function value, {required Function named}) {} localFunction(callback, named: callback.call); localFunction(callback, named: callback.call); localFunction(callback.call, named: callback); void Function(Function, {required Function named}) functionValue = localFunction; functionValue(callback, named: callback.call); final inferredFunctionValue = localFunction; inferredFunctionValue(callback, named: callback.call); void scoped(List<Callable> callbacks) { Function localReturn() => const Callable(); for (Callable callback in callbacks) { accept(callback); } on Callable catch (callback) { accept(callback); final (Callable callback,) = (const Callable(),); accept(callback); void inheritedCalls(Callable callback) { inherited(callback); inherited(callback); this.inherited(callback); this.inherited(callback); inheritedSetter = callback; inheritedSetter = callback; this.inheritedSetter = callback;void topLevelCalls(Callable callback, Receiver receiver) { Receiver(callback, named: callback.call); Receiver(callback, named: callback.call); receiver.instance(callback, named: callback.call); void topLevelShadowsInherited(Callable callback) { accept(callback);) { void Function() conditional = condition ? first : second; void Function() conditional = condition ? first : second; void Function() cascade = first..value = 1; void Function() cascade = first..value = 1; void Function() coalesced = nullable ?? second;void contextualCoercions(Callable callback, CallableView view) { void Function() extensionValue = view; void Function() extensionValue = view; var spread = <void Function()>[...[callback]]; var spread = <void Function()>[...[callback]]; (void Function(), int) positional = (callback, 1); (void Function(), int) positional = (callback, 1); ({void Function() callback}) named = (callback: callback); Future<void Function()> asyncReturn(Callable callback) async => callback;Iterable<void Function()> generatorReturn(Callable callback) sync* { yield callback;void boundedCoercion<T extends Callable>(T callback) { void Function() value = callback;void instantiatedCoercions(GenericCallable callback) { Function functionContext = callback<int>; Function functionContext = callback<int>; void Function(int) typedContext = callback<int>; void Function(int) typedContext = callback<int>; acceptIntCallback(callback<int>); acceptIntCallback(callback<int>); callback<int>; callback<int>; Function createdFunctionContext = GenericCallable()<int>; Function createdFunctionContext = GenericCallable()<int>; void Function(int) createdTypedContext = GenericCallable()<int>; void Function(int) createdTypedContext = GenericCallable()<int>; acceptIntCallback(GenericCallable()<int>); acceptIntCallback(GenericCallable()<int>); GenericCallable()<int>;void futureOrCoercion(Callable callback) { acceptFutureOrCallback(callback);Stream<void Function()> asyncGeneratorReturn(Callable callback) async* { yield callback;Valid
class Callable {
const Callable();
void call() {}
}
void accept(Function callback) {}
void acceptNamed({required Function callback}) {}
void acceptsString(String value) {}
Function returnExplicit() => const Callable().call;
Function topLevelCallback = const Callable().call;
class Receiver {
Receiver(Function callback, {required Function named});
Receiver.named({required Function callback});
Function fieldCallback = const Callable().call;
static Function staticCallback = const Callable().call;
void instance(Function callback, {required Function named}) {}
static void staticMethod(Function callback, {required Function named}) {}
Function returnMethod() => const Callable().call;
void explicit(Callable callback, Receiver receiver) {
Function localCallback = callback.call;
localCallback = callback.call;
fieldCallback = callback.call;
this.fieldCallback = callback.call;
Receiver.staticCallback = callback.call;
topLevelCallback = callback.call;
accept(callback.call);
acceptNamed(callback: callback.call);
instance(callback.call, named: callback.call);
receiver.instance(callback.call, named: callback.call);
Receiver.staticMethod(callback.call, named: callback.call);
Receiver(callback.call, named: callback.call);
new Receiver(callback.call, named: callback.call);
Receiver.named(callback: callback.call);
}
void memberShadowsTopLevel(Callable callback) {
void accept(String value) {}
accept(callback);
}
}
void lexicalShadowing(Callable callback) {
void accept(String value) {}
accept(callback);
void Receiver(String value) {}
Receiver(callback);
void localFunction(String value, {required String named}) {}
localFunction(callback, named: callback);
void Function(String) functionValue = acceptsString;
functionValue(callback);
final inferredFunctionValue = acceptsString;
inferredFunctionValue(callback);
}
void importedOrUnknownCalls(Callable callback, dynamic importedReceiver) {
importedAccept(callback);
importedReceiver.accept(callback);
}
class BaseStringReceiver {
void accept(Object value) {}
set callback(Object value) {}
}
class OwnStringReceiver extends BaseStringReceiver {
@override
void accept(Object value) {}
void declaredMembersShadowTopLevel(Callable callable) {
accept(callable);
}
}
class ChildStringReceiver extends BaseStringReceiver {
void inheritedMembersShadowTopLevel(Callable callable) {
this.accept(callable);
callback = callable;
this.callback = callable;
}
}
void prefixedImportedTypes(
ext.Callable callback,
ext.Receiver receiver,
) {
accept(callback);
receiver.instance(callback);
ext.Receiver(callback);
new ext.Receiver(callback);
}
void reassignedFunctionValue(Callable callback) {
Function target = accept;
target = acceptsString;
target(callback);
}
void scopedShadowing(Callable callback) {
{
void accept(String value) {}
accept(callback);
}
accept(callback.call);
}
// A cyclic `extends` chain is invalid Dart but still parses; the lookup must
// terminate instead of walking the cycle forever.
class CyclicA extends CyclicB {}
class CyclicB extends CyclicA {}
void cyclicHierarchy(CyclicA value, Callable callback) {
value.whatever(callback);
}
class GenericCallable {
void call<T>(T value) {}
}
void explicitCompositeTearoffs(
Callable first,
Callable second,
Callable? nullable,
GenericCallable generic,
bool condition,
) {
void Function() conditional = condition ? first.call : second.call;
void Function() coalesced = nullable?.call ?? second.call;
void Function(int) instantiated = generic.call<int>;
var spread = <void Function()>[...[first.call]];
(void Function(), int) record = (first.call, 1);
}Configure implicit-call-tearoffs
Set its severity in falcon.json. See the configuration guide.
{
"linter": {
"rules": {
"style": {
"implicit-call-tearoffs": "error"
}
}
}
}Or silence one occurrence with a suppression comment; the reason is required.
// falcon-ignore lint/style/implicit-call-tearoffs: <reason>More style rules
- initializers-ordering
Requires field initializers to follow their containing type's field declaration order by default.
- leading-newlines-in-multiline-strings
leading_newlines_in_multiline_stringsFlags a multiline string spanning several lines whose text does not start with a line break right after the opening quotes.
- library-annotations
library_annotationsrecommendedRequires library-targeted metadata to attach to a
librarydirective. - library-names
library_namesrecommendedFlags a library name that is not
lowercase_with_underscores. - library-prefixes
library_prefixesrecommendedFlags import prefixes that are not
lower_case_with_underscores. - lines-longer-than-80-chars
lines_longer_than_80_charsFlags source lines longer than 80 characters.
- map-keys-ordering
Flags literal string map keys that violate the configured order.
- matching-super-parameters
matching_super_parametersFlags positional super parameters named differently from the super constructor's corresponding parameter.