Increase the strictness of our requiring explicit types (#7585)

...now that we have generic methods, their types need to be specified too.
diff --git a/packages/flutter_tools/lib/src/android/android_device.dart b/packages/flutter_tools/lib/src/android/android_device.dart
index b18486f..2c4c48d 100644
--- a/packages/flutter_tools/lib/src/android/android_device.dart
+++ b/packages/flutter_tools/lib/src/android/android_device.dart
@@ -587,12 +587,11 @@
         _timeOrigin = _adbTimestampToDateTime(lastTimestamp);
     else
         _timeOrigin = null;
-    runCommand(device.adbCommandForDevice(args)).then((Process process) {
+    runCommand(device.adbCommandForDevice(args)).then<Null>((Process process) {
       _process = process;
       _process.stdout.transform(UTF8.decoder).transform(const LineSplitter()).listen(_onLine);
       _process.stderr.transform(UTF8.decoder).transform(const LineSplitter()).listen(_onLine);
-
-      _process.exitCode.then((int code) {
+      _process.exitCode.whenComplete(() {
         if (_linesController.hasListener)
           _linesController.close();
       });
diff --git a/packages/flutter_tools/lib/src/base/process.dart b/packages/flutter_tools/lib/src/base/process.dart
index dfed148..9d5a479 100644
--- a/packages/flutter_tools/lib/src/base/process.dart
+++ b/packages/flutter_tools/lib/src/base/process.dart
@@ -110,7 +110,7 @@
 
   // Wait for stdout to be fully processed
   // because process.exitCode may complete first causing flaky tests.
-  await subscription.asFuture();
+  await subscription.asFuture<Null>();
   subscription.cancel();
 
   return await process.exitCode;
diff --git a/packages/flutter_tools/lib/src/base/process_manager.dart b/packages/flutter_tools/lib/src/base/process_manager.dart
index 4ee26f2..c416fe8 100644
--- a/packages/flutter_tools/lib/src/base/process_manager.dart
+++ b/packages/flutter_tools/lib/src/base/process_manager.dart
@@ -410,13 +410,14 @@
     await files.forEach((FileSystemEntity entity) {
       File file = entity;
       Future<dynamic> readAsBytes = file.readAsBytes();
-      addAllFilesToArchive.add(readAsBytes.then((List<int> data) {
+      addAllFilesToArchive.add(readAsBytes.then<Null>((List<int> data) {
         archive.addFile(new ArchiveFile.noCompress(
-          path.basename(file.path), data.length, data));
+          path.basename(file.path), data.length, data)
+        );
       }));
     });
 
-    await Future.wait(addAllFilesToArchive);
+    await Future.wait<dynamic>(addAllFilesToArchive);
     return new ZipEncoder().encode(archive);
   }
 }
diff --git a/packages/flutter_tools/lib/src/cache.dart b/packages/flutter_tools/lib/src/cache.dart
index 680143e..b5dac2d 100644
--- a/packages/flutter_tools/lib/src/cache.dart
+++ b/packages/flutter_tools/lib/src/cache.dart
@@ -232,7 +232,7 @@
 
     return Cache._downloadFileToCache(
       Uri.parse(cache.getVersionFor(kName)), fontsDir, true
-    ).then((_) {
+    ).then<Null>((Null value) {
       cache.setStampFor(kName, cache.getVersionFor(kName));
       status.stop();
     }).whenComplete(() {
@@ -401,7 +401,7 @@
 
   Future<Null> _downloadItem(String message, String url, Directory dest) {
     Status status = logger.startProgress(message);
-    return Cache._downloadFileToCache(Uri.parse(url), dest, true).then((_) {
+    return Cache._downloadFileToCache(Uri.parse(url), dest, true).then<Null>((Null value) {
       status.stop();
     }).whenComplete(() {
       status.cancel();
diff --git a/packages/flutter_tools/lib/src/commands/analyze_continuously.dart b/packages/flutter_tools/lib/src/commands/analyze_continuously.dart
index 0f0dcf9..5a34c93 100644
--- a/packages/flutter_tools/lib/src/commands/analyze_continuously.dart
+++ b/packages/flutter_tools/lib/src/commands/analyze_continuously.dart
@@ -120,7 +120,7 @@
 
       if (firstAnalysis && isBenchmarking) {
         writeBenchmark(analysisTimer, issueCount, -1); // TODO(ianh): track members missing dartdocs instead of saying -1
-        server.dispose().then((_) => exit(issueCount > 0 ? 1 : 0));
+        server.dispose().whenComplete(() { exit(issueCount > 0 ? 1 : 0); });
       }
 
       firstAnalysis = false;
diff --git a/packages/flutter_tools/lib/src/commands/daemon.dart b/packages/flutter_tools/lib/src/commands/daemon.dart
index d32a067..9acadf0 100644
--- a/packages/flutter_tools/lib/src/commands/daemon.dart
+++ b/packages/flutter_tools/lib/src/commands/daemon.dart
@@ -171,7 +171,7 @@
       if (_handlers.containsKey(command))
         return _handlers[command](args);
       throw 'command not understood: $name.$command';
-    }).then((dynamic result) {
+    }).then<Null>((dynamic result) {
       if (result == null) {
         _send(<String, dynamic>{'id': id});
       } else {
@@ -386,7 +386,7 @@
 
     if (options.debuggingEnabled) {
       connectionInfoCompleter = new Completer<DebugConnectionInfo>();
-      connectionInfoCompleter.future.then((DebugConnectionInfo info) {
+      connectionInfoCompleter.future.then<Null>((DebugConnectionInfo info) {
         Map<String, dynamic> params = <String, dynamic>{
           'port': info.httpUri.port,
           'wsUri': info.wsUri.toString(),
@@ -397,7 +397,7 @@
       });
     }
     Completer<Null> appStartedCompleter = new Completer<Null>();
-    appStartedCompleter.future.then((_) {
+    appStartedCompleter.future.then<Null>((Null value) {
       _sendAppEvent(app, 'started');
     });
 
diff --git a/packages/flutter_tools/lib/src/devfs.dart b/packages/flutter_tools/lib/src/devfs.dart
index e741fef..1fcd99a 100644
--- a/packages/flutter_tools/lib/src/devfs.dart
+++ b/packages/flutter_tools/lib/src/devfs.dart
@@ -266,7 +266,7 @@
       Stream<List<int>> contents = content.contentsAsCompressedStream();
       await request.addStream(contents);
       HttpClientResponse response = await request.close();
-      await response.drain();
+      await response.drain<Null>();
     } catch (e) {
       printError('Error writing "$devicePath" to DevFS: $e');
     }
@@ -417,7 +417,10 @@
         if (progressReporter != null) {
           final int max = _pendingOperations.length;
           int complete = 0;
-          _pendingOperations.forEach((Future<dynamic> f) => f.then((dynamic v) {
+          _pendingOperations.forEach((Future<dynamic> f) => f.whenComplete(() {
+            // TODO(ianh): If one of the pending operations fail, we'll keep
+            // calling progressReporter long after update() has completed its
+            // future, assuming that doesn't crash the app.
             complete += 1;
             progressReporter(complete, max);
           }));
diff --git a/packages/flutter_tools/lib/src/ios/devices.dart b/packages/flutter_tools/lib/src/ios/devices.dart
index c89871e..424c495 100644
--- a/packages/flutter_tools/lib/src/ios/devices.dart
+++ b/packages/flutter_tools/lib/src/ios/devices.dart
@@ -402,12 +402,11 @@
   String get name => device.name;
 
   void _start() {
-    runCommand(<String>[device.loggerPath]).then((Process process) {
+    runCommand(<String>[device.loggerPath]).then<Null>((Process process) {
       _process = process;
       _process.stdout.transform(UTF8.decoder).transform(const LineSplitter()).listen(_onLine);
       _process.stderr.transform(UTF8.decoder).transform(const LineSplitter()).listen(_onLine);
-
-      _process.exitCode.then((int code) {
+      _process.exitCode.whenComplete(() {
         if (_linesController.hasListener)
           _linesController.close();
       });
diff --git a/packages/flutter_tools/lib/src/ios/simulators.dart b/packages/flutter_tools/lib/src/ios/simulators.dart
index 1ff1eb4..2b68783 100644
--- a/packages/flutter_tools/lib/src/ios/simulators.dart
+++ b/packages/flutter_tools/lib/src/ios/simulators.dart
@@ -663,7 +663,7 @@
     _systemProcess.stdout.transform(UTF8.decoder).transform(const LineSplitter()).listen(_onSystemLine);
     _systemProcess.stderr.transform(UTF8.decoder).transform(const LineSplitter()).listen(_onSystemLine);
 
-    _deviceProcess.exitCode.then((int code) {
+    _deviceProcess.exitCode.whenComplete(() {
       if (_linesController.hasListener)
         _linesController.close();
     });
diff --git a/packages/flutter_tools/lib/src/test/coverage_collector.dart b/packages/flutter_tools/lib/src/test/coverage_collector.dart
index d0efb52..62e1a94 100644
--- a/packages/flutter_tools/lib/src/test/coverage_collector.dart
+++ b/packages/flutter_tools/lib/src/test/coverage_collector.dart
@@ -35,7 +35,7 @@
 
     int pid = process.pid;
     int exitCode;
-    process.exitCode.then((int code) {
+    process.exitCode.then<Null>((int code) {
       exitCode = code;
     });
 
diff --git a/packages/flutter_tools/lib/src/test/flutter_platform.dart b/packages/flutter_tools/lib/src/test/flutter_platform.dart
index 504b3b5..76a0896 100644
--- a/packages/flutter_tools/lib/src/test/flutter_platform.dart
+++ b/packages/flutter_tools/lib/src/test/flutter_platform.dart
@@ -124,7 +124,7 @@
     bool subprocessActive = false;
     bool controllerSinkClosed = false;
     try {
-      controller.sink.done.then((_) { controllerSinkClosed = true; });
+      controller.sink.done.whenComplete(() { controllerSinkClosed = true; });
 
       // Prepare our WebSocket server to talk to the engine subproces.
       HttpServer server = await HttpServer.bind(_kHost, 0);
@@ -524,10 +524,10 @@
 
   @override
   Future<dynamic> close() {
-   Future.wait(<Future<dynamic>>[
+   Future.wait<dynamic>(<Future<dynamic>>[
       _parent.close(),
       _shellProcessClosed,
-    ]).then(
+    ]).then<Null>(
       (List<dynamic> value) {
         _done.complete();
       },
diff --git a/packages/flutter_tools/lib/src/vmservice.dart b/packages/flutter_tools/lib/src/vmservice.dart
index 02c18e0..a8034af 100644
--- a/packages/flutter_tools/lib/src/vmservice.dart
+++ b/packages/flutter_tools/lib/src/vmservice.dart
@@ -561,7 +561,7 @@
   Future<Isolate> getIsolate(String isolateId) {
     if (!loaded) {
       // Trigger a VM load, then get the isolate. Ignore any errors.
-      return load().then((_) => getIsolate(isolateId)).catchError((_) => null);
+      return load().then<Isolate>((ServiceObject serviceObject) => getIsolate(isolateId)).catchError((dynamic error) => null);
     }
     return new Future<Isolate>.value(_isolateCache[isolateId]);
   }
diff --git a/packages/flutter_tools/lib/src/zip.dart b/packages/flutter_tools/lib/src/zip.dart
index 0aae818..788709e 100644
--- a/packages/flutter_tools/lib/src/zip.dart
+++ b/packages/flutter_tools/lib/src/zip.dart
@@ -37,9 +37,9 @@
     final Completer<Null> finished = new Completer<Null>();
     int count = entries.length;
     entries.forEach((String archivePath, DevFSContent content) {
-      content.contentsAsBytes().then((List<int> data) {
+      content.contentsAsBytes().then<Null>((List<int> data) {
         archive.addFile(new ArchiveFile.noCompress(archivePath, data.length, data));
-        --count;
+        count -= 1;
         if (count == 0)
           finished.complete();
       });
@@ -73,11 +73,11 @@
     final Completer<Null> finished = new Completer<Null>();
     int count = entries.length;
     entries.forEach((String archivePath, DevFSContent content) {
-      content.contentsAsBytes().then((List<int> data) {
+      content.contentsAsBytes().then<Null>((List<int> data) {
         File file = fs.file(path.join(zipBuildDir.path, archivePath));
         file.parent.createSync(recursive: true);
-        file.writeAsBytes(data).then((_) {
-          --count;
+        file.writeAsBytes(data).then<Null>((File value) {
+          count -= 1;
           if (count == 0)
             finished.complete();
         });