analyzer: Return generated Diagnostic objects from AbstractAnalysisRule reporting methods

Fixes https://github.com/dart-lang/sdk/issues/61759

This work supports holding onto a Diagnostic which is being reported
for other later uses. The two use cases in DAS are storing complex
data which can be used by fixes. The data in these two cases is stored
in an Expando keyed to the Diagnostic object. Plugin authors have
requested the same ability.

Change-Id: I95784e1b170d5ef0dee534df6adaf1dbdfd94fa6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/456762
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
diff --git a/pkg/analyzer/api.txt b/pkg/analyzer/api.txt
index 981b0b8..d549a0e 100644
--- a/pkg/analyzer/api.txt
+++ b/pkg/analyzer/api.txt
@@ -13,16 +13,16 @@
     new (constructor: AnalysisRule Function({required String description, required String name, RuleState state}))
     diagnosticCode (getter: DiagnosticCode)
     diagnosticCodes (getter: List<DiagnosticCode>)
-    reportAtNode (method: void Function(AstNode?, {List<Object> arguments, List<DiagnosticMessage>? contextMessages}))
-    reportAtOffset (method: void Function(int, int, {List<Object> arguments, List<DiagnosticMessage>? contextMessages}))
-    reportAtPubNode (method: void Function(PubspecNode, {List<Object> arguments, List<DiagnosticMessage> contextMessages}))
-    reportAtToken (method: void Function(Token, {List<Object> arguments, List<DiagnosticMessage>? contextMessages}))
+    reportAtNode (method: Diagnostic? Function(AstNode?, {List<Object> arguments, List<DiagnosticMessage>? contextMessages}))
+    reportAtOffset (method: Diagnostic Function(int, int, {List<Object> arguments, List<DiagnosticMessage>? contextMessages}))
+    reportAtPubNode (method: Diagnostic Function(PubspecNode, {List<Object> arguments, List<DiagnosticMessage> contextMessages}))
+    reportAtToken (method: Diagnostic? Function(Token, {List<Object> arguments, List<DiagnosticMessage>? contextMessages}))
   MultiAnalysisRule (class extends AbstractAnalysisRule):
     new (constructor: MultiAnalysisRule Function({required String description, required String name, RuleState state}))
-    reportAtNode (method: void Function(AstNode?, {List<Object> arguments, List<DiagnosticMessage>? contextMessages, required DiagnosticCode diagnosticCode}))
-    reportAtOffset (method: void Function(int, int, {List<Object> arguments, List<DiagnosticMessage>? contextMessages, required DiagnosticCode diagnosticCode}))
-    reportAtPubNode (method: void Function(PubspecNode, {List<Object> arguments, List<DiagnosticMessage> contextMessages, required DiagnosticCode diagnosticCode}))
-    reportAtToken (method: void Function(Token, {List<Object> arguments, List<DiagnosticMessage>? contextMessages, required DiagnosticCode diagnosticCode}))
+    reportAtNode (method: Diagnostic? Function(AstNode?, {List<Object> arguments, List<DiagnosticMessage>? contextMessages, required DiagnosticCode diagnosticCode}))
+    reportAtOffset (method: Diagnostic Function(int, int, {List<Object> arguments, List<DiagnosticMessage>? contextMessages, required DiagnosticCode diagnosticCode}))
+    reportAtPubNode (method: Diagnostic Function(PubspecNode, {List<Object> arguments, List<DiagnosticMessage> contextMessages, required DiagnosticCode diagnosticCode}))
+    reportAtToken (method: Diagnostic? Function(Token, {List<Object> arguments, List<DiagnosticMessage>? contextMessages, required DiagnosticCode diagnosticCode}))
 package:analyzer/analysis_rule/pubspec.dart:
   PubspecDependency (class extends Object):
     new (constructor: PubspecDependency Function())
diff --git a/pkg/analyzer/lib/analysis_rule/analysis_rule.dart b/pkg/analyzer/lib/analysis_rule/analysis_rule.dart
index 094cfe6..d8b7c42 100644
--- a/pkg/analyzer/lib/analysis_rule/analysis_rule.dart
+++ b/pkg/analyzer/lib/analysis_rule/analysis_rule.dart
@@ -76,30 +76,31 @@
     RuleContext context,
   ) {}
 
