nilts 0.25.0
nilts: ^0.25.0 copied to clipboard
nilts is lint rules, quick fixes and assists for Dart and Flutter projects that helps you enforce best practices, and avoid errors.
nilts #
nilts is lint rules, quick fixes and assists for Dart and Flutter projects that helps you enforce best practices, and avoid errors.
Contents #
- Usage
- Configuration
- Lint rules and quick fixes
- Assists
- Known issues
- Feature requests
- Bug reports
- Contributing
Usage #
nilts depends on custom_lint.
You should add nilts and custom_lint to your dev_dependencies in pubspec.yaml file.
dev_dependencies:
custom_lint: <version>
nilts: <version>
And also, add custom_lint to your analysis_options.yaml file.
analyzer:
plugins:
- custom_lint
Configuration #
You can configure all lint rules provided by nilts in analysis_options.yaml file.
Choice one of the following configuration strategies.
Disabling strategy #
All of nilts rules are enabled by default.
Add lint rule name and set false to disable it.
custom_lint:
rules:
# Disable particular lint rules if you want ignore them whole package.
- unnecessary_rebuilds_from_media_query: false
Enabling strategy #
You can disable all lint rules depends on custom_lint by setting enable_all_lint_rules to false.
Add lint rule name and set true to enable it.
custom_lint:
# Disable all lint rules depends on custom_lint.
enable_all_lint_rules: false
rules:
- unnecessary_rebuilds_from_media_query: true
NOTE: If you enable_all_lint_rules set to false, all of lint rules (not only all of nilts's lint rules) depends on custom_lint will be disabled by default.
Lint rules and quick fixes #
Read below to learn about each lint rules intend to. Some of lint rules support quick fixes on IDE.
Overview #
| Rule name | Overview | Target SDK | Rule type | Maturity level | Quick fix |
|---|---|---|---|---|---|
| defined_async_callback_type | Checks Future<void> Function() definitions. |
Any versions nilts supports | Practice | Experimental | ✅️ |
| defined_async_value_getter_type | Checks Future<T> Function() definitions. |
Any versions nilts supports | Practice | Experimental | ✅️ |
| defined_async_value_setter_type | Checks Future<void> Function(T value) definitions. |
Any versions nilts supports | Practice | Experimental | ✅️ |
| defined_value_changed_type | Checks void Function(T value) definitions. |
Any versions nilts supports | Practice | Experimental | ✅️ |
| defined_value_getter_type | Checks T Function() definitions. |
Any versions nilts supports | Practice | Experimental | ✅️ |
| defined_value_setter_type | Checks void Function(T value) definitions. |
Any versions nilts supports | Practice | Experimental | ✅️ |
| defined_void_callback_type | Checks void Function() definitions. |
Any versions nilts supports | Practice | Experimental | ✅️ |
| fixed_text_scale_rich_text | Checks usage of textScaler or textScaleFactor in RichText constructor. |
Any versions nilts supports | Practice | Experimental | ✅️ |
| flaky_tests_with_set_up_all | Checks setUpAll usages. |
Any versions nilts supports | Practice | Experimental | ✅️ |
| low_readability_numeric_literals | Checks numeric literals with 5 or more digits. | >= Flutter 3.27.0 (Dart 3.6.0) | Practice | Experimental | ✅️ |
| no_support_multi_text_direction | Checks if supports TextDirection changes. |
Any versions nilts supports | Practice | Experimental | ✅️ |
| no_support_web_platform_check | Checks if Platform.isXxx usages. |
Any versions nilts supports | Practice | Experimental | ✅️ |
| open_type_hierarchy | Checks if class modifiers exsist (final, sealed, etc.) | Any versions nilts supports | Practice | Experimental | ✅️ |
| shrink_wrapped_scroll_view | Checks the content of the scroll view is shrink wrapped. | Any versions nilts supports | Practice | Experimental | ✅️ |
| unnecessary_rebuilds_from_media_query | Checks MediaQuery.xxxOf(context) or MediaQuery.maybeXxxOf(context) usages. |
Any versions nilts supports | Practice | Experimental | ✅️ |
| unsafe_null_assertion | Checks usage of the ! operator for forced type casting. |
Any versions nilts supports | Practice | Experimental | ✅️ |
| unstable_enum_name | Checks usage of enum name property. | Any versions nilts supports | Practice | Experimental | ❌ |
| unstable_enum_values | Checks usage of enum values property. | Any versions nilts supports | Practice | Experimental | ❌ |
Details #
defined_async_callback_type
- Target SDK : Any versions nilts supports
- Rule type : Practice
- Maturity level : Experimental
- Quick fix : ✅
Consider replace Future<void> Function() with AsyncCallback which is defined in Flutter SDK.
BAD:
final Future<void> Function() callback;
GOOD:
final AsyncCallback callback;
See also:
defined_async_value_getter_type
- Target SDK : Any versions nilts supports
- Rule type : Practice
- Maturity level : Experimental
- Quick fix : ✅
Consider replace Future<T> Function() with AsyncValueGetter which is defined in Flutter SDK.
BAD:
final Future<int> Function() callback;
GOOD:
final AsyncValueGetter<int> callback;
See also:
defined_async_value_setter_type
- Target SDK : Any versions nilts supports
- Rule type : Practice
- Maturity level : Experimental
- Quick fix : ✅
Consider replace Future<void> Function(T value) with AsyncValueSetter which is defined in Flutter SDK.
BAD:
final Future<void> Function(int value) callback;
GOOD:
final AsyncValueSetter<int> callback;
See also:
defined_value_changed_type
- Target SDK : Any versions nilts supports
- Rule type : Practice
- Maturity level : Experimental
- Quick fix : ✅
Consider replace void Function(T value) with ValueChanged which is defined in Flutter SDK.
If the value has been set, use ValueSetter instead.
BAD:
final void Function(int value) callback;
GOOD:
final ValueChanged<int> callback;
See also:
defined_value_getter_type
- Target SDK : Any versions nilts supports
- Rule type : Practice
- Maturity level : Experimental
- Quick fix : ✅
Consider replace T Function() with ValueGetter which is defined in Flutter SDK.
BAD:
final int Function() callback;
GOOD:
final ValueGetter<int> callback;
See also:
defined_value_setter_type
- Target SDK : Any versions nilts supports
- Rule type : Practice
- Maturity level : Experimental
- Quick fix : ✅
Consider replace void Function(T value) with ValueSetter which is defined in Flutter SDK.
If the value has changed, use ValueChanged instead.
BAD:
final void Function(int value) callback;
GOOD:
final ValueSetter<int> callback;
See also:
defined_void_callback_type
- Target SDK : Any versions nilts supports
- Rule type : Practice
- Maturity level : Experimental
- Quick fix : ✅
Consider replace void Function() with VoidCallback which is defined in Flutter SDK.
BAD:
final void Function() callback;
GOOD:
final VoidCallback callback;
See also:
fixed_text_scale_rich_text
- Target SDK : Any versions nilts supports
- Rule type : Practice
- Maturity level : Experimental
- Quick fix : ✅
Consider using Text.rich or adding textScaler or textScaleFactor (deprecated on Flutter 3.16.0 and above) argument to RichText constructor to make the text size responsive for user setting.
BAD:
RichText(
text: TextSpan(
text: 'Hello, world!',
),
)
GOOD:
Text.rich(
TextSpan(
text: 'Hello, world!',
),
)
GOOD:
RichText(
text: TextSpan(
text: 'Hello, world!',
),
textScaler: MediaQuery.textScalerOf(context),
)
GOOD (deprecated on Flutter 3.16.0 and above):
RichText(
text: TextSpan(
text: 'Hello, world!',
),
textScaleFactor: MediaQuery.textScaleFactorOf(context),
)
See also:
flaky_tests_with_set_up_all
- Target SDK : Any versions nilts supports
- Rule type : Practice
- Maturity level : Experimental
- Quick fix : ✅
Consider using setUp function or initialization on top level or body of test group.
setUpAll may cause flaky tests with concurrency executions.
BAD:
setUpAll(() {
// ...
});
GOOD:
setUp(() {
// ...
});
void main() {
// do initialization on top level
// ...
group('...', () {
// or do initialization on body of test group
// ...
});
}
See also:
low_readability_numeric_literals
- Target SDK : >= Flutter 3.27.0 (Dart 3.6.0)
- Rule type : Practice
- Maturity level : Experimental
- Quick fix : ✅
Consider using digit separators for numeric literals with 5 or more digits to improve readability.
BAD:
const int value = 123456;
GOOD:
const int value = 123_456;
See also:
no_support_multi_text_direction
- Target SDK : Any versions nilts supports
- Rule type : Practice
- Maturity level : Experimental
- Quick fix : ✅
Consider using TextDirection aware configurations if your application supports different TextDirection languages.
BAD:
Align(
alignment: Alignment.bottomLeft,
)
BAD:
Padding(
padding: EdgeInsets.only(left: 16, right: 4),
)
BAD:
Positioned(left: 12, child: SizedBox())
GOOD:
Align(
alignment: AlignmentDirectional.bottomStart,
)
GOOD:
Padding(
padding: EdgeInsetsDirectional.only(start: 16, end: 4),
)
GOOD:
Positioned.directional(
start: 12,
textDirection: TextDirection.ltr,
child: SizedBox(),
)
PositionedDirectional(
start: 12,
child: SizedBox(),
)
See also:
no_support_web_platform_check
- Target SDK : Any versions nilts supports
- Rule type : Practice
- Maturity level : Experimental
- Quick fix : ✅
Prefer using defaultTargetPlatform instead of Platform API if you want to know which platform your application is running on.
This is because
PlatformAPI throws a runtime exception on web application.- By combining
kIsWebanddefaultTargetPlatform, you can accurately determine which platform your web application is running on.
BAD:
bool get isIOS => !kIsWeb && Platform.isIOS;
GOOD:
bool get isIOS => !kIsWeb && defaultTargetPlatform == TargetPlatform.iOS;
See also:
open_type_hierarchy
- Target SDK : Any versions nilts supports
- Rule type : Practice
- Maturity level : Experimental
- Quick fix : ✅
Consider adding a class modifier (final, sealed, etc.) to explicitly define the inheritance policy of your class.
BAD:
class MyClass {}
GOOD:
final class MyClass {}
shrink_wrapped_scroll_view
- Target SDK : Any versions nilts supports
- Rule type : Practice
- Maturity level : Experimental
- Quick fix : ✅
Consider removing shrinkWrap argument and update the Widget not to shrink wrap.
Shrink wrapping the content of the scroll view is significantly more expensive than expanding to the maximum allowed size because the content can expand and contract during scrolling, which means the size of the scroll view needs to be recomputed whenever the scroll position changes.
You can avoid shrink wrap with 3 steps below in case of your scroll view is nested.
- Replace the parent scroll view with
CustomScrollView. - Replace the child scroll view with
SliverListVieworSliverGridView. - Set
SliverChildBuilderDelegatetodelegateargument of theSliverListVieworSliverGridView.
BAD:
ListView(shrinkWrap: true)
GOOD:
ListView(shrinkWrap: false)
See also:
unnecessary_rebuilds_from_media_query
- Target SDK : Any versions nilts supports
- Rule type : Practice
- Maturity level : Experimental
- Quick fix : ✅
Prefer using MediaQuery.xxxOf or MediaQuery.maybeXxxOf instead of MediaQuery.of or MediaQuery.maybeOf to avoid unnecessary rebuilds.
BAD:
final size = MediaQuery.of(context).size;
GOOD:
final size = MediaQuery.sizeOf(context);
Note that using MediaQuery.of or MediaQuery.maybeOf makes sense following cases:
- wrap Widget with
MediaQueryoverriddenMediaQueryData - observe all changes of
MediaQueryData
See also:
unsafe_null_assertion
- Target SDK : Any versions nilts supports
- Rule type : Practice
- Maturity level : Experimental
- Quick fix : ✅
Prefer using if-null operator, null-aware operator or pattern matching instead of force type casting with ! operator.
BAD:
final value = someValue!;
GOOD:
final value = someValue ?? /* default value */;
GOOD:
final value = someValue?.someMethod();
See also:
unstable_enum_name
- Target SDK : Any versions nilts supports
- Rule type : Practice
- Maturity level : Experimental
- Quick fix : ❌
Consider using a more stable way to handle enum values.
The name property is a string representation of the enum value,
which can be changed without breaking the code.
BAD:
void printColorValue(Color color) {
print(color.name); // 'red', 'green', 'blue'
}
GOOD:
enum Color {
red,
green,
blue,
;
String get id => switch (this) {
red => 'red',
green => 'green',
blue => 'blue',
};
}
void printColorValue(Color color) {
print(color.id);
}
See also:
unstable_enum_values
- Target SDK : Any versions nilts supports
- Rule type : Practice
- Maturity level : Experimental
- Quick fix : ❌
Consider using a more stable way to handle enum values.
The values property returns a mutable List, which can be modified
and may cause unexpected behavior.
BAD:
enum Color { red, green, blue }
void printColors() {
for (final color in Color.values) {
print(color);
}
}
GOOD:
enum Color { red, green, blue }
void printColors() {
final colors = [Color.red, Color.green, Color.blue];
for (final color in colors) {
print(color);
}
}
See also:
Assists #
Upcoming... 🚀
Known issues #
Lint rule errors don't appear and quick fixes don't work in IDE (Fixed) #
Important
This issue is solved on nilts 0.18.3 using custom_lint 0.7.3.
Since custom_lint 0.6.7, the IDE has not shown lint rule errors in some cases.
See also:
- analysis.setContextRoots failed - RequestErrorCode.PLUGIN_ERROR ProcessException: / No such file or directory / Command: flutter pub get · Issue #270 · invertase/dart_custom_lint
- IntelliJ and Android Studio don't show custom lints · Issue #307 · invertase/dart_custom_lint
Quick fix priorities (Fixed) #
Important
Finding which a plugin version fixed the issue is hard, but it looks work as expected. Checked works as expected on Dart plugin 242.24931 and 243.23654.44.
The priorities assigned to quick fixes are not currently visible in IntelliJ IDEA and Android Studio due to the lack of support for PrioritizedSourceChange in these environments.
In contrast, VS Code does support this feature, allowing quick fixes to be listed along with their respective priorities.
| VS Code | IntelliJ IDEA / Android Studio |
|---|---|
See also:
fix-all assist (Fixed) #
Important
Finding which a plugin version fixed the issue is hard, but it looks as expected. Checked works as expected on Dart plugin 242.24931 and 243.23654.44.
The fix-all assist feature has been introduced in custom_lint_builder 0.6.0.
However, this feature is not yet supported in IntelliJ IDEA and Android Studio, owing to their current lack of support for PrioritizedSourceChange.
| VS Code | IntelliJ IDEA / Android Studio |
|---|---|
Feature requests #
If you have any feature requests, please create an issue from this template.
Bug reports #
If you find any bugs, please create an issue from this template.
Contributing #
Welcome your contributions!! Please read CONTRIBUTING docs before submitting your PR.