Use Duration for waitForResponses() from plugins.

Change-Id: I5cf1203559f601c0f5458e278a89b1fd83750ee7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/218340
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/lib/src/domain_abstract.dart b/pkg/analysis_server/lib/src/domain_abstract.dart
index e7079c1..3ff067b 100644
--- a/pkg/analysis_server/lib/src/domain_abstract.dart
+++ b/pkg/analysis_server/lib/src/domain_abstract.dart
@@ -4,7 +4,6 @@
 
 import 'dart:async';
 import 'dart:convert';
-import 'dart:math' as math;
 
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/analysis_server_abstract.dart';
@@ -38,19 +37,18 @@
   /// restarted. The [timeout] is the maximum amount of time that will be spent
   /// waiting for plugins to respond.
   Future<List<plugin.Response>> waitForResponses(
-      Map<PluginInfo, Future<plugin.Response>> futures,
-      {plugin.RequestParams? requestParameters,
-      int timeout = 500}) async {
+    Map<PluginInfo, Future<plugin.Response>> futures, {
+    plugin.RequestParams? requestParameters,
+    Duration timeout = const Duration(milliseconds: 500),
+  }) async {
     // TODO(brianwilkerson) requestParameters might need to be required.
-    var endTime = DateTime.now().millisecondsSinceEpoch + timeout;
+    var timer = Stopwatch()..start();
     var responses = <plugin.Response>[];
     for (var entry in futures.entries) {
       var pluginInfo = entry.key;
       var future = entry.value;
       try {
-        var startTime = DateTime.now().millisecondsSinceEpoch;
-        var response = await future
-            .timeout(Duration(milliseconds: math.max(endTime - startTime, 0)));
+        var response = await future.timeout(timeout - timer.elapsed);
         var error = response.error;
         if (error != null) {
           // TODO(brianwilkerson) Report the error to the plugin manager.
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart
index 4434ecc..015acf4 100644
--- a/pkg/analysis_server/lib/src/domain_completion.dart
+++ b/pkg/analysis_server/lib/src/domain_completion.dart
@@ -571,8 +571,7 @@
     var responses = await waitForResponses(
       requestToPlugins.futures,
       requestParameters: requestToPlugins.parameters,
-      // TODO(scheglov) pass Duration
-      timeout: budget.left.inMilliseconds,
+      timeout: budget.left,
     );
     for (var response in responses) {
       var result = plugin.CompletionGetSuggestionsResult.fromResponse(response);
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
index c853df6b..74ca47f 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
@@ -179,8 +179,8 @@
     int offset,
   ) async {
     final requestParams = plugin.CompletionGetSuggestionsParams(path, offset);
-    final pluginResponses =
-        await requestFromPlugins(path, requestParams, timeout: 100);
+    final pluginResponses = await requestFromPlugins(path, requestParams,
+        timeout: const Duration(milliseconds: 100));
 
     final pluginResults = pluginResponses
         .map((e) => plugin.CompletionGetSuggestionsResult.fromResponse(e))
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
index 7837653..6b87d05 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
@@ -97,7 +97,7 @@
   Future<List<Response>> requestFromPlugins(
     String path,
     RequestParams params, {
-    int timeout = 500,
+    Duration timeout = const Duration(milliseconds: 500),
   }) {
     final driver = server.getAnalysisDriver(path);
     final pluginFutures = server.pluginManager.broadcastRequest(
diff --git a/pkg/analysis_server/test/src/domain_abstract_test.dart b/pkg/analysis_server/test/src/domain_abstract_test.dart
index 36ca0d3..1116cbf 100644
--- a/pkg/analysis_server/test/src/domain_abstract_test.dart
+++ b/pkg/analysis_server/test/src/domain_abstract_test.dart
@@ -32,7 +32,8 @@
   Future<void> test_waitForResponses_empty_timeout() async {
     AbstractRequestHandler handler = TestAbstractRequestHandler(server);
     var futures = <PluginInfo, Future<plugin.Response>>{};
-    var responses = await handler.waitForResponses(futures, timeout: 250);
+    var responses = await handler.waitForResponses(futures,
+        timeout: const Duration(milliseconds: 250));
     expect(responses, isEmpty);
   }
 
@@ -79,7 +80,8 @@
       plugin2: Future.value(response2),
       plugin3: Future.delayed(Duration(milliseconds: 500), () => response3)
     };
-    var responses = await handler.waitForResponses(futures, timeout: 50);
+    var responses = await handler.waitForResponses(futures,
+        timeout: const Duration(milliseconds: 50));
     expect(responses, unorderedEquals([response2]));
   }