-  void _reportAtNode(
+  Diagnostic? _reportAtNode(
     AstNode? node, {
     List<Object> arguments = const [],
     List<DiagnosticMessage>? contextMessages,
     required DiagnosticCode diagnosticCode,
   }) {
     if (node != null && !node.isSynthetic) {
-      _reporter.atNode(
+      return _reporter.atNode(
         node,
         diagnosticCode,
         arguments: arguments,
         contextMessages: contextMessages,
       );
     }
+    return null;
   }
 
-  void _reportAtOffset(
+  Diagnostic _reportAtOffset(
     int offset,
     int length, {
     required DiagnosticCode diagnosticCode,
     List<Object> arguments = const [],
     List<DiagnosticMessage>? contextMessages,
   }) {
-    _reporter.atOffset(
+    return _reporter.atOffset(
       offset: offset,
       length: length,
       diagnosticCode: diagnosticCode,
@@ -108,7 +109,7 @@
     );
   }
 
-  void _reportAtPubNode(
+  Diagnostic _reportAtPubNode(
     PubspecNodeImpl node, {
     List<Object> arguments = const [],
     List<DiagnosticMessage> contextMessages = const [],
@@ -124,22 +125,24 @@
       contextMessages: contextMessages,
     );
     _reporter.reportError(diagnostic);
+    return diagnostic;
   }
 
-  void _reportAtToken(
+  Diagnostic? _reportAtToken(
     Token token, {
     required DiagnosticCode diagnosticCode,
     List<Object> arguments = const [],
     List<DiagnosticMessage>? contextMessages,
   }) {
     if (!token.isSynthetic) {
-      _reporter.atToken(
+      return _reporter.atToken(
         token,
         diagnosticCode,
         arguments: arguments,
         contextMessages: contextMessages,
       );
     }
+    return null;
   }
 }
 
@@ -156,7 +159,7 @@
 
   /// Reports a diagnostic at [node] with message [arguments] and
   /// [contextMessages].
-  void reportAtNode(
+  Diagnostic? reportAtNode(
     AstNode? node, {
     List<Object> arguments = const [],
     List<DiagnosticMessage>? contextMessages,
@@ -169,7 +172,7 @@
 
   /// Reports a diagnostic at [offset], with [length], with message [arguments]
   /// and [contextMessages].
-  void reportAtOffset(
+  Diagnostic reportAtOffset(
     int offset,
     int length, {
     List<Object> arguments = const [],
@@ -184,7 +187,7 @@
 
   /// Reports a diagnostic at Pubspec [node], with message [arguments] and
   /// [contextMessages].
-  void reportAtPubNode(
+  Diagnostic reportAtPubNode(
     PubspecNode node, {
     List<Object> arguments = const [],
     List<DiagnosticMessage> contextMessages = const [],
@@ -197,7 +200,7 @@
 
   /// Reports a diagnostic at [token], with message [arguments] and
   /// [contextMessages].
-  void reportAtToken(
+  Diagnostic? reportAtToken(
     Token token, {
     List<Object> arguments = const [],
     List<DiagnosticMessage>? contextMessages,
@@ -220,7 +223,7 @@
 
   /// Reports [diagnosticCode] at [node] with message [arguments] and
   /// [contextMessages].
-  void reportAtNode(
+  Diagnostic? reportAtNode(
     AstNode? node, {
     List<Object> arguments = const [],
     List<DiagnosticMessage>? contextMessages,
@@ -234,7 +237,7 @@
 
   /// Reports [diagnosticCode] at [offset], with [length], with message [arguments]
   /// and [contextMessages].
-  void reportAtOffset(
+  Diagnostic reportAtOffset(
     int offset,
     int length, {
     required DiagnosticCode diagnosticCode,
@@ -250,14 +253,14 @@
 
   /// Reports [diagnosticCode] at Pubspec [node], with message [arguments] and
   /// [contextMessages].
-  void reportAtPubNode(
+  Diagnostic reportAtPubNode(
     PubspecNode node, {
     required DiagnosticCode diagnosticCode,
     List<Object> arguments = const [],
     List<DiagnosticMessage> contextMessages = const [],
   }) {
-    // Cache error and location info for creating `AnalysisErrorInfo`s.
-    var error = Diagnostic.tmp(
+    // Cache diagnostic and location info for creating `AnalysisErrorInfo`s.
+    var diagnostic = Diagnostic.tmp(
       source: (node as PubspecNodeImpl).source,
       offset: node.span.start.offset,
       length: node.span.length,
@@ -265,12 +268,13 @@
       arguments: arguments,
       contextMessages: contextMessages,
     );
-    _reporter.reportError(error);
+    _reporter.reportError(diagnostic);
+    return diagnostic;
   }
 
   /// Reports [diagnosticCode] at [token], with message [arguments] and
   /// [contextMessages].
-  void reportAtToken(
+  Diagnostic? reportAtToken(
     Token token, {
     required DiagnosticCode diagnosticCode,
     List<Object> arguments = const [],