Enable discarded_futures lint in analyzer and _fe_analyzer_shared.

Several call sites intentionally discard a future; these call sites
have been wrapped with `unawaited()` (which is the standard way to
suppress the lint).

Turning on this lint uncovered several tests that should have been
async; these tests have been fixed.

Change-Id: I66e0f6bf7a05946e8d460ce9b5581837ce067870
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/431420
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Auto-Submit: Paul Berry <paulberry@google.com>
diff --git a/pkg/_fe_analyzer_shared/analysis_options.yaml b/pkg/_fe_analyzer_shared/analysis_options.yaml
index 8579d9b..aab7f10 100644
--- a/pkg/_fe_analyzer_shared/analysis_options.yaml
+++ b/pkg/_fe_analyzer_shared/analysis_options.yaml
@@ -10,6 +10,7 @@
     - annotate_overrides
     - collection_methods_unrelated_type
     - curly_braces_in_flow_control_structures
+    - discarded_futures
     - prefer_adjacent_string_concatenation
     - unawaited_futures
     - recursive_getters
diff --git a/pkg/analyzer/analysis_options.yaml b/pkg/analyzer/analysis_options.yaml
index 4b9db4e..324647e 100644
--- a/pkg/analyzer/analysis_options.yaml
+++ b/pkg/analyzer/analysis_options.yaml
@@ -53,6 +53,7 @@
     - avoid_dynamic_calls
     - avoid_redundant_argument_values
     - avoid_unused_constructor_parameters
+    - discarded_futures
     - flutter_style_todos
     - unawaited_futures
     - unnecessary_breaks
diff --git a/pkg/analyzer/lib/file_system/memory_file_system.dart b/pkg/analyzer/lib/file_system/memory_file_system.dart
index d2cb846..017b01a 100644
--- a/pkg/analyzer/lib/file_system/memory_file_system.dart
+++ b/pkg/analyzer/lib/file_system/memory_file_system.dart
@@ -631,12 +631,14 @@
     void setupWatcher() {
       var watchers = provider._pathToWatchers[path] ??= [];
       watchers.add(streamController);
-      streamController.done.then((_) {
-        watchers.remove(streamController);
-        if (watchers.isEmpty) {
-          provider._pathToWatchers.remove(path);
-        }
-      });
+      unawaited(
+        streamController.done.then((_) {
+          watchers.remove(streamController);
+          if (watchers.isEmpty) {
+            provider._pathToWatchers.remove(path);
+          }
+        }),
+      );
       ready.complete();
       if (provider.emitPathNotFoundExceptionsForPaths.contains(path)) {
         streamController.addError(
diff --git a/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart b/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart
index bf6a744..9d84321 100644
--- a/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.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:analyzer/dart/analysis/analysis_context_collection.dart';
 import 'package:analyzer/dart/analysis/declared_variables.dart';
 import 'package:analyzer/file_system/file_system.dart';
@@ -70,7 +72,7 @@
     if (scheduler == null) {
       scheduler = AnalysisDriverScheduler(performanceLog);
       if (drainStreams) {
-        scheduler.events.drain<void>();
+        unawaited(scheduler.events.drain<void>());
       }
       scheduler.start();
     }
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_builder.dart b/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
index 3d1d6af..338d08d 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_builder.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:analyzer/dart/analysis/context_root.dart';
 import 'package:analyzer/dart/analysis/declared_variables.dart';
 import 'package:analyzer/file_system/file_system.dart';
@@ -179,7 +181,7 @@
     // AnalysisDriver reports results into streams.
     // We need to drain these streams to avoid memory leak.
     if (drainStreams) {
-      driver.exceptions.drain<void>();
+      unawaited(driver.exceptions.drain<void>());
     }
 
     return analysisContext;
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 086b37d..dfbf27c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -2559,7 +2559,7 @@
       throw StateError('The scheduler has already been started.');
     }
     _started = true;
-    _run();
+    unawaited(_run());
   }
 
   /// Return a future that will be completed the next time the status is idle.
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_byte_store.dart b/pkg/analyzer/lib/src/dart/analysis/file_byte_store.dart
index 16227d9..a634753 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_byte_store.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_byte_store.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 'dart:isolate';
 import 'dart:typed_data';
@@ -37,7 +38,7 @@
 
   EvictingFileByteStore(this._cachePath, this._maxSizeBytes)
     : _fileByteStore = FileByteStore(_cachePath) {
-    _requestCacheCleanUp();
+    unawaited(_requestCacheCleanUp());
   }
 
   @override
@@ -49,7 +50,7 @@
     // Update the current size.
     _bytesWrittenSinceCleanup += bytes.length;
     if (_bytesWrittenSinceCleanup > _maxSizeBytes ~/ 8) {
-      _requestCacheCleanUp();
+      unawaited(_requestCacheCleanUp());
     }
     return bytes;
   }
