Flutter Refactor Plugin
A custom lint plugin that encourages declarative widget composition by suggesting the extraction of complex widget trees into separate helper methods or widgets.
This plugin includes the prefer_declarative_over_widget_nesting rule, which flags widget trees that are too deep or complex inside a build method and provides a Quick Fix to extract them with intelligent naming.
Features
- Lint Rule:
prefer_declarative_over_widget_nestingdetects when structural widgets (likeColumn,Row,Stack) contain complex children that should be extracted. - Smart Naming: The Quick Fix automatically suggests meaningful names for extracted methods based on the widget's content (e.g.,
Text('Login')->_buildLoginText). - Context Awareness: Handles
l10nvariables,contextaccess, and custom widgets gracefully. - Batch Fix Support: Safely handles "Fix All" operations by coordinating names to avoid collisions (e.g.,
_buildBorderLine,_buildBorderLine2). - Cross-Platform Support: Automatically downloads the required native helper binary for your platform (Linux, macOS, Windows) on the first run.
Installation
Add the package to your pubspec.yaml as a dev dependency, along with custom_lint:
dev_dependencies:
custom_lint: ^0.8.0
flutter_refactor_plugin: ^1.0.0
Note: The first time you run
dart run custom_lintor open the project in your IDE, the plugin will download a small helper binary (~5MB) from GitHub Releases. Internet access is required for this one-time setup.
Usage
Enable the plugin in your analysis_options.yaml:
analyzer:
plugins:
- custom_lint
custom_lint:
rules:
- prefer_declarative_over_widget_nesting
Example
Before:
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Text('Hello'), // Flagged: "Extract this widget..."
Icon(Icons.star),
],
),
);
}
After (Quick Fix):
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
_buildHelloText(),
_buildStarIcon(),
],
),
);
}
Widget _buildHelloText() {
return Text('Hello');
}
Widget _buildStarIcon() {
return Icon(Icons.star);
}