Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update for new core lint diagnostic docs #6159

Merged
merged 1 commit into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions src/_data/linter_rules.json
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,8 @@
"name": "avoid_futureor_void",
"description": "Avoid using 'FutureOr<void>' as the type of a result.",
"categories": [
"errorProne"
"errorProne",
"unintentional"
],
"state": "experimental",
"incompatible": [],
Expand Down Expand Up @@ -385,11 +386,11 @@
"categories": [
"style"
],
"state": "stable",
"state": "removed",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
"details": "**DON'T** check for `null` in custom `==` operators.\n\nAs `null` is a special value, no instance of any class (other than `Null`) can\nbe equivalent to it. Thus, it is redundant to check whether the other instance\nis `null`.\n\n**BAD:**\n```dart\nclass Person {\n final String? name;\n\n @override\n operator ==(Object? other) =>\n other != null && other is Person && name == other.name;\n}\n```\n\n**GOOD:**\n```dart\nclass Person {\n final String? name;\n\n @override\n operator ==(Object? other) => other is Person && name == other.name;\n}\n```",
"fixStatus": "noFix",
"details": "**DON'T** check for `null` in custom `==` operators.\n\nAs `null` is a special value, no instance of any class (other than `Null`) can\nbe equivalent to it. Thus, it is redundant to check whether the other instance\nis `null`.\n\n**BAD:**\n```dart\nclass Person {\n final String? name;\n\n @override\n operator ==(Object? other) =>\n other != null && other is Person && name == other.name;\n}\n```\n\n**GOOD:**\n```dart\nclass Person {\n final String? name;\n\n @override\n operator ==(Object? other) => other is Person && name == other.name;\n}\n```\n\nThis rule has been removed.",
"sinceDartSdk": "2.0"
},
{
Expand Down Expand Up @@ -757,7 +758,7 @@
"flutter"
],
"fixStatus": "noFix",
"details": "From [Effective Dart](https://dart.dev/effective-dart/style#do-name-extensions-using-uppercamelcase):\n\n**DO** name extensions using `UpperCamelCase`.\n\nExtensions should capitalize the first letter of each word (including\nthe first word), and use no separators.\n\n**GOOD:**\n```dart\nextension MyFancyList<T> on List<T> { \n // ... \n}\n\nextension SmartIterable<T> on Iterable<T> {\n // ...\n}\n```",
"details": "From [Effective Dart](https://dart.dev/effective-dart/style#do-name-extensions-using-uppercamelcase):\n\n**DO** name extensions using `UpperCamelCase`.\n\nExtensions should capitalize the first letter of each word (including\nthe first word), and use no separators.\n\n**GOOD:**\n```dart\nextension MyFancyList<T> on List<T> {\n // ...\n}\n\nextension SmartIterable<T> on Iterable<T> {\n // ...\n}\n```",
"sinceDartSdk": "2.6"
},
{
Expand Down Expand Up @@ -1760,11 +1761,11 @@
"effectiveDart",
"publicInterface"
],
"state": "stable",
"state": "deprecated",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "**DO** provide doc comments for all public APIs.\n\nAs described in the [pub package layout doc](https://dart.dev/tools/pub/package-layout#implementation-files),\npublic APIs consist in everything in your package's `lib` folder, minus\nimplementation files in `lib/src`, adding elements explicitly exported with an\n`export` directive.\n\nFor example, given `lib/foo.dart`:\n```dart\nexport 'src/bar.dart' show Bar;\nexport 'src/baz.dart';\n\nclass Foo { }\n\nclass _Foo { }\n```\nits API includes:\n\n* `Foo` (but not `_Foo`)\n* `Bar` (exported) and\n* all *public* elements in `src/baz.dart`\n\nAll public API members should be documented with `///` doc-style comments.\n\n**BAD:**\n```dart\nclass Bar {\n void bar();\n}\n```\n\n**GOOD:**\n```dart\n/// A Foo.\nabstract class Foo {\n /// Start foo-ing.\n void start() => _start();\n\n _start();\n}\n```\n\nAdvice for writing good doc comments can be found in the\n[Doc Writing Guidelines](https://dart.dev/effective-dart/documentation).",
"details": "**NOTE:** This lint is deprecated because it is has not\nbeen fully functional since at least Dart 2.0.\nRemove all inclusions of this lint from your analysis options.\n\n**DO** provide doc comments for all public APIs.\n\nAs described in the [pub package layout doc](https://dart.dev/tools/pub/package-layout#implementation-files),\npublic APIs consist in everything in your package's `lib` folder, minus\nimplementation files in `lib/src`, adding elements explicitly exported with an\n`export` directive.\n\nFor example, given `lib/foo.dart`:\n```dart\nexport 'src/bar.dart' show Bar;\nexport 'src/baz.dart';\n\nclass Foo { }\n\nclass _Foo { }\n```\nits API includes:\n\n* `Foo` (but not `_Foo`)\n* `Bar` (exported) and\n* all *public* elements in `src/baz.dart`\n\nAll public API members should be documented with `///` doc-style comments.\n\n**BAD:**\n```dart\nclass Bar {\n void bar();\n}\n```\n\n**GOOD:**\n```dart\n/// A Foo.\nabstract class Foo {\n /// Start foo-ing.\n void start() => _start();\n\n _start();\n}\n```\n\nAdvice for writing good doc comments can be found in the\n[Doc Writing Guidelines](https://dart.dev/effective-dart/documentation).",
"sinceDartSdk": "2.0"
},
{
Expand Down Expand Up @@ -2621,7 +2622,7 @@
],
"sets": [],
"fixStatus": "hasFix",
"details": "Do type annotate initialized local variables when the type is non-obvious.\n\nType annotations on local variables can serve as a request for type inference,\ndocumenting the expected outcome of the type inference step, and declaratively\nallowing the compiler and analyzer to solve the possibly complex task of\nfinding type arguments and annotations in the initializing expression that\nyield the desired result.\n\nType annotations on local variables can also inform readers about the type\nof the initializing expression, which will allow them to proceed reading the\nsubsequent lines of code with known good information about the type of the\ngiven variable (which may not be immediately evident by looking at the\ninitializing expression).\n\nAn expression is considered to have a non-obvious type when it does not\nhave an obvious type.\n\nAn expression e has an obvious type in the following cases:\n\n- e is a non-collection literal. For instance, 1, true, 'Hello, $name!'.\n- e is a collection literal with actual type arguments. For instance,\n <int, bool>{}.\n- e is a list literal or a set literal where at least one element has an\n obvious type, and all elements have the same type. For instance, [1, 2] and\n { [true, false], [] }, but not [1, 1.5].\n- e is a map literal where all key-value pair have a key with an obvious type\n and a value with an obvious type, and all keys have the same type, and all\n values have the same type. For instance, { #a: <int>[] }, but not\n {1: 1, 2: true}.\n- e is an instance creation expression whose class part is not raw. For\n instance C(14) if C is a non-generic class, or C<int>(14) if C accepts one\n type argument, but not C(14) if C accepts one or more type arguments.\n- e is a cascade whose target has an obvious type. For instance,\n 1..isEven..isEven has an obvious type because 1 has an obvious type.\n- e is a type cast. For instance, myComplexpression as int.\n\n**BAD:**\n```dart\nList<List<Ingredient>> possibleDesserts(Set<Ingredient> pantry) {\n var desserts = genericFunctionDeclaredFarAway(<num>[42], 'Something');\n for (final recipe in cookbook) {\n if (pantry.containsAll(recipe)) {\n desserts.add(recipe);\n }\n }\n\n return desserts;\n}\n\nconst List<List<Ingredient>> cookbook = ...;\n```\n\n**GOOD:**\n```dart\nList<List<Ingredient>> possibleDesserts(Set<Ingredient> pantry) {\n List<List<Ingredient>> desserts = genericFunctionDeclaredFarAway(\n <num>[42],\n 'Something',\n );\n for (final List<Ingredient> recipe in cookbook) {\n if (pantry.containsAll(recipe)) {\n desserts.add(recipe);\n }\n }\n\n return desserts;\n}\n\nconst List<List<Ingredient>> cookbook = ...;\n```\n\n**This rule is experimental.** It is being evaluated, and it may be changed\nor removed. Feedback on its behavior is welcome! The main issue is here:\nhttps://github.com/dart-lang/linter/issues/3480.",
"details": "Do type annotate initialized local variables when the type is non-obvious.\n\nType annotations on local variables can serve as a request for type inference,\ndocumenting the expected outcome of the type inference step, and declaratively\nallowing the compiler and analyzer to solve the possibly complex task of\nfinding type arguments and annotations in the initializing expression that\nyield the desired result.\n\nType annotations on local variables can also inform readers about the type\nof the initializing expression, which will allow them to proceed reading the\nsubsequent lines of code with known good information about the type of the\ngiven variable (which may not be immediately evident by looking at the\ninitializing expression).\n\nAn expression is considered to have a non-obvious type when it does not\nhave an obvious type.\n\nAn expression e has an obvious type in the following cases:\n\n- e is a non-collection literal. For instance, 1, true, 'Hello, $name!'.\n- e is a collection literal with actual type arguments. For instance,\n <int, bool>{}.\n- e is a list literal or a set literal where at least one element has an\n obvious type, and all elements have the same type. For instance, [1, 2] and\n { [true, false], [] }, but not [1, 1.5].\n- e is a map literal where all key-value pair have a key with an obvious type\n and a value with an obvious type, and all keys have the same type, and all\n values have the same type. For instance, { #a: <int>[] }, but not\n {1: 1, 2: true}.\n- e is an instance creation expression whose class part is not raw. For\n instance C(14) if C is a non-generic class, or C<int>(14) if C accepts one\n type argument, but not C(14) if C accepts one or more type arguments.\n- e is a cascade whose target has an obvious type. For instance,\n 1..isEven..isEven has an obvious type because 1 has an obvious type.\n- e is a type cast. For instance, myComplexExpression as int.\n\n**BAD:**\n```dart\nList<List<Ingredient>> possibleDesserts(Set<Ingredient> pantry) {\n var desserts = genericFunctionDeclaredFarAway(<num>[42], 'Something');\n for (final recipe in cookbook) {\n if (pantry.containsAll(recipe)) {\n desserts.add(recipe);\n }\n }\n\n return desserts;\n}\n\nconst List<List<Ingredient>> cookbook = ...;\n```\n\n**GOOD:**\n```dart\nList<List<Ingredient>> possibleDesserts(Set<Ingredient> pantry) {\n List<List<Ingredient>> desserts = genericFunctionDeclaredFarAway(\n <num>[42],\n 'Something',\n );\n for (final List<Ingredient> recipe in cookbook) {\n if (pantry.containsAll(recipe)) {\n desserts.add(recipe);\n }\n }\n\n return desserts;\n}\n\nconst List<List<Ingredient>> cookbook = ...;\n```\n\n**This rule is experimental.** It is being evaluated, and it may be changed\nor removed. Feedback on its behavior is welcome! The main issue is here:\nhttps://github.com/dart-lang/linter/issues/3480.",
"sinceDartSdk": "3.6-wip"
},
{
Expand Down
228 changes: 228 additions & 0 deletions src/content/tools/diagnostic-messages.md
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,9 @@ export 'b.dart' hide C;

### ambiguous_extension_member_access

_A member named '{0}' is defined in '{1}' and '{2}', and neither is more
specific._

_A member named '{0}' is defined in {1}, and none are more specific._

#### Description
Expand Down Expand Up @@ -25962,6 +25965,77 @@ void f() {
}
```

### invalid_runtime_check_with_js_interop_types

_Cast from '{0}' to '{1}' casts a Dart value to a JS interop type, which might
not be platform-consistent._

_Cast from '{0}' to '{1}' casts a JS interop value to a Dart type, which might
not be platform-consistent._

_Cast from '{0}' to '{1}' casts a JS interop value to an incompatible JS interop
type, which might not be platform-consistent._

_Runtime check between '{0}' and '{1}' checks whether a Dart value is a JS
interop type, which might not be platform-consistent._

_Runtime check between '{0}' and '{1}' checks whether a JS interop value is a
Dart type, which might not be platform-consistent._

_Runtime check between '{0}' and '{1}' involves a non-trivial runtime check
between two JS interop types that might not be platform-consistent._

_Runtime check between '{0}' and '{1}' involves a runtime check between a JS
interop value and an unrelated JS interop type that will always be true and won't check the underlying type._

#### Description

The analyzer produces this diagnostic when an `is` test has either
- a JS interop type on the right-hand side, whether directly or as a type
argument to another type, or
- a JS interop value on the left-hand side.

#### Examples

The following code produces this diagnostic because the JS interop type
`JSBoolean` is on the right-hand side of an `is` test:

```dart
import 'dart:js_interop';

bool f(Object b) => [!b is JSBoolean!];
```

The following code produces this diagnostic because the JS interop type
`JSString` is used as a type argument on the right-hand side of an `is`
test:

```dart
import 'dart:js_interop';

bool f(List<Object> l) => [!l is List<JSString>!];
```

The following code produces this diagnostic because the JS interop value
`a` is on the left-hand side of an `is` test:

```dart
import 'dart:js_interop';

bool f(JSAny a) => [!a is String!];
```

#### Common fixes

Use a JS interop helper, such as `isA`, to check the underlying type of
JS interop values:

```dart
import 'dart:js_interop';

void f(Object b) => b.jsify()?.isA<JSBoolean>();
```

### invalid_use_of_do_not_submit_member

_Uses of '{0}' should not be submitted to source control._
Expand Down Expand Up @@ -26015,6 +26089,43 @@ void emulateCrashWithOtherFunctionality() {
}
```

### library_annotations

_This annotation should be attached to a library directive._

#### Description

The analyzer produces this diagnostic when an annotation that applies to
a whole library isn't associated with a `library` directive.

#### Example

The following code produces this diagnostic because the `TestOn`
annotation, which applies to the whole library, is associated with an
`import` directive rather than a `library` directive:

```dart
[!@TestOn('browser')!]

import 'package:test/test.dart';

void main() {}
```

#### Common fixes

Associate the annotation with a `library` directive, adding one if
necessary:

```dart
@TestOn('browser')
library;

import 'package:test/test.dart';

void main() {}
```

### library_names

_The library name '{0}' isn't a lower\_case\_with\_underscores identifier._
Expand Down Expand Up @@ -26402,6 +26513,7 @@ The following code produces this diagnostic because the name of the
parameter consists of two underscores:

```dart
// @dart = 3.6
void f(int __) {
print([!__!]);
}
Expand All @@ -26411,6 +26523,7 @@ The following code produces this diagnostic because the name of the
local variable consists of a single underscore:

```dart
// @dart = 3.6
void f() {
int _ = 0;
print([!_!]);
Expand Down Expand Up @@ -28218,6 +28331,59 @@ Future<void> f() async {
Future<int> g() => Future.value(0);
```

### unintended_html_in_doc_comment

_Angle brackets will be interpreted as HTML._

#### Description

The analyzer produces this diagnostic when a documentation comment
contains angle bracketed text (`<...>`) that isn't one of the allowed
exceptions.

Such text is interpreted by markdown to be an HTML tag, which is rarely
what was intended.

See the [lint rule description](https://dart.dev/tools/linter-rules/unintended_html_in_doc_comment)
for the list of allowed exceptions.

#### Example

The following code produces this diagnostic because the documentation
comment contains the text `<int>`, which isn't one of the allowed
exceptions:

```dart
/// Converts a List[!<int>!] to a comma-separated String.
String f(List<int> l) => '';
```

#### Common fixes

If the text was intended to be part of a code span, then add backticks
around the code:

```dart
/// Converts a `List<int>` to a comma-separated String.
String f(List<int> l) => '';
```

If the text was intended to be part of a link, then add square brackets
around the code:

```dart
/// Converts a [List<int>] to a comma-separated String.
String f(List<int> l) => '';
```

If the text was intended to be printed as-is, including the angle
brackets, then add backslash escapes before the angle brackets:

```dart
/// Converts a List\<int\> to a comma-separated String.
String f(List<int> l) => '';
```

### unnecessary_brace_in_string_interps

_Unnecessary braces in a string interpolation._
Expand Down Expand Up @@ -28448,6 +28614,39 @@ class C {
}
```

### unnecessary_library_name

_Library names are not necessary._

#### Description

The analyzer produces this diagnostic when a `library` directive specifies
a name.

#### Example

The following code produces this diagnostic because the `library`
directive includes a name:

```dart
library [!some.name!];

class C {}
```

#### Common fixes

Remove the name from the `library` directive:

```dart
library;

class C {}
```

If the library has any parts, then any `part of` declarations that use
the library name should be updated to use the URI of the library instead.

### unnecessary_new

_Unnecessary 'new' keyword._
Expand Down Expand Up @@ -29489,6 +29688,35 @@ class B extends A {
}
```

### use_truncating_division

_Use truncating division._

#### Description

The analyzer produces this diagnostic when the result of dividing two
numbers is converted to an integer using `toInt`.

Dart has a built-in integer division operator that is both more efficient
and more concise.

#### Example

The following code produces this diagnostic because the result of dividing
`x` and `y` is converted to an integer using `toInt`:

```dart
int divide(int x, int y) => [!(x / y).toInt()!];
```

#### Common fixes

Use the integer division operator (`~/`):

```dart
int divide(int x, int y) => x ~/ y;
```

### valid_regexps

_Invalid regular expression syntax._
Expand Down