@@ -300,12 +301,14 @@
   void _run(Future Function() fn) {
     _available--;
 
-    fn().whenComplete(() {
-      _available++;
+    unawaited(
+      fn().whenComplete(() {
+        _available++;
 
-      if (waiting.isNotEmpty) {
-        _run(waiting.removeAt(0));
-      }
-    });
+        if (waiting.isNotEmpty) {
+          _run(waiting.removeAt(0));
+        }
+      }),
+    );
   }
 }
diff --git a/pkg/analyzer/lib/src/workspace/blaze_watcher.dart b/pkg/analyzer/lib/src/workspace/blaze_watcher.dart
index be84a0f..442f140 100644
--- a/pkg/analyzer/lib/src/workspace/blaze_watcher.dart
+++ b/pkg/analyzer/lib/src/workspace/blaze_watcher.dart
@@ -317,10 +317,10 @@
       _toIsolatePort.send(BlazeWatcherShutdownIsolate());
     }
     if (_isolateIsStarting) {
-      _fromIsolateSubscription.cancel();
+      unawaited(_fromIsolateSubscription.cancel());
       _fromIsolatePort.close();
     }
-    _events.close();
+    unawaited(_events.close());
   }
 
   void startWatching(String workspace, BlazeSearchInfo info) {
@@ -363,11 +363,13 @@
   void _startIsolateIfNeeded() {
     if (_isolateIsStarting) return;
     _isolateIsStarting = true;
-    _startIsolateImpl();
-    _isolateHasStarted.future.then((_) {
-      _buffer.forEach(_toIsolatePort.send);
-      _buffer.clear();
-    });
+    unawaited(_startIsolateImpl());
+    unawaited(
+      _isolateHasStarted.future.then((_) {
+        _buffer.forEach(_toIsolatePort.send);
+        _buffer.clear();
+      }),
+    );
   }
 
   Future<void> _startIsolateImpl() async {
diff --git a/pkg/analyzer/test/file_system/physical_resource_provider_watch_test.dart b/pkg/analyzer/test/file_system/physical_resource_provider_watch_test.dart
index 24decfb..31e21b7 100644
--- a/pkg/analyzer/test/file_system/physical_resource_provider_watch_test.dart
+++ b/pkg/analyzer/test/file_system/physical_resource_provider_watch_test.dart
@@ -154,7 +154,7 @@
       var subscription = file.watch().changes.listen(changesReceived.add);
       // Delay running the rest of the test to allow file.changes propagate.
       return _delayed(() => test(changesReceived)).whenComplete(() {
-        subscription.cancel();
+        unawaited(subscription.cancel());
       });
     });
   }
@@ -177,7 +177,7 @@
       // won't be able to reliably distinguish new files from modified
       // ones.
       return _delayed(() => test(changesReceived)).whenComplete(() {
-        subscription.cancel();
+        unawaited(subscription.cancel());
       });
     });
   }
