flutter_semantic_lints 0.1.4
flutter_semantic_lints: ^0.1.4 copied to clipboard
Custom lint rules that detect meaningless, conflicting, or no-effect Flutter code.
flutter_semantic_lints #
English | 日本語 | 한국어 | Tiếng Việt | 中文 | Português | हिन्दी + English | Bahasa Indonesia | Türkçe | Español | العربية
Not style. Not formatting.
This package detects meaningless Flutter code.
Why this exists #
Most lint packages focus on:
- style
- naming
- best practices
But they miss something critical:
Code that works but makes no sense.
This package detects:
- conflicting parameters
- useless parameters
- no-effect widgets
Rules #
box_decoration_color_gradient #
Bad:
BoxDecoration(
color: Colors.red,
gradient: LinearGradient(...),
)
color is ignored.
Good:
BoxDecoration(
color: Colors.red,
)
Good:
BoxDecoration(
gradient: LinearGradient(...),
)
Use either color or gradient, not both.
container_color_decoration #
Bad:
Container(
color: Colors.red,
decoration: BoxDecoration(...),
)
color conflicts with decoration.
Good:
Container(
color: Colors.red,
)
Good:
Container(
decoration: BoxDecoration(
color: Colors.red,
),
)
Move the color into decoration when using decoration.
expanded_flex_one #
Bad:
Expanded(flex: 1)
Default value is already 1.
Good:
Expanded(
child: child,
)
Good:
Expanded(
flex: 2,
child: child,
)
Omit flex when the value is 1.
visibility_visible_true #
Bad:
Visibility(
visible: true,
child: child,
)
The child is already visible.
Good:
child
Good:
Visibility(
visible: isVisible,
child: child,
)
Use Visibility when visibility is dynamic.
edge_insets_all_zero #
Bad:
EdgeInsets.all(0)
EdgeInsets.zero already represents zero insets.
Good:
EdgeInsets.zero
border_radius_circular_zero #
Bad:
BorderRadius.circular(0)
BorderRadius.zero already represents no radius.
Good:
BorderRadius.zero
opacity_one #
Bad:
Opacity(
opacity: 1.0,
child: ...,
)
No visual effect. Adds cost only.
Good:
child
Good:
Opacity(
opacity: 0.5,
child: child,
)
Remove Opacity when the value is 1.0.
padding_zero #
Bad:
Padding(
padding: EdgeInsets.zero,
child: child,
)
No spacing is added.
Good:
child
transform_scale_one #
Bad:
Transform.scale(
scale: 1.0,
child: child,
)
The child is not scaled.
Good:
child
rotated_box_zero_turns #
Bad:
RotatedBox(
quarterTurns: 0,
child: child,
)
The child is not rotated.
Good:
child
empty_sized_box #
Bad:
SizedBox()
No width, height, or child is provided.
Good:
SizedBox.shrink()
Good:
SizedBox(width: 8)
Use SizedBox.shrink() when an explicit zero-size placeholder is intended.
Installation #
dev_dependencies:
custom_lint:
flutter_semantic_lints:
Setup #
analyzer:
plugins:
- custom_lint
Run #
dart run custom_lint
Configuration #
All rules are enabled by default.
Disable a rule:
analyzer:
plugins:
- custom_lint
custom_lint:
rules:
- opacity_one: false
Enable only selected rules:
analyzer:
plugins:
- custom_lint
custom_lint:
enable_all_lint_rules: false
rules:
- box_decoration_color_gradient
- container_color_decoration
Philosophy #
- correctness over style
- semantics over formatting
- signal over noise
Rule Categories #
conflicting_parameter #
box_decoration_color_gradientcontainer_color_decoration
useless_parameter #
expanded_flex_onevisibility_visible_trueedge_insets_all_zeroborder_radius_circular_zero
no_effect_widget #
opacity_onepadding_zerotransform_scale_onerotated_box_zero_turnsempty_sized_box
Not Included #
These are intentionally not linted yet:
Duration.zeroText('')foregroundDecorationcombinationsInputDecorationcombinations
They may be meaningful depending on the API or context. This package skips rules unless they are almost always correct.
Testing #
The example project doubles as integration coverage.
cp example/analysis_options.custom_lint.yaml example/analysis_options.yaml
cd example
dart run custom_lint
Positive cases use // expect_lint: comments. Negative and edge cases live in
separate example files and should stay quiet.
Non-goals #
- style lint
- naming rules
- formatting
- architecture opinions
Status #
MVP
Implemented rules:
- BoxDecoration conflict
- Container conflict
- Expanded(flex: 1)
- Opacity(1.0)
- Visibility(visible: true)
- EdgeInsets.all(0)
- BorderRadius.circular(0)
- Padding(padding: EdgeInsets.zero)
- Transform.scale(scale: 1.0)
- RotatedBox(quarterTurns: 0)
- SizedBox()
Contributing #
Only submit rules that:
- are objectively correct
- have near-zero false positives
- are explainable in one sentence
License #
MIT