[linter] Update docs and state status for latest lints

Change-Id: If6006f5df03f90c50eb2860a3fa17118c8941b36
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/510820
Commit-Queue: Keerti Parthasarathy <keertip@google.com>
Reviewed-by: Keerti Parthasarathy <keertip@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Parker Lougheed
2026-06-11 11:01:15 -07:00
committed by dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent dbeb7e1e5b
commit 69ed86fda6
17 changed files with 180 additions and 39 deletions
+1 -1
View File
@@ -123,7 +123,7 @@ To learn more about the feature, check out the
- A `no_dynamic_casts` lint rule is introduced, which replaces the
`strict-casts` analysis option, offering a more consistent approach.
- The following lint rules have been determined to be low value, and are
deprecated: `avoid_public_typedef_functions`, and `one_member_abstracts`.
deprecated: `avoid_private_typedef_functions`, and `one_member_abstracts`.
If there is desire to keep using these, they can be re-implemented with
[analyzer plugins][].
+7 -1
View File
@@ -1,7 +1,13 @@
# 3.13.0-wip
- new lint: `unnecessary_const_in_enum_constructor`
- new lint: `async_return_with_no_await`
- new lint: `no_dynamic_casts`
- new lint: `no_raw_types`
- new lint: `unnecessary_type_name_in_constructor`
- new _(experimental)_ lint: `unnecessary_const_in_enum_constructor`
- new _(experimental)_ lint: `unnecessary_primary_constructor_body`
- deprecated lint: `avoid_private_typedef_functions`
- deprecated lint: `one_member_abstracts`
- stable: `unnecessary_null_checks`
- update `type_literal_in_constant_pattern` to ignore cases where the matched
pattern is of type `Type`.
+22
View File
@@ -90,6 +90,7 @@ const LinterLintWithoutArguments alwaysSpecifyTypesAddType =
name: 'always_specify_types',
problemMessage: "Missing type annotation.",
correctionMessage: "Try adding a type annotation.",
hasPublishedDocs: true,
uniqueName: 'always_specify_types_add_type',
expectedTypes: [],
);
@@ -337,6 +338,7 @@ annotateRedeclares = LinterLintTemplate(
problemMessage:
"The member '{0}' is redeclaring but isn't annotated with '@redeclare'.",
correctionMessage: "Try adding the '@redeclare' annotation.",
hasPublishedDocs: true,
uniqueName: 'annotate_redeclares',
withArguments: _withArgumentsAnnotateRedeclares,
expectedTypes: [ExpectedType.object],
@@ -358,6 +360,7 @@ const LinterLintWithoutArguments avoidAnnotatingWithDynamic =
name: 'avoid_annotating_with_dynamic',
problemMessage: "Unnecessary 'dynamic' type annotation.",
correctionMessage: "Try removing the type 'dynamic'.",
hasPublishedDocs: true,
uniqueName: 'avoid_annotating_with_dynamic',
expectedTypes: [],
);
@@ -378,6 +381,7 @@ const LinterLintWithoutArguments avoidBoolLiteralsInConditionalExpressions =
"Conditional expressions with a 'bool' literal can be simplified.",
correctionMessage:
"Try rewriting the expression to use either '&&' or '||'.",
hasPublishedDocs: true,
uniqueName: 'avoid_bool_literals_in_conditional_expressions',
expectedTypes: [],
);
@@ -390,6 +394,7 @@ const LinterLintWithoutArguments avoidCatchesWithoutOnClauses =
"Catch clause should use 'on' to specify the type of exception being "
"caught.",
correctionMessage: "Try adding an 'on' clause before the 'catch'.",
hasPublishedDocs: true,
uniqueName: 'avoid_catches_without_on_clauses',
expectedTypes: [],
);
@@ -438,6 +443,7 @@ const LinterLintWithoutArguments avoidDoubleAndIntChecks =
name: 'avoid_double_and_int_checks',
problemMessage: "Explicit check for double or int.",
correctionMessage: "Try removing the check.",
hasPublishedDocs: true,
uniqueName: 'avoid_double_and_int_checks',
expectedTypes: [],
);
@@ -513,6 +519,7 @@ const LinterLintWithoutArguments avoidFinalParameters =
name: 'avoid_final_parameters',
problemMessage: "Parameters should not be marked as 'final'.",
correctionMessage: "Try removing the keyword 'final'.",
hasPublishedDocs: true,
uniqueName: 'avoid_final_parameters',
expectedTypes: [],
);
@@ -565,6 +572,7 @@ avoidJsRoundedInts = LinterLintWithoutArguments(
problemMessage:
"Integer literal can't be represented exactly when compiled to JavaScript.",
correctionMessage: "Try using a 'BigInt' to represent the value.",
hasPublishedDocs: true,
uniqueName: 'avoid_js_rounded_ints',
expectedTypes: [],
);
@@ -596,6 +604,7 @@ const LinterLintWithoutArguments avoidPositionalBooleanParameters =
name: 'avoid_positional_boolean_parameters',
problemMessage: "'bool' parameters should be named parameters.",
correctionMessage: "Try converting the parameter to a named parameter.",
hasPublishedDocs: true,
uniqueName: 'avoid_positional_boolean_parameters',
expectedTypes: [],
);
@@ -629,6 +638,7 @@ avoidRedundantArgumentValues = LinterLintWithoutArguments(
"The value of the argument is redundant because it matches the default "
"value.",
correctionMessage: "Try removing the argument.",
hasPublishedDocs: true,
uniqueName: 'avoid_redundant_argument_values',
expectedTypes: [],
);
@@ -821,6 +831,7 @@ const LinterLintWithoutArguments avoidTypesOnClosureParameters =
problemMessage:
"Unnecessary type annotation on a function expression parameter.",
correctionMessage: "Try removing the type annotation.",
hasPublishedDocs: true,
uniqueName: 'avoid_types_on_closure_parameters',
expectedTypes: [],
);
@@ -868,6 +879,7 @@ avoidUnusedConstructorParameters = LinterLintTemplate(
name: 'avoid_unused_constructor_parameters',
problemMessage: "The parameter '{0}' is not used in the constructor.",
correctionMessage: "Try using the parameter or removing it.",
hasPublishedDocs: true,
uniqueName: 'avoid_unused_constructor_parameters',
withArguments: _withArgumentsAvoidUnusedConstructorParameters,
expectedTypes: [ExpectedType.object],
@@ -2157,6 +2169,7 @@ parameterAssignments = LinterLintTemplate(
name: 'parameter_assignments',
problemMessage: "Invalid assignment to the parameter '{0}'.",
correctionMessage: "Try using a local variable in place of the parameter.",
hasPublishedDocs: true,
uniqueName: 'parameter_assignments',
withArguments: _withArgumentsParameterAssignments,
expectedTypes: [ExpectedType.object],
@@ -2550,6 +2563,7 @@ const LinterLintWithoutArguments preferIntLiterals = LinterLintWithoutArguments(
name: 'prefer_int_literals',
problemMessage: "Unnecessary use of a 'double' literal.",
correctionMessage: "Try using an 'int' literal.",
hasPublishedDocs: true,
uniqueName: 'prefer_int_literals',
expectedTypes: [],
);
@@ -2827,6 +2841,7 @@ const LinterLintWithoutArguments simpleDirectivePaths =
name: 'simple_directive_paths',
problemMessage: "Use simple directive paths.",
correctionMessage: "Try simplifying the directive path.",
hasPublishedDocs: true,
uniqueName: 'simple_directive_paths',
expectedTypes: [],
);
@@ -3124,6 +3139,7 @@ const LinterLintWithoutArguments unnecessaryAsync = LinterLintWithoutArguments(
name: 'unnecessary_async',
problemMessage: "Don't make a function 'async' if it doesn't use 'await'.",
correctionMessage: "Try removing the 'async' modifier.",
hasPublishedDocs: true,
uniqueName: 'unnecessary_async',
expectedTypes: [],
);
@@ -3134,6 +3150,7 @@ const LinterLintWithoutArguments unnecessaryAwaitInReturn =
name: 'unnecessary_await_in_return',
problemMessage: "Unnecessary 'await'.",
correctionMessage: "Try removing the 'await'.",
hasPublishedDocs: true,
uniqueName: 'unnecessary_await_in_return',
expectedTypes: [],
);
@@ -3154,6 +3171,7 @@ const LinterLintWithoutArguments unnecessaryBreaks = LinterLintWithoutArguments(
name: 'unnecessary_breaks',
problemMessage: "Unnecessary 'break' statement.",
correctionMessage: "Try removing the 'break'.",
hasPublishedDocs: true,
uniqueName: 'unnecessary_breaks',
expectedTypes: [],
);
@@ -3174,6 +3192,7 @@ const LinterLintWithoutArguments unnecessaryConstInEnumConstructor =
name: 'unnecessary_const_in_enum_constructor',
problemMessage: "Unnecessary 'const' keyword in an enum constructor.",
correctionMessage: "Try removing the keyword.",
hasPublishedDocs: true,
uniqueName: 'unnecessary_const_in_enum_constructor',
expectedTypes: [],
);
@@ -3315,6 +3334,7 @@ unnecessaryLibraryDirective = LinterLintWithoutArguments(
problemMessage:
"Library directives without comments or annotations should be avoided.",
correctionMessage: "Try deleting the library directive.",
hasPublishedDocs: true,
uniqueName: 'unnecessary_library_directive',
expectedTypes: [],
);
@@ -3504,6 +3524,7 @@ const LinterLintWithoutArguments unnecessaryTypeNameInConstructor =
name: 'unnecessary_type_name_in_constructor',
problemMessage: "Unnecessary type name in a constructor.",
correctionMessage: "Try removing the type name.",
hasPublishedDocs: true,
uniqueName: 'unnecessary_type_name_in_constructor',
expectedTypes: [],
);
@@ -3964,6 +3985,7 @@ const LinterLintWithoutArguments varWithNoTypeAnnotation =
correctionMessage:
"Try removing the keyword 'var' or replacing `var` with a type "
"annotation.",
hasPublishedDocs: true,
uniqueName: 'var_with_no_type_annotation',
expectedTypes: [],
);
@@ -14,7 +14,12 @@ import '../diagnostic.dart' as diag;
const _desc = r'Return with no await.';
class AsyncReturnWithNoAwait extends AnalysisRule {
new() : super(name: LintNames.async_return_with_no_await, description: _desc);
new()
: super(
name: LintNames.async_return_with_no_await,
description: _desc,
state: .stable(since: .new(3, 13, 0)),
);
@override
DiagnosticCode get diagnosticCode => diag.asyncReturnWithNoAwait;
@@ -17,7 +17,12 @@ import '../diagnostic.dart' as diag;
const _desc = r'Use `;` instead of `{}` for empty container bodies.';
class EmptyContainerBodies extends AnalysisRule {
new() : super(name: LintNames.empty_container_bodies, description: _desc);
new()
: super(
name: LintNames.empty_container_bodies,
description: _desc,
state: .experimental(since: .new(3, 13, 0)),
);
@override
DiagnosticCode get diagnosticCode => diag.emptyContainerBodies;
@@ -21,6 +21,7 @@ class InitializeInFieldDeclaration extends AnalysisRule {
: super(
name: LintNames.initialize_in_field_declaration,
description: _desc,
state: .experimental(since: .new(3, 13, 0)),
);
@override
@@ -17,7 +17,12 @@ import '../diagnostic.dart' as diag;
const _desc = r'Avoid implicit casts from `dynamic`.';
class NoDynamicCasts extends AnalysisRule {
new() : super(name: LintNames.no_dynamic_casts, description: _desc);
new()
: super(
name: LintNames.no_dynamic_casts,
description: _desc,
state: .stable(since: .new(3, 13, 0)),
);
@override
DiagnosticCode get diagnosticCode => diag.noDynamicCasts;
+6 -1
View File
@@ -16,7 +16,12 @@ import '../diagnostic.dart' as diag;
const _desc = r'Avoid raw types.';
class NoRawTypes extends AnalysisRule {
new() : super(name: LintNames.no_raw_types, description: _desc);
new()
: super(
name: LintNames.no_raw_types,
description: _desc,
state: .stable(since: .new(3, 13, 0)),
);
@override
DiagnosticCode get diagnosticCode => diag.noRawTypes;
@@ -16,7 +16,12 @@ import '../diagnostic.dart' as diag;
const _desc = r'Use simple directive paths.';
class SimpleDirectivePaths extends AnalysisRule {
new() : super(name: LintNames.simple_directive_paths, description: _desc);
new()
: super(
name: LintNames.simple_directive_paths,
description: _desc,
state: .stable(since: .new(3, 12, 0)),
);
@override
DiagnosticCode get diagnosticCode => diag.simpleDirectivePaths;
@@ -20,6 +20,7 @@ class UnnecessaryConstInEnumConstructor extends AnalysisRule {
: super(
name: LintNames.unnecessary_const_in_enum_constructor,
description: _desc,
state: .experimental(since: .new(3, 13, 0)),
);
@override
@@ -20,6 +20,7 @@ class UnnecessaryPrimaryConstructorBody extends AnalysisRule {
: super(
name: LintNames.unnecessary_primary_constructor_body,
description: _desc,
state: .experimental(since: .new(3, 13, 0)),
);
@override
@@ -20,6 +20,7 @@ class UnnecessaryTypeNameInConstructor extends AnalysisRule {
: super(
name: LintNames.unnecessary_type_name_in_constructor,
description: _desc,
state: .stable(since: .new(3, 13, 0)),
);
@override
@@ -17,7 +17,12 @@ import '../diagnostic.dart' as diag;
const _desc = r'Use a declaring parameter.';
class UseDeclaringParameters extends AnalysisRule {
new() : super(name: LintNames.use_declaring_parameters, description: _desc);
new()
: super(
name: LintNames.use_declaring_parameters,
description: _desc,
state: .experimental(since: .new(3, 13, 0)),
);
@override
DiagnosticCode get diagnosticCode => diag.useDeclaringParameters;
@@ -18,7 +18,12 @@ import '../diagnostic.dart' as diag;
const _desc = r'Use a primary constructor.';
class UsePrimaryConstructors extends AnalysisRule {
new() : super(name: LintNames.use_primary_constructors, description: _desc);
new()
: super(
name: LintNames.use_primary_constructors,
description: _desc,
state: .experimental(since: .new(3, 13, 0)),
);
@override
DiagnosticCode get diagnosticCode => diag.usePrimaryConstructors;
@@ -18,7 +18,11 @@ const _desc = r'Avoid declaring parameters with `var` and no type annotation.';
class VarWithNoTypeAnnotation extends AnalysisRule {
new()
: super(name: LintNames.var_with_no_type_annotation, description: _desc);
: super(
name: LintNames.var_with_no_type_annotation,
description: _desc,
state: .experimental(since: .new(3, 12, 0)),
);
@override
DiagnosticCode get diagnosticCode => diag.varWithNoTypeAnnotation;
+39 -22
View File
@@ -6,6 +6,7 @@
# make sure to regenerate supporting classes by running:
#
# dart run pkg/linter/tool/generate_lints.dart
# dart run pkg/analyzer/tool/messages/generate.dart
# There is a fixed set of categories:
#
@@ -270,7 +271,7 @@ LinterLintCode:
state:
stable: "2.0"
categories: [style]
hasPublishedDocs: false
hasPublishedDocs: true
documentation: |-
#### Description
@@ -740,7 +741,7 @@ LinterLintCode:
state:
experimental: "3.2"
categories: [style]
hasPublishedDocs: false
hasPublishedDocs: true
documentation: |-
#### Description
@@ -887,7 +888,7 @@ LinterLintCode:
state:
stable: "2.0"
categories: [brevity, style]
hasPublishedDocs: false
hasPublishedDocs: true
documentation: |-
#### Description
@@ -987,7 +988,7 @@ LinterLintCode:
state:
stable: "2.0"
categories: [brevity]
hasPublishedDocs: false
hasPublishedDocs: true
documentation: |-
#### Description
@@ -1054,7 +1055,7 @@ LinterLintCode:
state:
stable: "2.0"
categories: [effectiveDart, style]
hasPublishedDocs: false
hasPublishedDocs: true
documentation: |-
#### Description
@@ -1216,7 +1217,7 @@ LinterLintCode:
state:
stable: "2.0"
categories: [errorProne, web]
hasPublishedDocs: false
hasPublishedDocs: true
documentation: |-
#### Description
@@ -1637,7 +1638,7 @@ LinterLintCode:
state:
stable: "2.16"
categories: [style]
hasPublishedDocs: false
hasPublishedDocs: true
documentation: |-
NOTE: This rule is removed in Dart 3.13.0; it is no longer functional.
@@ -2070,7 +2071,7 @@ LinterLintCode:
state:
stable: "2.0"
categories: [errorProne, web]
hasPublishedDocs: false
hasPublishedDocs: true
documentation: |-
#### Description
@@ -2199,7 +2200,7 @@ LinterLintCode:
experimental: "2.0"
stable: "2.2"
categories: [effectiveDart, style]
hasPublishedDocs: false
hasPublishedDocs: true
documentation: |-
#### Description
@@ -2346,9 +2347,17 @@ LinterLintCode:
correctionMessage: "Try inlining the type or using it in other places."
state:
stable: "2.0"
deprecated: "3.13"
categories: [style]
hasPublishedDocs: false
deprecatedDetails: |-
**NOTE:** As a private typedef can make some code more readable,
this lint rule has been deprecated as of Dart 3.13 and is
set to be removed in a future release of the Dart SDK.
Remove all inclusions of this lint from your analysis options.
If you wish to keep enforcing it, consider implementing the
rule with an [analyzer plugin](https://dart.dev/tools/analyzer-plugins).
**AVOID** private typedef functions used only once. Prefer inline function
syntax.
@@ -2370,7 +2379,7 @@ LinterLintCode:
state:
stable: "2.8"
categories: [brevity, style]
hasPublishedDocs: false
hasPublishedDocs: true
documentation: |-
#### Description
@@ -3208,7 +3217,7 @@ LinterLintCode:
state:
stable: "2.0"
categories: [style]
hasPublishedDocs: false
hasPublishedDocs: true
documentation: |-
#### Description
@@ -3380,7 +3389,7 @@ LinterLintCode:
# TODO(srawlins): This isn't even just about unintentional syntax; unused
# parameters can represent code bloat.
categories: [unintentional]
hasPublishedDocs: false
hasPublishedDocs: true
documentation: |-
#### Description
@@ -8643,9 +8652,17 @@ LinterLintCode:
correctionMessage: "Try making '#p0' a top-level function and removing the class."
state:
stable: "2.0"
deprecated: "3.13"
categories: [effectiveDart, languageFeatureUsage, style]
hasPublishedDocs: false
deprecatedDetails: |-
**NOTE:** As one member abstracts are often a stepping stone,
this lint rule has been deprecated as of Dart 3.13 and is
set to be removed in a future release of the Dart SDK.
Remove all inclusions of this lint from your analysis options.
If you wish to keep enforcing it, consider implementing the
rule with an [analyzer plugin](https://dart.dev/tools/analyzer-plugins).
From [Effective Dart](https://dart.dev/effective-dart/design#avoid-defining-a-one-member-abstract-class-when-a-simple-function-will-do):
**AVOID** defining a one-member abstract class when a simple function will do.
@@ -9036,7 +9053,7 @@ LinterLintCode:
state:
stable: "2.0"
categories: [style]
hasPublishedDocs: false
hasPublishedDocs: true
documentation: |-
#### Description
@@ -11022,7 +11039,7 @@ LinterLintCode:
state:
stable: "2.1"
categories: [style]
hasPublishedDocs: false
hasPublishedDocs: true
documentation: |-
#### Description
@@ -12195,7 +12212,7 @@ LinterLintCode:
state:
stable: "3.12"
categories: [style]
hasPublishedDocs: false
hasPublishedDocs: true
documentation: |-
#### Description
@@ -13910,7 +13927,7 @@ LinterLintCode:
state:
experimental: "3.7"
categories: [style]
hasPublishedDocs: false
hasPublishedDocs: true
documentation: |-
#### Description
@@ -13969,7 +13986,7 @@ LinterLintCode:
state:
stable: "2.1"
categories: [style]
hasPublishedDocs: false
hasPublishedDocs: true
documentation: |-
#### Description
@@ -14089,7 +14106,7 @@ LinterLintCode:
state:
stable: "3.0"
categories: [brevity, style]
hasPublishedDocs: false
hasPublishedDocs: true
documentation: |-
#### Description
@@ -14239,7 +14256,7 @@ LinterLintCode:
state:
experimental: "3.13"
categories: [brevity, style]
hasPublishedDocs: false
hasPublishedDocs: true
documentation: |-
#### Description
@@ -14735,7 +14752,7 @@ LinterLintCode:
state:
stable: "2.19"
categories: [brevity]
hasPublishedDocs: false
hasPublishedDocs: true
documentation: |-
#### Description
@@ -15764,7 +15781,7 @@ LinterLintCode:
state:
stable: "3.13"
categories: [brevity, style]
hasPublishedDocs: false
hasPublishedDocs: true
documentation: |-
#### Description
@@ -17749,7 +17766,7 @@ LinterLintCode:
state:
experimental: "3.12"
categories: [languageFeatureUsage]
hasPublishedDocs: false
hasPublishedDocs: true
documentation: |-
NOTE: This rule is removed in Dart 3.13.0; it is no longer functional.
+59 -6
View File
@@ -109,6 +109,19 @@
"details": "**DO** annotate redeclared members.\n\nThis practice improves code readability and helps protect against\nunintentionally redeclaring members or being surprised when a member ceases to\nredeclare (due for example to a rename refactoring).\n\n**BAD:**\n```dart\nclass C {\n void f() { }\n}\n\nextension type E(C c) implements C {\n void f() {\n ...\n }\n}\n```\n\n**GOOD:**\n```dart\nimport 'package:meta/meta.dart';\n\nclass C {\n void f() { }\n}\n\nextension type E(C c) implements C {\n @redeclare\n void f() {\n ...\n }\n}\n```",
"sinceDartSdk": "3.2"
},
{
"name": "async_return_with_no_await",
"description": "Return with no await.",
"categories": [
"errorProne"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
"details": "**DO** use `await` when returning a `Future` from an `async` function.\n\n**BAD:**\n```dart\nFuture<String> futureString(Future<String> value) async {\n return value;\n}\nFuture<int> futureInt(Future<int> value) async => value;\n```\n\n**GOOD:**\n```dart\nFuture<String> futureString(Future<String> value) async {\n return await value;\n}\nFuture<int> futureInt(Future<int> value) => value;\n```",
"sinceDartSdk": "3.13"
},
{
"name": "avoid_annotating_with_dynamic",
"description": "Avoid annotating with `dynamic` when not required.",
@@ -414,11 +427,11 @@
"categories": [
"style"
],
"state": "stable",
"state": "deprecated",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
"details": "**AVOID** private typedef functions used only once. Prefer inline function\nsyntax.\n\n**BAD:**\n```dart\ntypedef void _F();\nm(_F f);\n```\n\n**GOOD:**\n```dart\nm(void Function() f);\n```",
"details": "**NOTE:** As a private typedef can make some code more readable,\nthis lint rule has been deprecated as of Dart 3.13 and is\nset to be removed in a future release of the Dart SDK.\nRemove all inclusions of this lint from your analysis options.\nIf you wish to keep enforcing it, consider implementing the\nrule with an [analyzer plugin](https://dart.dev/tools/analyzer-plugins).\n\n**AVOID** private typedef functions used only once. Prefer inline function\nsyntax.\n\n**BAD:**\n```dart\ntypedef void _F();\nm(_F f);\n```\n\n**GOOD:**\n```dart\nm(void Function() f);\n```",
"sinceDartSdk": "2.0"
},
{
@@ -1389,6 +1402,19 @@
"details": "**DON'T** use more than one case with same value.\n\nThis is usually a typo or changed value of constant.\n\n**BAD:**\n```dart\nconst int A = 1;\nswitch (v) {\n case 1:\n case 2:\n case A:\n case 2:\n}\n```\n\n**GOOD:**\n```dart\nconst int A = 1;\nswitch (v) {\n case A:\n case 2:\n}\n```\n\nNOTE: this lint only reports duplicate cases in libraries opted in to Dart 2.19\nand below. In Dart 3.0 and after, duplicate cases are reported as dead code\nby the analyzer.",
"sinceDartSdk": "2.0"
},
{
"name": "no_dynamic_casts",
"description": "Avoid implicit casts from `dynamic`.",
"categories": [
"errorProne"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "needsFix",
"details": "**DO** avoid implicit casts from `dynamic`.\n\nAssigning a `dynamic`-typed expression to a non-`dynamic`, non-`Object?`\ntarget is a form of implicit casting. It is better to make such a cast\nexplicit, so that it is visible to developers.\n\n**BAD:**\n```dart\nvoid f(dynamic x) {\n int y = x;\n}\n```\n\n**GOOD:**\n```dart\nvoid f(dynamic x) {\n int y = x as int;\n}\n```",
"sinceDartSdk": "3.13"
},
{
"name": "no_leading_underscores_for_library_prefixes",
"description": "Avoid leading underscores for library prefixes.",
@@ -1443,6 +1469,19 @@
"details": "**DON'T** put any logic in `createState()`.\n\nImplementations of `createState()` should return a new instance\nof a State object and do nothing more. Since state access is preferred\nvia the `widget` field, passing data to `State` objects using custom\nconstructor parameters should also be avoided and so further, the State\nconstructor is required to be passed no arguments.\n\n**BAD:**\n```dart\nMyState global;\n\nclass MyStateful extends StatefulWidget {\n @override\n MyState createState() {\n global = MyState();\n return global;\n }\n}\n```\n\n```dart\nclass MyStateful extends StatefulWidget {\n @override\n MyState createState() => MyState()..field = 42;\n}\n```\n\n```dart\nclass MyStateful extends StatefulWidget {\n @override\n MyState createState() => MyState(42);\n}\n```\n\n\n**GOOD:**\n```dart\nclass MyStateful extends StatefulWidget {\n @override\n MyState createState() {\n return MyState();\n }\n}\n```",
"sinceDartSdk": "2.8"
},
{
"name": "no_raw_types",
"description": "Avoid raw types.",
"categories": [
"errorProne"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "needsFix",
"details": "**DON'T** use raw types.\n\nA raw type is a type annotation for a generic type which omits type\narguments. Developers may mistakenly believe that the type arguments are\ninferred, but in fact each type parameter's bound is used, which can lead\nto lost type information.\n\n**BAD:**\n```dart\nList list = [1, 2, 3];\n```\n\n**GOOD:**\n```dart\nList<int> list = [1, 2, 3];\n```",
"sinceDartSdk": "3.13"
},
{
"name": "no_runtimetype_tostring",
"description": "Avoid calling `toString()` on `runtimeType`.",
@@ -1590,11 +1629,11 @@
"languageFeatureUsage",
"style"
],
"state": "stable",
"state": "deprecated",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "From [Effective Dart](https://dart.dev/effective-dart/design#avoid-defining-a-one-member-abstract-class-when-a-simple-function-will-do):\n\n**AVOID** defining a one-member abstract class when a simple function will do.\n\nUnlike Java, Dart has first-class functions, closures, and a nice light syntax\nfor using them. If all you need is something like a callback, just use a\nfunction. If you're defining a class and it only has a single abstract member\nwith a meaningless name like `call` or `invoke`, there is a good chance\nyou just want a function.\n\n**BAD:**\n```dart\nabstract class Predicate {\n bool test(item);\n}\n```\n\n**GOOD:**\n```dart\ntypedef Predicate = bool Function(item);\n```",
"details": "**NOTE:** As one member abstracts are often a stepping stone,\nthis lint rule has been deprecated as of Dart 3.13 and is\nset to be removed in a future release of the Dart SDK.\nRemove all inclusions of this lint from your analysis options.\nIf you wish to keep enforcing it, consider implementing the\nrule with an [analyzer plugin](https://dart.dev/tools/analyzer-plugins).\n\nFrom [Effective Dart](https://dart.dev/effective-dart/design#avoid-defining-a-one-member-abstract-class-when-a-simple-function-will-do):\n\n**AVOID** defining a one-member abstract class when a simple function will do.\n\nUnlike Java, Dart has first-class functions, closures, and a nice light syntax\nfor using them. If all you need is something like a callback, just use a\nfunction. If you're defining a class and it only has a single abstract member\nwith a meaningless name like `call` or `invoke`, there is a good chance\nyou just want a function.\n\n**BAD:**\n```dart\nabstract class Predicate {\n bool test(item);\n}\n```\n\n**GOOD:**\n```dart\ntypedef Predicate = bool Function(item);\n```",
"sinceDartSdk": "2.0"
},
{
@@ -2686,7 +2725,7 @@
"brevity",
"style"
],
"state": "stable",
"state": "experimental",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
@@ -2916,6 +2955,20 @@
"details": "**AVOID** using parentheses when not needed.\n\n**BAD:**\n```dart\na = (b);\n```\n\n**GOOD:**\n```dart\na = b;\n```\n\nParentheses are considered unnecessary if they do not change the meaning of the\ncode and they do not improve the readability of the code. The goal is not to\nforce all developers to maintain the expression precedence table in their heads,\nwhich is why the second condition is included. Examples of this condition\ninclude:\n\n* cascade expressions - it is sometimes not clear what the target of a cascade\n expression is, especially with assignments, or nested cascades. For example,\n the expression `a.b = (c..d)`.\n* expressions with whitespace between tokens - it can look very strange to see\n an expression like `!await foo` which is valid and equivalent to\n `!(await foo)`.\n* logical expressions - parentheses can improve the readability of the implicit\n grouping defined by precedence. For example, the expression\n `(a && b) || c && d`.",
"sinceDartSdk": "2.0"
},
{
"name": "unnecessary_primary_constructor_body",
"description": "Unnecessary primary constructor bodies can be removed.",
"categories": [
"brevity",
"style"
],
"state": "experimental",
"incompatible": [],
"sets": [],
"fixStatus": "needsFix",
"details": "Don't include an empty primary constructor body.\n\n**BAD:**\n```dart\nclass C() {\n this;\n}\n```\n\n**GOOD:**\n```dart\nclass C();\n```",
"sinceDartSdk": "3.13"
},
{
"name": "unnecessary_raw_strings",
"description": "Unnecessary raw string.",
@@ -3397,7 +3450,7 @@
"categories": [
"languageFeatureUsage"
],
"state": "stable",
"state": "experimental",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",