prefer-extracting-callbacks
Same as prefer-extracting-callbacks in Dart Code Metrics
- Group
- Complexity
- Path
lint/complexity/prefer-extracting-callbacks- Default
- Off, opt in
- Origin
- Dart Code Metrics
- Domain
- flutter
- Rule
- 353 of 512
Flags inline block-body callbacks passed to Widget constructors.
The rule uses resolved Flutter identities for both the containing Widget class and each constructed Widget. Calls that cannot be resolved uniquely are left alone; spelling, capitalization, and import-prefix shape are not evidence.
allowed-line-count (optional integer, default: unset) permits callbacks up
to that many lines. ignored-named-arguments (string array, default: empty)
excludes matching named arguments from callback checks.
Invalid
import 'package:flutter/material.dart';
import 'package:flutter/material.dart' as f;
class MyWidget extends StatelessWidget {
const MyWidget({super.key});
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {
final now = DateTime.now();
doSomething(now);
},
child: const Text('go'),
);
}
}
class MyState extends State<MyWidget> {
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
setState(() {});
doSomething(null);
},
child: const Text('tap'),
);
}
}
class PrefixedWidget extends f.StatelessWidget {
@override
f.Widget build(f.BuildContext context) => f.ElevatedButton(
onPressed: () {
final value = DateTime.now();
doSomething(value);
},
);
}
void doSomething(Object? x) {}
class NestedClosureReturn extends StatelessWidget {
@override
Widget build(BuildContext context) => ElevatedButton(
onPressed: () {
final nested = () {
return const Text('nested');
};
doSomething(nested);
},
);
} return ElevatedButton( onPressed: () { return GestureDetector( onTap: () { f.Widget build(f.BuildContext context) => f.ElevatedButton( onPressed: () { Widget build(BuildContext context) => ElevatedButton( onPressed: () {Valid
import 'package:flutter/material.dart';
// Non-widget class: callbacks are never flagged (dcl only visits Widget/State).
class NotAWidget {
void run(List<int> items) {
items.forEach((item) {
final doubled = item * 2;
print(doubled);
});
}
}
class MyWidget extends StatelessWidget {
const MyWidget({super.key});
final int mode = 0;
@override
Widget build(BuildContext context) {
return Column(
children: [
// Arrow callback: not a block body, never flagged.
ElevatedButton(
onPressed: () => doSomething(),
child: const Text('go'),
),
// Single-line block callback: within allowed_line_count, not flagged.
ElevatedButton(
onPressed: () { doSomething(); },
child: const Text('short'),
),
// Builder callback (first parameter is BuildContext) is excluded.
Builder(
builder: (BuildContext context) {
final theme = Theme.of(context);
return Text('$theme');
},
),
// Untyped builder parameter: unresolved, still treated as a builder.
Builder(
builder: (context) {
final label = 'value';
return Text(label);
},
),
// Widget returned only from nested branches still counts as a builder.
Builder(
builder: (BuildContext context) {
switch (mode) {
case 0:
return const Text('a');
default:
return const Text('b');
}
},
),
],
);
}
}
void doSomething() {}
class LocalFunctionReturn extends StatelessWidget {
@override
Widget build(BuildContext context) => Builder(
builder: (BuildContext context) {
Widget local() {
return const Text('local');
}
return local();
},
);
}Configure prefer-extracting-callbacks
Set its severity in falcon.json. See the configuration guide.
{
"linter": {
"rules": {
"complexity": {
"prefer-extracting-callbacks": "error"
}
}
}
}Or silence one occurrence with a suppression comment; the reason is required.
// falcon-ignore lint/complexity/prefer-extracting-callbacks: <reason>More complexity rules
- prefer-for-elements-to-map-from-iterable
prefer_for_elements_to_map_fromIterablerecommendedFlags
Map.fromIterable(x, key: ..., value: ...). - prefer-if-elements-to-conditional-expressions
prefer_if_elements_to_conditional_expressionsPrefers collection
ifelements to conditional expressions in list and set literals. - prefer-if-null-operators
prefer_if_null_operatorsrecommendedFlags
x == null ? y : x(and the invertedx != null ? x : y). - prefer-immediate-return
prefer-immediate-returnFlags a local variable that is returned on the immediately following statement.
- prefer-iterable-any
prefer_iterable_anyrecommendedFlags
iterable.where(...).isNotEmpty. - prefer-iterable-every
prefer_iterable_everyrecommendedFlags
iterable.where(predicate).isEmptyand filtered-length comparisons. - prefer-moving-to-variable
prefer-moving-to-variableFlags repeated property/getter chains in local variable initializers.
- prefer-null-aware-operators
prefer_null_aware_operatorsrecommendedFlags
x == null ? null : x.y(and the invertedx != null ? x.y : null).