[analysis_server] Enable unawaited_futures lint and fix remaining violations

Change-Id: I44b56ba8e1bd9ed5ba3d85006eb5d615e5a2c9d6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/251461
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/analysis_options.yaml b/pkg/analysis_server/analysis_options.yaml
index 9e70161..37bbd55 100644
--- a/pkg/analysis_server/analysis_options.yaml
+++ b/pkg/analysis_server/analysis_options.yaml
@@ -24,5 +24,6 @@
 linter:
   rules:
     - depend_on_referenced_packages
+    - unawaited_futures
     - unnecessary_parenthesis
     - use_super_parameters
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_reanalyze.dart b/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_reanalyze.dart
index b3355c2d..5282454 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_reanalyze.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_reanalyze.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:async';
+
 import 'package:analysis_server/lsp_protocol/protocol.dart';
 import 'package:analysis_server/src/lsp/constants.dart';
 import 'package:analysis_server/src/lsp/handlers/handlers.dart';
@@ -18,7 +20,9 @@
   @override
   Future<ErrorOr<void>> handle(
       void params, MessageInfo message, CancellationToken token) async {
-    server.reanalyze();
+    // This command just starts a refresh, it does not wait for it to
+    // complete before responding to the client.
+    unawaited(server.reanalyze());
     return success(null);
   }
 }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_exit.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_exit.dart
index b8b2dbf..5487d58 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_exit.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_exit.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:async';
 import 'dart:io';
 
 import 'package:analysis_server/lsp_protocol/protocol.dart';
@@ -30,9 +31,10 @@
     server.willExit = true;
 
     await server.shutdown();
-    Future(() {
-      exit(clientDidCallShutdown ? 0 : 1);
-    });
+    // Use Future to schedule the exit after we have responded to this request
+    // (so the client gets the response). Do not await it as it will prevent the
+    // response from completing.
+    unawaited(Future(() => exit(clientDidCallShutdown ? 0 : 1)));
     return success(null);
   }
 }
diff --git a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
index fd36e21..442bfe4 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
@@ -272,7 +272,9 @@
 
     // Client config can affect capabilities, so this should only be done after
     // we have the initial/updated config.
-    capabilitiesComputer.performDynamicRegistration();
+    // Don't await this because it involves sending requests to the client (for
+    // config) that should not stop/delay initialization.
+    unawaited(capabilitiesComputer.performDynamicRegistration());
   }
 
   /// Return a [LineInfo] for the file with the given [path].
diff --git a/pkg/analysis_server/test/lsp/closing_labels_test.dart b/pkg/analysis_server/test/lsp/closing_labels_test.dart
index 211d57d..2518e37 100644
--- a/pkg/analysis_server/test/lsp/closing_labels_test.dart
+++ b/pkg/analysis_server/test/lsp/closing_labels_test.dart
@@ -30,11 +30,11 @@
     await initialize(initializationOptions: {'closingLabels': true});
 
     final labelsUpdateBeforeChange = waitForClosingLabels(mainFileUri);
-    openFile(mainFileUri, initialContent);
+    await openFile(mainFileUri, initialContent);
     final labelsBeforeChange = await labelsUpdateBeforeChange;
 
     final labelsUpdateAfterChange = waitForClosingLabels(mainFileUri);
-    replaceFile(1, mainFileUri, updatedContent);
+    await replaceFile(1, mainFileUri, updatedContent);
     final labelsAfterChange = await labelsUpdateAfterChange;
 
     expect(labelsBeforeChange, isEmpty);
@@ -70,7 +70,7 @@
     await initialize(initializationOptions: {'closingLabels': true});
 
     final closingLabelsUpdate = waitForClosingLabels(mainFileUri);
-    openFile(mainFileUri, content);
+    await openFile(mainFileUri, content);
     final labels = await closingLabelsUpdate;
 
     expect(labels, hasLength(2));
diff --git a/pkg/analysis_server/test/lsp/configuration_test.dart b/pkg/analysis_server/test/lsp/configuration_test.dart
index c4d5b12..c736a40 100644
--- a/pkg/analysis_server/test/lsp/configuration_test.dart
+++ b/pkg/analysis_server/test/lsp/configuration_test.dart
@@ -92,7 +92,7 @@
         .listen((_) => didGetConfigRequest = true);
 
     await initialize();
-    pumpEventQueue();
+    await pumpEventQueue();
 
     expect(didGetConfigRequest, isFalse);
   }
@@ -105,6 +105,6 @@
     await initialize(
         workspaceCapabilities:
             withConfigurationSupport(emptyWorkspaceClientCapabilities));
-    pumpEventQueue();
+    await pumpEventQueue();
   }
 }
diff --git a/pkg/analysis_server/test/lsp/diagnostic_test.dart b/pkg/analysis_server/test/lsp/diagnostic_test.dart
index 994943f..98330d6 100644
--- a/pkg/analysis_server/test/lsp/diagnostic_test.dart
+++ b/pkg/analysis_server/test/lsp/diagnostic_test.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:async';
+
 import 'package:analysis_server/lsp_protocol/protocol.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