diff --git a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
index 829a59d..f131a08 100644
--- a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
+++ b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
@@ -1040,8 +1040,8 @@
 ''');
   }
 
-  test_errors_hasNullSuffix() {
-    assertErrorsInCode(
+  Future<void> test_errors_hasNullSuffix() async {
+    await assertErrorsInCode(
       r'''
 String f(Map<int, String> a) {
   return a[0];
diff --git a/pkg/analyzer/test/src/diagnostics/analysis_options/include_file_not_found_test.dart b/pkg/analyzer/test/src/diagnostics/analysis_options/include_file_not_found_test.dart
index 4849900..c6331e0 100644
--- a/pkg/analyzer/test/src/diagnostics/analysis_options/include_file_not_found_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/analysis_options/include_file_not_found_test.dart
@@ -15,8 +15,8 @@
 
 @reflectiveTest
 class IncludeFileNotFoundTest extends AbstractAnalysisOptionsTest {
-  void test_notFound_existent_doubleQuoted() {
-    assertErrorsInCode(
+  Future<void> test_notFound_existent_doubleQuoted() async {
+    await assertErrorsInCode(
       '''
 include: "./analysis_options.yaml"
 ''',
@@ -24,8 +24,8 @@
     );
   }
 
-  void test_notFound_existent_notQuoted() {
-    assertErrorsInCode(
+  Future<void> test_notFound_existent_notQuoted() async {
+    await assertErrorsInCode(
       '''
 include: ./analysis_options.yaml
 ''',
@@ -33,8 +33,8 @@
     );
   }
 
-  void test_notFound_existent_singleQuoted() {
-    assertErrorsInCode(
+  Future<void> test_notFound_existent_singleQuoted() async {
+    await assertErrorsInCode(
       '''
 include: './analysis_options.yaml'
 ''',
@@ -42,8 +42,8 @@
     );
   }
 
-  void test_notFound_nonexistent_doubleQuoted() {
-    assertErrorsInCode(
+  Future<void> test_notFound_nonexistent_doubleQuoted() async {
+    await assertErrorsInCode(
       '''
 # We don't depend on pedantic, but we should consider adding it.
 include: "package:pedantic/analysis_options.yaml"
@@ -61,8 +61,8 @@
     );
   }
 
-  void test_notFound_nonexistent_notQuoted() {
-    assertErrorsInCode(
+  Future<void> test_notFound_nonexistent_notQuoted() async {
+    await assertErrorsInCode(
       '''
 # We don't depend on pedantic, but we should consider adding it.
 include: package:pedantic/analysis_options.yaml
@@ -80,8 +80,8 @@
     );
   }
 
-  void test_notFound_nonexistent_singleQuoted() {
-    assertErrorsInCode(
+  Future<void> test_notFound_nonexistent_singleQuoted() async {
+    await assertErrorsInCode(
       '''
 # We don't depend on pedantic, but we should consider adding it.
 include: 'package:pedantic/analysis_options.yaml'
diff --git a/pkg/analyzer/test/src/diagnostics/analysis_options/include_file_warning_test.dart b/pkg/analyzer/test/src/diagnostics/analysis_options/include_file_warning_test.dart
index 9d0d0a4..932ba9f 100644
--- a/pkg/analyzer/test/src/diagnostics/analysis_options/include_file_warning_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/analysis_options/include_file_warning_test.dart
@@ -15,12 +15,12 @@
 
 @reflectiveTest
 class IncludeFileWarningTest extends AbstractAnalysisOptionsTest {
-  void test_fileWarning() {
+  Future<void> test_fileWarning() async {
     newFile('/a.yaml', '''
 analyzer:
   something: bad
 ''');
-    assertErrorsInCode(
+    await assertErrorsInCode(
       '''
 include: a.yaml
 ''',
diff --git a/pkg/analyzer/test/src/diagnostics/analysis_options/recursive_include_file_test.dart b/pkg/analyzer/test/src/diagnostics/analysis_options/recursive_include_file_test.dart
index 735e8fdc..51cff61 100644
--- a/pkg/analyzer/test/src/diagnostics/analysis_options/recursive_include_file_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/analysis_options/recursive_include_file_test.dart
@@ -15,8 +15,8 @@
 
 @reflectiveTest
 class RecursiveIncludeFileTest extends AbstractAnalysisOptionsTest {
-  void test_itself() {
-    assertErrorsInCode(
+  Future<void> test_itself() async {
+    await assertErrorsInCode(
       '''
 include: analysis_options.yaml
 ''',
@@ -33,8 +33,8 @@
     );
   }
 
-  void test_itself_inList() {
-    assertErrorsInCode(
+  Future<void> test_itself_inList() async {
+    await assertErrorsInCode(
       '''
 include:
   - analysis_options.yaml
@@ -52,14 +52,14 @@
     );
   }
 
-  void test_recursive() {
+  Future<void> test_recursive() async {
     newFile('/a.yaml', '''
 include: b.yaml
 ''');
     newFile('/b.yaml', '''
 include: analysis_options.yaml
 ''');
-    assertErrorsInCode(
+    await assertErrorsInCode(
       '''
 include: a.yaml
 ''',
@@ -76,11 +76,11 @@
     );
   }
 
-  void test_recursive_itself() {
+  Future<void> test_recursive_itself() async {
     newFile('/a.yaml', '''
 include: a.yaml
 ''');
-    assertErrorsInCode(
+    await assertErrorsInCode(
       '''
 include: a.yaml
 ''',
@@ -98,7 +98,7 @@
     );
   }
 
-  void test_recursive_listAtTop() {
+  Future<void> test_recursive_listAtTop() async {
     newFile('/a.yaml', '''
 include: b.yaml
 ''');
@@ -107,7 +107,7 @@
 ''');
     newFile('/empty.yaml', '''
 ''');
-    assertErrorsInCode(
+    await assertErrorsInCode(
       '''
 include:
   - empty.yaml
@@ -126,7 +126,7 @@
     );
   }
 
-  void test_recursive_listIncluded() {
+  Future<void> test_recursive_listIncluded() async {
     newFile('/a.yaml', '''
 include:
   - empty.yaml
@@ -137,7 +137,7 @@
 ''');
     newFile('/empty.yaml', '''
 ''');
-    assertErrorsInCode(
+    await assertErrorsInCode(
       '''
 include: a.yaml
 ''',
@@ -154,14 +154,14 @@
     );
   }
 
-  void test_recursive_notInBeginning() {
+  Future<void> test_recursive_notInBeginning() async {
     newFile('/a.yaml', '''
 include: b.yaml
 ''');
     newFile('/b.yaml', '''
 include: a.yaml
 ''');
-    assertErrorsInCode(
+    await assertErrorsInCode(
       '''
 include: a.yaml
 ''',
diff --git a/pkg/analyzer/test/src/options/options_rule_validator_test.dart b/pkg/analyzer/test/src/options/options_rule_validator_test.dart
index dae7c8e..c8c76e3 100644
--- a/pkg/analyzer/test/src/options/options_rule_validator_test.dart
+++ b/pkg/analyzer/test/src/options/options_rule_validator_test.dart
@@ -46,26 +46,26 @@
 @reflectiveTest
 class OptionsRuleValidatorIncludedFileTest extends AbstractAnalysisOptionsTest
     with OptionsRuleValidatorTestMixin {
-  test_deprecated_rule_inInclude_ok() {
+  Future<void> test_deprecated_rule_inInclude_ok() async {
     newFile('/included.yaml', '''
 linter:
   rules:
     - deprecated_lint
 ''');
 
-    assertErrorsInCode('''
+    await assertErrorsInCode('''
 include: included.yaml
 ''', []);
   }
 
-  test_removed_rule_inInclude_ok() {
+  Future<void> test_removed_rule_inInclude_ok() async {
     newFile('/included.yaml', '''
 linter:
   rules:
     - removed_in_2_12_lint
 ''');
 
-    assertErrorsInCode('''
+    await assertErrorsInCode('''
 include: included.yaml
 ''', []);
   }
diff --git a/pkg/analyzer_utilities/lib/testing/tree_string_sink.dart b/pkg/analyzer_utilities/lib/testing/tree_string_sink.dart
index 71d0bfd..5ef214d 100644
--- a/pkg/analyzer_utilities/lib/testing/tree_string_sink.dart
+++ b/pkg/analyzer_utilities/lib/testing/tree_string_sink.dart
@@ -37,7 +37,7 @@
     }
   }
 
-  Future<void> writeFlags(Map<String, bool> flags) async {
+  void writeFlags(Map<String, bool> flags) {
     if (flags.values.any((flag) => flag)) {
       writeIndentedLine(() {
         write('flags:');