Document some lint diagnostics
Change-Id: I38ba6f77a7d25e3f4716c2b2432b790c973c5650
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/390303
Reviewed-by: Phil Quitslund <pquitslund@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/test/services/completion/dart/declaration/record_type_test.dart b/pkg/analysis_server/test/services/completion/dart/declaration/record_type_test.dart
index 80027a7..68df403 100644
--- a/pkg/analysis_server/test/services/completion/dart/declaration/record_type_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/declaration/record_type_test.dart
@@ -60,6 +60,9 @@
toString
kind: methodInvocation
returnType: String
+ jsify
+ kind: methodInvocation
+ returnType: JSAny?
noSuchMethod
kind: methodInvocation
returnType: dynamic
@@ -94,6 +97,9 @@
toString
kind: methodInvocation
returnType: String
+ jsify
+ kind: methodInvocation
+ returnType: JSAny?
noSuchMethod
kind: methodInvocation
returnType: dynamic
@@ -130,6 +136,9 @@
foo
kind: methodInvocation
returnType: void
+ jsify
+ kind: methodInvocation
+ returnType: JSAny?
noSuchMethod
kind: methodInvocation
returnType: dynamic
@@ -160,6 +169,9 @@
toString
kind: methodInvocation
returnType: String
+ jsify
+ kind: methodInvocation
+ returnType: JSAny?
noSuchMethod
kind: methodInvocation
returnType: dynamic
@@ -190,6 +202,9 @@
toString
kind: methodInvocation
returnType: String
+ jsify
+ kind: methodInvocation
+ returnType: JSAny?
noSuchMethod
kind: methodInvocation
returnType: dynamic
@@ -220,6 +235,9 @@
toString
kind: methodInvocation
returnType: String
+ jsify
+ kind: methodInvocation
+ returnType: JSAny?
noSuchMethod
kind: methodInvocation
returnType: dynamic
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index 80a434b..121345e 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -1526,6 +1526,23 @@
extension type JSTypedArray._(TypedData _) implements JSObject {}
extension type JSUint8List._(Uint8List _) implements JSTypedArray {}
+
+extension JSAnyUtilityExtension on JSAny? {
+ external bool typeofEquals(String typeString);
+
+ external bool instanceof(JSFunction constructor);
+
+ bool instanceOfString(String constructorName) => false;
+
+ @Since('3.4')
+ external bool isA<T extends JSAny?>();
+
+ external Object? dartify();
+}
+
+extension NullableObjectUtilExtension on Object? {
+ external JSAny? jsify();
+}
''',
)
],
diff --git a/pkg/analyzer/test/verify_diagnostics_test.dart b/pkg/analyzer/test/verify_diagnostics_test.dart
index 73f1f2a..e18054f 100644
--- a/pkg/analyzer/test/verify_diagnostics_test.dart
+++ b/pkg/analyzer/test/verify_diagnostics_test.dart
@@ -112,6 +112,8 @@
// Doesn't produce a lint for the second example, even though the analyzer
// does when the example is pasted into a file.
'LintCode.prefer_inlined_adds_single',
+ // No mock 'test' package, no good library annotations in 'meta'.
+ 'LintCode.library_annotations',
// Produces an unused import diagnostic.
'LintCode.library_prefixes',
// Produces an unused element diagnostic.
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index 2e83d76..2f4097d 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -25993,6 +25993,77 @@
}
```
+### 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._
@@ -26046,6 +26117,43 @@
}
```
+### 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._
@@ -28251,6 +28359,59 @@
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._
@@ -28481,6 +28642,39 @@
}
```
+### 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._
@@ -29522,6 +29716,35 @@
}
```
+### 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._
diff --git a/pkg/linter/messages.yaml b/pkg/linter/messages.yaml
index 5242c2c..188e9122 100644
--- a/pkg/linter/messages.yaml
+++ b/pkg/linter/messages.yaml
@@ -4980,6 +4980,54 @@
addedIn: "3.5"
categories: [errorProne, web]
hasPublishedDocs: false
+ documentation: |-
+ #### 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>();
+ ```
deprecatedDetails: |-
**DON'T** use `is` checks where the type is a JS interop type.
@@ -5368,6 +5416,39 @@
addedIn: "2.19"
categories: [style]
hasPublishedDocs: false
+ documentation: |-
+ #### 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() {}
+ ```
deprecatedDetails: |-
Attach library annotations to library directives, rather than
some other library-level element.
@@ -11181,6 +11262,55 @@
addedIn: "3.5"
categories: [errorProne]
hasPublishedDocs: false
+ documentation: |-
+ #### 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) => '';
+ ```
deprecatedDetails: |-
**DON'T** use angle-bracketed text, `<…>`, in a doc comment unless you want to
write an HTML tag or link.
@@ -11777,6 +11907,35 @@
addedIn: "3.4"
categories: [brevity, languageFeatureUsage, style]
hasPublishedDocs: false
+ documentation: |-
+ #### 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.
deprecatedDetails: |-
**DON'T** have a library name in a `library` declaration.
@@ -13904,6 +14063,31 @@
addedIn: "3.6"
categories: [languageFeatureUsage]
hasPublishedDocs: false
+ documentation: |-
+ #### 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;
+ ```
deprecatedDetails: |-
**DO** use truncating division, '~/', instead of regular division ('/') followed
by 'toInt()'.