@@ -270,11 +272,15 @@
     newFile(dotFolderFilePath, 'String a = 1;');
 
     List<Diagnostic>? diagnostics;
-    waitForDiagnostics(dotFolderFileUri).then((d) => diagnostics = d);
+    // Record if diagnostics are recieved, but since we don't expect them
+    // don't await them.
+    unawaited(
+        waitForDiagnostics(dotFolderFileUri).then((d) => diagnostics = d));
 
     // Send a request for a hover.
     await initialize();
     await getHover(dotFolderFileUri, Position(line: 0, character: 0));
+    await pumpEventQueue(times: 5000);
 
     // Ensure that as part of responding to getHover, diagnostics were not
     // transmitted.
diff --git a/pkg/analysis_server/test/lsp/flutter_outline_test.dart b/pkg/analysis_server/test/lsp/flutter_outline_test.dart
index c400feb..3c5fa75 100644
--- a/pkg/analysis_server/test/lsp/flutter_outline_test.dart
+++ b/pkg/analysis_server/test/lsp/flutter_outline_test.dart
@@ -37,11 +37,11 @@
     await initialize(initializationOptions: {'flutterOutline': true});
 
     final outlineUpdateBeforeChange = waitForFlutterOutline(mainFileUri);
-    openFile(mainFileUri, initialContent);
+    await openFile(mainFileUri, initialContent);
     final outlineBeforeChange = await outlineUpdateBeforeChange;
 
     final outlineUpdateAfterChange = waitForFlutterOutline(mainFileUri);
-    replaceFile(1, mainFileUri, updatedContent);
+    await replaceFile(1, mainFileUri, updatedContent);
     final outlineAfterChange = await outlineUpdateAfterChange;
 
     expect(outlineBeforeChange, isNotNull);
@@ -76,7 +76,7 @@
     await initialize(initializationOptions: {'flutterOutline': true});
 
     final outlineNotification = waitForFlutterOutline(mainFileUri);
-    openFile(mainFileUri, content);
+    await openFile(mainFileUri, content);
     final outline = await outlineNotification;
 
     expect(outline, isNotNull);
diff --git a/pkg/analysis_server/test/lsp/initialization_test.dart b/pkg/analysis_server/test/lsp/initialization_test.dart
index 4f6bf6e..d304655 100644
--- a/pkg/analysis_server/test/lsp/initialization_test.dart
+++ b/pkg/analysis_server/test/lsp/initialization_test.dart
@@ -470,14 +470,12 @@
     // The server will send an unregister request followed by another register
     // request to change document filter on folding. We need to respond to the
     // unregister request as the server awaits that.
-    requestsFromServer
+    // This is set up as a future callback and should not be awaited here.
+    unawaited(requestsFromServer
         .firstWhere((r) => r.method == Method.client_unregisterCapability)
         .then((request) {
       respondTo(request, null);
-      return UnregistrationParams.fromJson(
-              request.params as Map<String, Object?>)
-          .unregisterations;
-    });
+    }));
 
     final request = await expectRequest(Method.client_registerCapability, () {
       final plugin = configureTestPlugin();
diff --git a/pkg/analysis_server/test/lsp/outline_test.dart b/pkg/analysis_server/test/lsp/outline_test.dart
index 7c630a2..e369585 100644
--- a/pkg/analysis_server/test/lsp/outline_test.dart
+++ b/pkg/analysis_server/test/lsp/outline_test.dart
@@ -22,11 +22,11 @@
     await initialize(initializationOptions: {'outline': true});
 
     final outlineUpdateBeforeChange = waitForOutline(mainFileUri);
-    openFile(mainFileUri, initialContent);
+    await openFile(mainFileUri, initialContent);
     final outlineBeforeChange = await outlineUpdateBeforeChange;
 
     final outlineUpdateAfterChange = waitForOutline(mainFileUri);
-    replaceFile(1, mainFileUri, updatedContent);
+    await replaceFile(1, mainFileUri, updatedContent);
     final outlineAfterChange = await outlineUpdateAfterChange;
 
     expect(outlineBeforeChange, isNotNull);
@@ -46,7 +46,7 @@
     await initialize(initializationOptions: {'outline': true});
 
     final outlineUpdate = waitForOutline(mainFileUri);
-    openFile(mainFileUri, initialContent);
+    await openFile(mainFileUri, initialContent);
     final outline = await outlineUpdate;
 
     expect(outline, isNotNull);
@@ -72,7 +72,7 @@
     await initialize(initializationOptions: {'outline': true});
 
     final outlineNotification = waitForOutline(mainFileUri);
-    openFile(mainFileUri, content);
+    await openFile(mainFileUri, content);
     final outline = await outlineNotification;
 
     expect(outline, isNotNull);