analyzer: Add a 'public interface' lint rule category

Work towards https://github.com/dart-lang/linter/issues/4991

I also fix a number of incorrect categorizations, and add some
Effective Dart links. This CR makes the total 25 Effective Dart-backed
lint rules.

Cq-Include-Trybots: luci.dart.try:flutter-analyze-try,analyzer-win-release-try,pkg-win-release-try
Change-Id: I2765bb525eb2833e4e8954dc185d2c9b3dd357e6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/375722
Commit-Queue: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/lib/src/lint/linter.dart b/pkg/analyzer/lib/src/lint/linter.dart
index 09202ad..ea4d094b 100644
--- a/pkg/analyzer/lib/src/lint/linter.dart
+++ b/pkg/analyzer/lib/src/lint/linter.dart
@@ -71,6 +71,9 @@
   /// A category representing Pub-related rules.
   static const String pub = 'pub';
 
+  /// A category of rules that promote a healthy public interface.
+  static const String publicInterface = 'public interface';
+
   /// A category representing matters of style, largely derived from Effective
   /// Dart.
   static const String style = 'style';
diff --git a/pkg/linter/lib/src/rules/avoid_catches_without_on_clauses.dart b/pkg/linter/lib/src/rules/avoid_catches_without_on_clauses.dart
index 25d5b86..be6e81b 100644
--- a/pkg/linter/lib/src/rules/avoid_catches_without_on_clauses.dart
+++ b/pkg/linter/lib/src/rules/avoid_catches_without_on_clauses.dart
@@ -13,6 +13,8 @@
 const _desc = r'Avoid catches without on clauses.';
 
 const _details = r'''
+From [Effective Dart](https://dart.dev/effective-dart/usage#avoid-catches-without-on-clauses):
+
 **AVOID** catches without on clauses.
 
 Using catch clauses without on clauses make your code prone to encountering
@@ -63,7 +65,7 @@
             name: 'avoid_catches_without_on_clauses',
             description: _desc,
             details: _details,
-            categories: {Category.style});
+            categories: {Category.effectiveDart, Category.style});
 
   @override
   LintCode get lintCode => code;
diff --git a/pkg/linter/lib/src/rules/avoid_classes_with_only_static_members.dart b/pkg/linter/lib/src/rules/avoid_classes_with_only_static_members.dart
index 0290018..a09de7e 100644
--- a/pkg/linter/lib/src/rules/avoid_classes_with_only_static_members.dart
+++ b/pkg/linter/lib/src/rules/avoid_classes_with_only_static_members.dart
@@ -56,7 +56,11 @@
             name: 'avoid_classes_with_only_static_members',
             description: _desc,
             details: _details,
-            categories: {Category.effectiveDart, Category.style});
+            categories: {
+              Category.effectiveDart,
+              Category.languageFeatureUsage,
+              Category.style,
+            });
 
   @override
   LintCode get lintCode => code;
diff --git a/pkg/linter/lib/src/rules/avoid_field_initializers_in_const_classes.dart b/pkg/linter/lib/src/rules/avoid_field_initializers_in_const_classes.dart
index 4301612..9e489af 100644
--- a/pkg/linter/lib/src/rules/avoid_field_initializers_in_const_classes.dart
+++ b/pkg/linter/lib/src/rules/avoid_field_initializers_in_const_classes.dart
@@ -44,11 +44,13 @@
           'Try converting the field to a getter or initialize the field in the '
           'constructors.');
 
-  AvoidFieldInitializersInConstClasses()
-      : super(
+  AvoidFieldInitializersInConstClasses() : super(
             name: 'avoid_field_initializers_in_const_classes',
             description: _desc,
             details: _details,
+            // TODO(srawlins): This rule has nothing to do with style. It is to
+            // reduce runtime memory usage. But we don't have a Category for
+            // that yet.
             categories: {Category.style});
 
   @override
diff --git a/pkg/linter/lib/src/rules/avoid_positional_boolean_parameters.dart b/pkg/linter/lib/src/rules/avoid_positional_boolean_parameters.dart
index eb28b5f..8a6e50f1 100644
--- a/pkg/linter/lib/src/rules/avoid_positional_boolean_parameters.dart
+++ b/pkg/linter/lib/src/rules/avoid_positional_boolean_parameters.dart
@@ -14,6 +14,8 @@
 const _desc = r'Avoid positional boolean parameters.';
 
 const _details = r'''
+From [Effective Dart](https://dart.dev/effective-dart/design#avoid-positional-boolean-parameters):
+
 **AVOID** positional boolean parameters.
 
 Positional boolean parameters are a bad practice because they are very
@@ -48,7 +50,7 @@
             name: 'avoid_positional_boolean_parameters',
             description: _desc,
             details: _details,
-            categories: {Category.style});
+            categories: {Category.effectiveDart, Category.style});
 
   @override
   LintCode get lintCode => code;
