From 72d91da9b123f47a9b2b71f98f35f77dd84b2c15 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Tue, 19 Sep 2023 11:21:06 -0500 Subject: [PATCH] Update to latest diagnostic messages and linter rule docs (#5200) --- src/_data/linter_rules.json | 21 ++++++++++++++++----- src/tools/diagnostic-messages.md | 27 ++++++++++++++++----------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/_data/linter_rules.json b/src/_data/linter_rules.json index 2c29fb2e73..d59dbe590e 100644 --- a/src/_data/linter_rules.json +++ b/src/_data/linter_rules.json @@ -259,7 +259,7 @@ "incompatible": [], "sets": [], "fixStatus": "hasFix", - "details": "Using an `interface`, `base`, `final`, or `sealed` modifier on a class,\nor a `base` modifier on a mixin,\nauthors can control whether classes and mixins allow being implemented,\nextended, and/or mixed in from outside of the library where they're defined.\nIn some cases, it's possible for an author to inadvertently relax these controls\nand implicitly \"reopen\" a class. (A similar reopening cannot occur with a mixin.)\n\nThis lint guards against unintentionally reopening a class by requiring such\ncases to be made explicit with the \n[`@reopen`](https://pub.dev/documentation/meta/latest/meta/reopen-constant.html)\nannotation in `package:meta`.\n\n**BAD:**\n```dart\ninterface class I {}\n\nclass C extends I {} // LINT\n```\n\n**GOOD:**\n```dart\ninterface class I {}\n\nfinal class C extends I {}\n```\n\n```dart\nimport 'package:meta/meta.dart';\n\ninterface class I {}\n\n@reopen\nclass C extends I {}\n```\n", + "details": "Using an `interface`, `base`, `final`, or `sealed` modifier on a class,\nor a `base` modifier on a mixin,\nauthors can control whether classes and mixins allow being implemented,\nextended, and/or mixed in from outside of the library where they're defined.\nIn some cases, it's possible for an author to inadvertently relax these controls\nand implicitly \"reopen\" a class. (A similar reopening cannot occur with a mixin.)\n\nThis lint guards against unintentionally reopening a class by requiring such\ncases to be made explicit with the\n[`@reopen`](https://pub.dev/documentation/meta/latest/meta/reopen-constant.html)\nannotation in `package:meta`.\n\n**BAD:**\n```dart\ninterface class I {}\n\nclass C extends I {} // LINT\n```\n\n**GOOD:**\n```dart\ninterface class I {}\n\nfinal class C extends I {}\n```\n\n```dart\nimport 'package:meta/meta.dart';\n\ninterface class I {}\n\n@reopen\nclass C extends I {}\n```\n", "sinceDartSdk": "3.0.0" }, { @@ -628,6 +628,17 @@ "details": "**DO** annotate overridden methods and fields.\n\nThis practice improves code readability and helps protect against\nunintentionally overriding superclass members.\n\n**BAD:**\n```dart\nclass Cat {\n int get lives => 9;\n}\n\nclass Lucky extends Cat {\n final int lives = 14;\n}\n```\n\n**GOOD:**\n```dart\nabstract class Dog {\n String get breed;\n void bark() {}\n}\n\nclass Husky extends Dog {\n @override\n final String breed = 'Husky';\n @override\n void bark() {}\n}\n```\n\n", "sinceDartSdk": "2.0.0" }, + { + "name": "annotate_redeclares", + "description": "Annotate redeclared members.", + "group": "style", + "state": "experimental", + "incompatible": [], + "sets": [], + "fixStatus": "hasFix", + "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```\n", + "sinceDartSdk": "Unreleased" + }, { "name": "avoid_annotating_with_dynamic", "description": "Avoid annotating with dynamic when not required.", @@ -1459,7 +1470,7 @@ "incompatible": [], "sets": [], "fixStatus": "noFix", - "details": "Calling `toString` on a runtime type is a non-trivial operation that can\nnegatively impact performance. It's better to avoid it.\n\n**BAD:**\n```dart\nclass A {\n String toString() => '$runtimeType()';\n}\n```\n\n**GOOD:**\n```dart\nclass A {\n String toString() => 'A()';\n}\n```\n\nThis lint has some exceptions where performance is not a problem or where real\ntype information is more important than performance:\n\n* in assertion\n* in throw expressions\n* in catch clauses\n* in mixin declaration\n* in abstract class\n\n", + "details": "Calling `toString` on a runtime type is a non-trivial operation that can\nnegatively impact performance. It's better to avoid it.\n\n**BAD:**\n```dart\nclass A {\n String toString() => '$runtimeType()';\n}\n```\n\n**GOOD:**\n```dart\nclass A {\n String toString() => 'A()';\n}\n```\n\nThis lint has some exceptions where performance is not a problem or where real\ntype information is more important than performance:\n\n* in an assertion\n* in a throw expression\n* in a catch clause\n* in a mixin declaration\n* in an abstract class declaration\n\n", "sinceDartSdk": "2.8.1" }, { @@ -1661,7 +1672,7 @@ "flutter" ], "fixStatus": "hasFix", - "details": "**DO** use collection literals when possible.\n\n**BAD:**\n```dart\nvar addresses = Map();\nvar uniqueNames = Set();\nvar ids = LinkedHashSet();\nvar coordinates = LinkedHashMap();\n```\n\n**GOOD:**\n```dart\nvar addresses = {};\nvar uniqueNames = {};\nvar ids = {};\nvar coordinates = {};\n```\n\n**EXCEPTIONS:**\n\nThere are cases with `LinkedHashSet` or `LinkedHashMap` where a literal constructor\nwill trigger a type error so those will be excluded from the lint.\n\n```dart\nvoid main() {\n LinkedHashSet linkedHashSet = LinkedHashSet.from([1, 2, 3]); // OK\n LinkedHashMap linkedHashMap = LinkedHashMap(); // OK\n \n printSet(LinkedHashSet()); // LINT\n printHashSet(LinkedHashSet()); // OK\n\n printMap(LinkedHashMap()); // LINT\n printHashMap(LinkedHashMap()); // OK\n}\n\nvoid printSet(Set ids) => print('$ids!');\nvoid printHashSet(LinkedHashSet ids) => printSet(ids);\nvoid printMap(Map map) => print('$map!');\nvoid printHashMap(LinkedHashMap map) => printMap(map);\n```\n", + "details": "**DO** use collection literals when possible.\n\n**BAD:**\n```dart\nvar addresses = Map();\nvar uniqueNames = Set();\nvar ids = LinkedHashSet();\nvar coordinates = LinkedHashMap();\n```\n\n**GOOD:**\n```dart\nvar addresses = {};\nvar uniqueNames = {};\nvar ids = {};\nvar coordinates = {};\n```\n\n**EXCEPTIONS:**\n\nWhen a `LinkedHashSet` or `LinkedHashMap` is expected, a collection literal is\nnot preferred (or allowed).\n\n```dart\nvoid main() {\n LinkedHashSet linkedHashSet = LinkedHashSet.from([1, 2, 3]); // OK\n LinkedHashMap linkedHashMap = LinkedHashMap(); // OK\n \n printSet(LinkedHashSet()); // LINT\n printHashSet(LinkedHashSet()); // OK\n\n printMap(LinkedHashMap()); // LINT\n printHashMap(LinkedHashMap()); // OK\n}\n\nvoid printSet(Set ids) => print('$ids!');\nvoid printHashSet(LinkedHashSet ids) => printSet(ids);\nvoid printMap(Map map) => print('$map!');\nvoid printHashMap(LinkedHashMap map) => printMap(map);\n```\n", "sinceDartSdk": "2.0.0" }, { @@ -2186,7 +2197,7 @@ "incompatible": [], "sets": [], "fixStatus": "needsFix", - "details": "Use `SizedBox.shrink(...)` and `SizedBox.expand(...)` constructors appropriately.\n\nThe `SizedBox.shrink(...)` and `SizedBox.expand(...)` constructors should be used\ninstead of the more general `SizedBox(...)` constructor when the named constructors\ncapture the intent of the code more succinctly.\n\n**Examples**\n\n**BAD:**\n```dart\nWidget buildLogo() {\n return SizedBox(\n height: 0,\n width: 0,\n child: const MyLogo(),\n );\n}\n```\n\n```dart\nWidget buildLogo() {\n return SizedBox(\n height: double.infinity,\n width: double.infinity,\n child: const MyLogo(),\n );\n}\n```\n\n**GOOD:**\n```dart\nWidget buildLogo() {\n return SizedBox.shrink(\n child: const MyLogo(),\n );\n}\n```\n\n```dart\nWidget buildLogo() {\n return SizedBox.expand(\n child: const MyLogo(),\n );\n}\n```\n", + "details": "Use `SizedBox.shrink(...)` and `SizedBox.expand(...)` constructors\nappropriately.\n\nEither the `SizedBox.shrink(...)` or `SizedBox.expand(...)` constructor should\nbe used instead of the more general `SizedBox(...)` constructor when one of the\nnamed constructors capture the intent of the code more succinctly.\n\n**Examples**\n\n**BAD:**\n```dart\nWidget buildLogo() {\n return SizedBox(\n height: 0,\n width: 0,\n child: const MyLogo(),\n );\n}\n```\n\n```dart\nWidget buildLogo() {\n return SizedBox(\n height: double.infinity,\n width: double.infinity,\n child: const MyLogo(),\n );\n}\n```\n\n**GOOD:**\n```dart\nWidget buildLogo() {\n return SizedBox.shrink(\n child: const MyLogo(),\n );\n}\n```\n\n```dart\nWidget buildLogo() {\n return SizedBox.expand(\n child: const MyLogo(),\n );\n}\n```\n", "sinceDartSdk": "2.16.0" }, { @@ -2644,7 +2655,7 @@ "incompatible": [], "sets": [], "fixStatus": "hasFix", - "details": "Classes that look like enumerations should be declared as `enum`s.\n\n**DO** use enums where appropriate.\n\nCandidates for enums are classes that:\n * are concrete,\n * are private or have only private generative constructors,\n * have two or more static const fields with the same type as the class,\n * have generative constructors that are only invoked at the top-level of the\n initialization expression of these static fields,\n * do not define `hashCode`, `==`, `values` or `index`,\n * do not extend any class other than Object, and\n * have no subclasses declared in the defining library.\n\n**BAD:**\n```dart\nclass LogPriority {\n static const error = LogPriority._(1, 'Error');\n static const warning = LogPriority._(2, 'Warning');\n static const log = LogPriority._unknown('Log');\n\n final String prefix;\n final int priority;\n const LogPriority._(this.priority, this.prefix);\n const LogPriority._unknown(String prefix) : this._(-1, prefix);\n}\n```\n\n**GOOD:**\n```dart\nenum LogPriority {\n error(1, 'Error'),\n warning(2, 'Warning'),\n log.unknown('Log');\n\n final String prefix;\n final int priority;\n const LogPriority(this.priority, this.prefix);\n const LogPriority.unknown(String prefix) : this(-1, prefix);\n}\n```\n", + "details": "Classes that look like enumerations should be declared as `enum`s.\n\n**DO** use enums where appropriate.\n\nCandidates for enums are classes that:\n\n * are concrete,\n * are private or have only private generative constructors,\n * have two or more static const fields with the same type as the class,\n * have generative constructors that are only invoked at the top-level of the\n initialization expression of these static fields,\n * do not define `hashCode`, `==`, `values` or `index`,\n * do not extend any class other than `Object`, and\n * have no subclasses declared in the defining library.\n\nTo learn more about creating and using these enums, check out\n[Declaring enhanced enums](https://dart.dev/language/enums#declaring-enhanced-enums).\n\n**BAD:**\n```dart\nclass LogPriority {\n static const error = LogPriority._(1, 'Error');\n static const warning = LogPriority._(2, 'Warning');\n static const log = LogPriority._unknown('Log');\n\n final String prefix;\n final int priority;\n const LogPriority._(this.priority, this.prefix);\n const LogPriority._unknown(String prefix) : this._(-1, prefix);\n}\n```\n\n**GOOD:**\n```dart\nenum LogPriority {\n error(1, 'Error'),\n warning(2, 'Warning'),\n log.unknown('Log');\n\n final String prefix;\n final int priority;\n const LogPriority(this.priority, this.prefix);\n const LogPriority.unknown(String prefix) : this(-1, prefix);\n}\n```\n", "sinceDartSdk": "2.17.0" }, { diff --git a/src/tools/diagnostic-messages.md b/src/tools/diagnostic-messages.md index ae53c679a9..8eccb11074 100644 --- a/src/tools/diagnostic-messages.md +++ b/src/tools/diagnostic-messages.md @@ -726,7 +726,8 @@ The analyzer produces this diagnostic when an invocation of either argument whose value isn't a constant expression. The analyzer also produces this diagnostic when the value of the -`exceptionalReturn` argument of `Pointer.fromFunction`. +`exceptionalReturn` argument of `Pointer.fromFunction` or +`NativeCallable.isolateLocal`. For more information about FFI, see [C interop using dart:ffi][ffi]. @@ -8907,13 +8908,14 @@ dependencies: ### invalid_exception_value -_The method 'Pointer.fromFunction' can't have an exceptional return value (the -second argument) when the return type of the function is either 'void', 'Handle' or 'Pointer'._ +_The method {0} can't have an exceptional return value (the second argument) +when the return type of the function is either 'void', 'Handle' or 'Pointer'._ #### Description The analyzer produces this diagnostic when an invocation of the method -`Pointer.fromFunction` has a second argument (the exceptional return +`Pointer.fromFunction` or `NativeCallable.isolateLocal` +has a second argument (the exceptional return value) and the type to be returned from the invocation is either `void`, `Handle` or `Pointer`. @@ -10269,8 +10271,8 @@ _Invalid reference to 'this' expression._ The analyzer produces this diagnostic when `this` is used outside of an instance method or a generative constructor. The reserved word `this` is -only defined in the context of an instance method or a generative -constructor. +only defined in the context of an instance method, a generative +constructor, or the initializer of a late instance field declaration. #### Example @@ -11898,13 +11900,14 @@ void f(E e) { ### missing_exception_value -_The method 'Pointer.fromFunction' must have an exceptional return value (the -second argument) when the return type of the function is neither 'void', 'Handle', nor 'Pointer'._ +_The method {0} must have an exceptional return value (the second argument) when +the return type of the function is neither 'void', 'Handle', nor 'Pointer'._ #### Description The analyzer produces this diagnostic when an invocation of the method -`Pointer.fromFunction` doesn't have a second argument (the exceptional +`Pointer.fromFunction` or `NativeCallable.isolateLocal` +doesn't have a second argument (the exceptional return value) when the type to be returned from the invocation is neither `void`, `Handle`, nor `Pointer`. @@ -13022,7 +13025,8 @@ _The type '{0}' given to '{1}' must be a valid 'dart:ffi' native function type._ #### Description The analyzer produces this diagnostic when an invocation of either -`Pointer.fromFunction` or `DynamicLibrary.lookupFunction` has a type +`Pointer.fromFunction`, `DynamicLibrary.lookupFunction`, +or a `NativeCallable` constructor, has a type argument(whether explicit or inferred) that isn't a native function type. For more information about FFI, see [C interop using dart:ffi][ffi]. @@ -13068,7 +13072,8 @@ _The type '{0}' must be a subtype of '{1}' for '{2}'._ #### Description The analyzer produces this diagnostic in two cases: -- In an invocation of `Pointer.fromFunction` where the type argument +- In an invocation of `Pointer.fromFunction`, or a + `NativeCallable` constructor where the type argument (whether explicit or inferred) isn't a supertype of the type of the function passed as the first argument to the method. - In an invocation of `DynamicLibrary.lookupFunction` where the first type