altive_lints 4.0.0
altive_lints: ^4.0.0 copied to clipboard
Analyzer-independent lint presets with Altive's recommended rule selection and optional Analyzer Plugin integration.
Altive Lints #
Provides all_lint_rules.yaml that activates all lint rules and altive_lints.yaml with Altive recommended lint rule selection.
altive_lints enables Altive-made analysis rules from the separately resolved
altive_lints_plugin Analyzer Plugin.
Table of content #
- Table of content
- Getting started
- All custom analysis rules
- All assists
- Lint rules adopted by altive_lints and why
- Migration guide
Getting started #
altive_lints #
- Add altive_lints to your
pubspec.yaml:
dev_dependencies:
altive_lints:
- Include altive_lints in analysis_options.yaml.
If not, create a new one or copy analysis_options.yaml and use it.
include: package:altive_lints/altive_lints.yaml
This enables both the YAML preset and custom analysis rules. Do not add
altive_lints_plugin to pubspec.yaml; the analysis server resolves it
separately from the consuming pub workspace.
To use only the analyzer-independent YAML preset, include:
include: package:altive_lints/altive_lints_preset.yaml
SDK and package compatibility #
altive_lints 4.x is analyzer-independent. Its bundled analysis options enable
altive_lints_plugin, which the analysis server resolves in a synthetic
package outside the consuming pub workspace.
altive_lints |
Dart SDK | analysis_server_plugin |
analyzer |
Compatible test setup |
|---|---|---|---|---|
| 4.x | >=3.10.0 <4.0.0 |
separately resolved by altive_lints_plugin |
no direct dependency | test 1.31.0 / test_api 0.7.11 can resolve |
| 3.x | >=3.10.0 <4.0.0 |
0.3.15 |
13.0.0 |
test 1.31.1 / test_api 0.7.12 can resolve |
| 2.x | >=3.10.0 <4.0.0 |
resolves to 0.3.4 |
9.0.0 |
test 1.31.0 / test_api 0.7.11 can resolve, but this line does not include 3.x changes |
Flutter 3.44.7 / Dart 3.12.2 pins test_api to 0.7.11 through
flutter_test. If the same pub workspace also contains a Dart package that
depends on test, pub selects test 1.31.0, which requires
analyzer >=8.0.0 <13.0.0. This conflicts with the analyzer 13.0.0
required by altive_lints 3.x, so that workspace cannot resolve 3.x. Upgrade
to altive_lints 4.x for this SDK combination. Do not force analyzer 13 with
dependency_overrides: it violates test 1.31.0's supported range.
On Flutter 3.44.x, use dart analyze when command-line output must include
Analyzer Plugin diagnostics. flutter analyze can finish before those plugin
results are reported.
Disabling lint rules/analysis rules #
By default when installing altive_lints, most of the lints will be enabled. To change this, you have a few options.
include: package:altive_lints/altive_lints.yaml
linter:
rules:
# Explicitly disable one lint rule.
- public_member_api_docs: false
plugins:
altive_lints_plugin:
version: ^1.0.0
diagnostics:
# Explicitly disable one analysis rule.
avoid_consecutive_sliver_to_box_adapter: false
avoid_hardcoded_color: false
avoid_hardcoded_japanese: false
avoid_shrink_wrap_in_list_view: false
avoid_single_child: false
prefer_clock_now: false
prefer_dedicated_media_query_methods: false
prefer_space_between_elements: false
prefer_to_include_sliver_in_name: false
Ignoring analysis rules #
You can ignore analysis rules by using
ignore: altive_lints_plugin/{rule_name}.
// for file.
// ignore_for_file: altive_lints_plugin/avoid_hardcoded_color
...
// for line.
// ignore: altive_lints_plugin/avoid_hardcoded_color
Color(0xFF00FF00);
All custom analysis rules #
avoid_consecutive_sliver_to_box_adapter #
SliverToBoxAdapter must not be placed consecutively in slivers of CustomScrollView.
Bad:
CustomScrollView(
slivers: [
SliverToBoxAdapter(child: Text('Item 1')), // Consecutive usage
SliverToBoxAdapter(child: Text('Item 2')), // LINT
],
);
Good:
CustomScrollView(
slivers: [
SliverList.list(
children: [
Text('Item 1')
Text('Item 2')
],
),
],
);
avoid_hardcoded_color #
Do not use hard-coded Color.
However, Colors.transparent can be used.
Bad:
ColoredBox(
color: Color(0xFF00FF00), // LINT
);
Good:
ColoredBox(
color: Theme.of(context).colorScheme.primary,
);
avoid_hardcoded_japanese #
Hard-coded Japanese text strings must not be used. Use AppLocalizations, etc. to support internationalization.
Not applicable on test files.
Bad:
final message = 'こんにちは'; // LINT
print('エラーが発生しました'); // LINT
Good:
final message = AppLocalizations.of(context).hello;
print(AppLocalizations.of(context).errorOccurred);
avoid_shrink_wrap_in_list_view #
The shrinkWrap property must not be used in a ListView.
Use CustomScrollView and SliverList instead.
However, it is OK to use shrinkWrap if it is used to reduce the size of a dialog, such as when there is extra height in the dialog, so use ignore explicitly in such cases.
Bad:
ListView(
shrinkWrap: true, // LINT
children: [
Text('Hello'),
Text('World'),
],
);
Good:
CustomScrollView(
slivers: [
SliverList.list(
children: [
Text('Hello'),
Text('World'),
],
),
],
);
avoid_single_child #
The children property is intended to have multiple elements and should not be used with only one child element.
Bad:
Column(
children: [YourWidget()], // LINT
);
Good:
Center(child: YourWidget());
// or
Column(
children: [YourWidget1(), YourWidget2()],
);
prefer_clock_now #
Prefer using clock.now() instead of DateTime.now() or DateTime.timestamp().
By using the clock package and clock.now(), you can use the withClock method to replace the date and time at test time.
Bad:
var now = DateTime.now(); // LINT
var timestamp = DateTime.timestamp(); // LINT
Good:
var now = clock.now(); // Using 'clock' package
var timestamp = clock.now().toUtc(); // Preserve timestamp's UTC behavior
When the clock package is available, the lint offers a quick fix that adds
the required import and preserves whether the original value is local or UTC.
prefer_dedicated_media_query_methods #
Prefer to use dedicated MediaQuery methods instead of MediaQuery.of or MediaQuery.maybeOf.
This is to reduce unnecessary widget rebuilding and improve performance by using dedicated methods such as MediaQuery.sizeOf and MediaQuery.viewInsetsOf.
Bad:
var size = MediaQuery.of(context).size; // LINT
var width = MediaQuery.sizeOf(context).width; // LINT
var height = MediaQuery.sizeOf(context).height; // LINT
var padding = MediaQuery.maybeOf(context)?.padding; // LINT
var viewInsets = MediaQuery.viewInsetsOf(context); // LINT
Good:
var size = MediaQuery.sizeOf(context);
var width = MediaQuery.widthOf(context);
var height = MediaQuery.heightOf(context);
var padding = MediaQuery.paddingOf(context);
var viewInsets = MediaQuery.viewInsetsOf(context);
prefer_space_between_elements #
Prefer to insert blank lines for spacing rules in class definitions. between constructors and fields, and between constructors and build methods.
The purpose of proper spacing is to improve code readability and organization and to make it easier to visually distinguish between different sections of a class.
Bad:
class MyWidget extends StatelessWidget {
MyWidget(this.title);
final String title; // LINT
@override // LINT
Widget build(BuildContext context) {
return Text(title);
}
}
Good:
class MyWidget extends StatelessWidget {
MyWidget(this.title);
final String title;
@override
Widget build(BuildContext context) {
return Text(title);
}
}
prefer_to_include_sliver_in_name #
Prefer to include ‘Sliver’ in the class name or named constructor of a widget that returns a Sliver-type widget.
This makes it easy for the user to know at a glance that it is a Sliver type Widget, and improves readability and consistency.
Bad:
class MyCustomList extends StatelessWidget { // LINT
@override
Widget build(BuildContext context) {
return SliverList(...);
}
}
Good:
class SliverMyCustomList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SliverList(...);
}
}
All assists #
Add macro template documentation comment #
Adds a Macros template to class declarations.
When you place the cursor on the class declaration and execute "Add macro template documentation comment", the documentation is created.
Before:
class MyClass {
// Class implementation
}
After applying the assist:
/// {@template my_package.MyClass}
///
/// {@endtemplate}
class MyClass {
// Class implementation
}
Add macro documentation comment #
Adds Macros comments to constructors and method declarations.
When you place the cursor on a constructor or method declaration and execute "Add macro documentation comment", the documentation is created.
Before:
const myClass();
After applying the assist:
/// {@macro my_package.myFunction}
const myClass();
Wrap with macro template documentation comment #
Wraps existing documentation comments with a Macros template.
When you select the documentation comment and execute "Wrap with macro template documentation comment", the documentation is created.
Before:
/// Some comment
/// More comments
class MyClass {}
After applying the assist:
/// {@template my_package.MyClass}
/// Some comment
/// More comments
/// {@endtemplate}
class MyClass {}
For class, enum, mixin, and extension type.
Lint rules adopted by altive_lints and why #
Reasons for adopting each lint rule.
All lint rules disabled by altive_lints and their reasons can be found in altive_lints.yaml.
public_member_api_docs #
Even the best naming is difficult to grasp the big picture unless it is very simple.
An overview of it and documentation of why it exists and how to use it will help your teammates and future self.
Note
If there are too many applicable sections, such as when introducing the rule to an existing project, it is recommended to disable the rule once and then gradually address the issue.
Bad:
class DashboardCard extends StatelessWidget {
DashboardCard({required this.title, required this.content});
final String title;
final Widget content;
...
}
Good:
/// Cards to display an overview of each function on the dashboard.
///
/// [title] and [content] are required and cannot be omitted.
class DashboardCard extends StatelessWidget {
/// Creates a card-like widget to be placed on the dashboard.
DashboardCard({required this.title, required this.content});
/// A title string indicating the content to be displayed on the card.
final String title;
/// A widget to be displayed below the title.
///
/// We assume text, images, graphs, etc., but basically anything can be included.
/// Consider using [Column] if you want to arrange multiple pieces of content vertically.
final Widget content;
...
}
Migration guide #
v4.0.0 #
The YAML presets and Analyzer Plugin implementation are now separate packages. The standard setup is unchanged:
# pubspec.yaml
dev_dependencies:
altive_lints: ^4.0.0
# analysis_options.yaml
include: package:altive_lints/altive_lints.yaml
Replace diagnostic ignore prefixes from altive_lints/ with
altive_lints_plugin/, then restart the Dart Analysis Server. Do not add
altive_lints_plugin to pubspec.yaml, because doing so would bring its
analyzer dependency back into the consuming workspace.
If analysis_options.yaml overrides plugin diagnostics, rename that plugin
configuration as follows:
Before v4:
plugins:
altive_lints:
version: ^3.0.0
With v4:
plugins:
altive_lints_plugin:
version: ^1.0.0
If custom diagnostics are not needed, the analyzer-independent preset can be used on its own:
include: package:altive_lints/altive_lints_preset.yaml
For Flutter 3.44.x command-line checks, use dart analyze to receive Analyzer
Plugin diagnostics. This package split fixes pub dependency resolution; it does
not change flutter analyze's plugin-result timing on that Flutter release.
v1.12.0 #
The public_member_api_docs prompt to add documents has been activated. Please add documentation comments to public members.
If there are too many issues, disable them in analysis_options.yaml.