diff --git a/pkg/linter/lib/src/rules/avoid_unused_constructor_parameters.dart b/pkg/linter/lib/src/rules/avoid_unused_constructor_parameters.dart
index 703062b..4086f39 100644
--- a/pkg/linter/lib/src/rules/avoid_unused_constructor_parameters.dart
+++ b/pkg/linter/lib/src/rules/avoid_unused_constructor_parameters.dart
@@ -37,12 +37,13 @@
       "The parameter '{0}' is not used in the constructor.",
       correctionMessage: 'Try using the parameter or removing it.');
 
-  AvoidUnusedConstructorParameters()
-      : super(
+  AvoidUnusedConstructorParameters() : super(
             name: 'avoid_unused_constructor_parameters',
             description: _desc,
             details: _details,
-            categories: {Category.style});
+            // TODO(srawlins): This isn't even just about unintentional syntax;
+            // unused parameters can represent code bloat.
+            categories: {Category.unintentional});
 
   @override
   LintCode get lintCode => code;
diff --git a/pkg/linter/lib/src/rules/cascade_invocations.dart b/pkg/linter/lib/src/rules/cascade_invocations.dart
index 967b93f..23a9e97 100644
--- a/pkg/linter/lib/src/rules/cascade_invocations.dart
+++ b/pkg/linter/lib/src/rules/cascade_invocations.dart
@@ -115,7 +115,7 @@
             name: 'cascade_invocations',
             description: _desc,
             details: _details,
-            categories: {Category.style});
+            categories: {Category.languageFeatureUsage, Category.style});
 
   @override
   LintCode get lintCode => code;
diff --git a/pkg/linter/lib/src/rules/exhaustive_cases.dart b/pkg/linter/lib/src/rules/exhaustive_cases.dart
index ff21bc9..68baf8f 100644
--- a/pkg/linter/lib/src/rules/exhaustive_cases.dart
+++ b/pkg/linter/lib/src/rules/exhaustive_cases.dart
@@ -84,7 +84,7 @@
             name: 'exhaustive_cases',
             description: _desc,
             details: _details,
-            categories: {Category.style});
+            categories: {Category.errorProne});
 
   @override
   LintCode get lintCode => code;
diff --git a/pkg/linter/lib/src/rules/library_private_types_in_public_api.dart b/pkg/linter/lib/src/rules/library_private_types_in_public_api.dart
index e0b7781..e05ff99 100644
--- a/pkg/linter/lib/src/rules/library_private_types_in_public_api.dart
+++ b/pkg/linter/lib/src/rules/library_private_types_in_public_api.dart
@@ -54,7 +54,7 @@
             name: 'library_private_types_in_public_api',
             description: _desc,
             details: _details,
-            categories: {Category.style});
+            categories: {Category.publicInterface});
 
   @override
   LintCode get lintCode => code;
diff --git a/pkg/linter/lib/src/rules/one_member_abstracts.dart b/pkg/linter/lib/src/rules/one_member_abstracts.dart
index 1cddd89..6deaabf 100644
--- a/pkg/linter/lib/src/rules/one_member_abstracts.dart
+++ b/pkg/linter/lib/src/rules/one_member_abstracts.dart
@@ -47,7 +47,11 @@
             name: 'one_member_abstracts',
             description: _desc,
             details: _details,
-            categories: {Category.effectiveDart, Category.style});
+            categories: {
+              Category.effectiveDart,
+              Category.languageFeatureUsage,
+              Category.style,
+            });
 
   @override
   LintCode get lintCode => code;
diff --git a/pkg/linter/lib/src/rules/package_api_docs.dart b/pkg/linter/lib/src/rules/package_api_docs.dart
index 3d25f43..d01b8fb 100644
--- a/pkg/linter/lib/src/rules/package_api_docs.dart
+++ b/pkg/linter/lib/src/rules/package_api_docs.dart
@@ -67,7 +67,7 @@
             name: 'package_api_docs',
             description: _desc,
             details: _details,
-            categories: {Category.effectiveDart, Category.style});
+            categories: {Category.effectiveDart, Category.publicInterface});
 
   @override
   LintCode get lintCode => code;
diff --git a/pkg/linter/lib/src/rules/prefer_final_fields.dart b/pkg/linter/lib/src/rules/prefer_final_fields.dart
index 5b9d581..2dbebb4 100644
--- a/pkg/linter/lib/src/rules/prefer_final_fields.dart
+++ b/pkg/linter/lib/src/rules/prefer_final_fields.dart
@@ -13,6 +13,8 @@
 const _desc = r'Private field could be `final`.';
 
 const _details = r'''
+From [Effective Dart](https://dart.dev/effective-dart/design#prefer-making-fields-and-top-level-variables-final):
+
 **DO** prefer declaring private fields as `final` if they are not reassigned
 later in the library.
 
@@ -92,7 +94,7 @@
             name: 'prefer_final_fields',
             description: _desc,
             details: _details,
-            categories: {Category.style});
+            categories: {Category.effectiveDart, Category.style});
 
   @override
   LintCode get lintCode => code;
diff --git a/pkg/linter/lib/src/rules/prefer_function_declarations_over_variables.dart b/pkg/linter/lib/src/rules/prefer_function_declarations_over_variables.dart
index e191116..9208715 100644
--- a/pkg/linter/lib/src/rules/prefer_function_declarations_over_variables.dart
+++ b/pkg/linter/lib/src/rules/prefer_function_declarations_over_variables.dart
@@ -10,6 +10,8 @@
 const _desc = r'Use a function declaration to bind a function to a name.';
 
 const _details = r'''
+From [Effective Dart](https://dart.dev/effective-dart/usage#do-use-a-function-declaration-to-bind-a-function-to-a-name):
+
 **DO** use a function declaration to bind a function to a name.
 
 As Dart allows local function declarations, it is a good practice to use them in
@@ -49,7 +51,7 @@
             name: 'prefer_function_declarations_over_variables',
             description: _desc,
             details: _details,
-            categories: {Category.style});
+            categories: {Category.effectiveDart, Category.style});
 
   @override
   LintCode get lintCode => code;
diff --git a/pkg/linter/lib/src/rules/prefer_mixin.dart b/pkg/linter/lib/src/rules/prefer_mixin.dart
index fc6d521..d392fcd 100644
--- a/pkg/linter/lib/src/rules/prefer_mixin.dart
+++ b/pkg/linter/lib/src/rules/prefer_mixin.dart
@@ -41,7 +41,7 @@
             name: 'prefer_mixin',
             description: _desc,
             details: _details,
-            categories: {Category.style});
+            categories: {Category.languageFeatureUsage, Category.style});
 
   @override
   LintCode get lintCode => code;
diff --git a/pkg/linter/lib/src/rules/provide_deprecation_message.dart b/pkg/linter/lib/src/rules/provide_deprecation_message.dart
index 6feeb2e..58618b5 100644
--- a/pkg/linter/lib/src/rules/provide_deprecation_message.dart
+++ b/pkg/linter/lib/src/rules/provide_deprecation_message.dart
@@ -43,7 +43,7 @@
             name: 'provide_deprecation_message',
             description: _desc,
             details: _details,
-            categories: {Category.style});
+            categories: {Category.publicInterface});
 
   @override
   LintCode get lintCode => code;
diff --git a/pkg/linter/lib/src/rules/public_member_api_docs.dart b/pkg/linter/lib/src/rules/public_member_api_docs.dart
index 61dc168..5740427b 100644
--- a/pkg/linter/lib/src/rules/public_member_api_docs.dart
+++ b/pkg/linter/lib/src/rules/public_member_api_docs.dart
@@ -75,7 +75,7 @@
             name: 'public_member_api_docs',
             description: _desc,
             details: _details,
-            categories: {Category.style});
+            categories: {Category.publicInterface, Category.style});
 
   @override
   LintCode get lintCode => code;
diff --git a/pkg/linter/lib/src/rules/type_annotate_public_apis.dart b/pkg/linter/lib/src/rules/type_annotate_public_apis.dart
index 8e69437..2640e78 100644
--- a/pkg/linter/lib/src/rules/type_annotate_public_apis.dart
+++ b/pkg/linter/lib/src/rules/type_annotate_public_apis.dart
@@ -59,7 +59,7 @@
             name: 'type_annotate_public_apis',
             description: _desc,
             details: _details,
-            categories: {Category.effectiveDart, Category.style});
+            categories: {Category.effectiveDart, Category.publicInterface});
 
   @override
   LintCode get lintCode => code;
diff --git a/pkg/linter/lib/src/rules/unnecessary_library_name.dart b/pkg/linter/lib/src/rules/unnecessary_library_name.dart
index 63978ba..82aaf7f 100644
--- a/pkg/linter/lib/src/rules/unnecessary_library_name.dart
+++ b/pkg/linter/lib/src/rules/unnecessary_library_name.dart
@@ -58,7 +58,7 @@
             name: 'unnecessary_library_name',
             description: _desc,
             details: _details,
-            categories: {Category.style});
+            categories: {Category.languageFeatureUsage, Category.style});
 
   @override
   LintCode get lintCode => code;
diff --git a/pkg/linter/lib/src/rules/unnecessary_new.dart b/pkg/linter/lib/src/rules/unnecessary_new.dart
index 210db77..eb533ab 100644
--- a/pkg/linter/lib/src/rules/unnecessary_new.dart
+++ b/pkg/linter/lib/src/rules/unnecessary_new.dart
@@ -42,7 +42,7 @@
             name: 'unnecessary_new',
             description: _desc,
             details: _details,
-            categories: {Category.style});
+            categories: {Category.languageFeatureUsage, Category.style});
 
   @override
   bool get canUseParsedResult => true;