adjust declared types to work with dart 2 typing at runtime (#19007)

* adjust declared types to work with dart 2 typing at runtime

* review comments

* update packages/flutter_tools/lib/src/ios/simulators.dart
diff --git a/packages/flutter_tools/lib/src/android/android_studio.dart b/packages/flutter_tools/lib/src/android/android_studio.dart
index 46119f2..f224411 100644
--- a/packages/flutter_tools/lib/src/android/android_studio.dart
+++ b/packages/flutter_tools/lib/src/android/android_studio.dart
@@ -150,7 +150,8 @@
         final Iterable<Directory> directories = fs
             .directory(path)
             .listSync()
-            .where((FileSystemEntity e) => e is Directory);
+            .where((FileSystemEntity e) => e is Directory)
+            .cast<Directory>();
         for (Directory directory in directories) {
           final String name = directory.basename;
           // An exact match, or something like 'Android Studio 3.0 Preview.app'.
diff --git a/packages/flutter_tools/lib/src/asset.dart b/packages/flutter_tools/lib/src/asset.dart
index ba81d81..9ee330c 100644
--- a/packages/flutter_tools/lib/src/asset.dart
+++ b/packages/flutter_tools/lib/src/asset.dart
@@ -10,6 +10,7 @@
 import 'base/context.dart';
 import 'base/file_system.dart';
 import 'base/platform.dart';
+import 'base/utils.dart';
 import 'build_info.dart';
 import 'cache.dart';
 import 'dart/package_map.dart';
@@ -268,20 +269,21 @@
   final String fontsPath = fs.path.join(fs.path.absolute(Cache.flutterRoot),
       'packages', 'flutter_tools', 'schema', 'material_fonts.yaml');
 
-  return loadYaml(fs.file(fontsPath).readAsStringSync());
+  return castStringKeyedMap(loadYaml(fs.file(fontsPath).readAsStringSync()));
 }
 
 final Map<String, dynamic> _materialFontsManifest = _readMaterialFontsManifest();
 
 List<Map<String, dynamic>> _getMaterialFonts(String fontSet) {
-  return _materialFontsManifest[fontSet];
+  final List<dynamic> fontsList = _materialFontsManifest[fontSet];
+  return fontsList?.map<Map<String, dynamic>>(castStringKeyedMap)?.toList();
 }
 
 List<_Asset> _getMaterialAssets(String fontSet) {
   final List<_Asset> result = <_Asset>[];
 
   for (Map<String, dynamic> family in _getMaterialFonts(fontSet)) {
-    for (Map<String, dynamic> font in family['fonts']) {
+    for (Map<dynamic, dynamic> font in family['fonts']) {
       final Uri entryUri = fs.path.toUri(font['asset']);
       result.add(new _Asset(
         baseDir: fs.path.join(Cache.flutterRoot, 'bin', 'cache', 'artifacts', 'material_fonts'),
diff --git a/packages/flutter_tools/lib/src/base/utils.dart b/packages/flutter_tools/lib/src/base/utils.dart
index a32eaff..f13c9c9 100644
--- a/packages/flutter_tools/lib/src/base/utils.dart
+++ b/packages/flutter_tools/lib/src/base/utils.dart
@@ -231,6 +231,13 @@
       value.toRadixString(16).padLeft(count, '0');
 }
 
+/// Given a data structure which is a Map of String to dynamic values, return
+/// the same structure (`Map<String, dynamic>`) with the correct runtime types.
+Map<String, dynamic> castStringKeyedMap(dynamic untyped) {
+  final Map<dynamic, dynamic> map = untyped;
+  return map.cast<String, dynamic>();
+}
+
 Clock get clock => context[Clock];
 
 typedef Future<Null> AsyncCallback();
diff --git a/packages/flutter_tools/lib/src/commands/daemon.dart b/packages/flutter_tools/lib/src/commands/daemon.dart
index 9289943..a5451e3 100644
--- a/packages/flutter_tools/lib/src/commands/daemon.dart
+++ b/packages/flutter_tools/lib/src/commands/daemon.dart
@@ -143,8 +143,12 @@
         throw 'no domain for method: $method';
 
       _domainMap[prefix].handleCommand(name, id, request['params'] ?? const <String, dynamic>{});
-    } catch (error) {
-      _send(<String, dynamic>{'id': id, 'error': _toJsonable(error)});
+    } catch (error, trace) {
+      _send(<String, dynamic>{
+        'id': id,
+        'error': _toJsonable(error),
+        'trace': '$trace',
+      });
     }
   }
 
@@ -184,14 +188,18 @@
       if (_handlers.containsKey(command))
         return _handlers[command](args);
       throw 'command not understood: $name.$command';
-    }).then<Null>((dynamic result) {
+    }).then<dynamic>((dynamic result) {
       if (result == null) {
         _send(<String, dynamic>{'id': id});
       } else {
         _send(<String, dynamic>{'id': id, 'result': _toJsonable(result)});
       }
     }).catchError((dynamic error, dynamic trace) {
-      _send(<String, dynamic>{'id': id, 'error': _toJsonable(error)});
+      _send(<String, dynamic>{
+        'id': id,
+        'error': _toJsonable(error),
+        'trace': '$trace',
+      });
     });
   }
 
@@ -393,7 +401,7 @@
       _sendAppEvent(app, 'started');
     });
 
-    await app._runInZone(this, () async {
+    await app._runInZone<Null>(this, () async {
       try {
         await runner.run(
           connectionInfoCompleter: connectionInfoCompleter,
@@ -401,8 +409,11 @@
           route: route,
         );
         _sendAppEvent(app, 'stop');
-      } catch (error) {
-        _sendAppEvent(app, 'stop', <String, dynamic>{'error': _toJsonable(error)});
+      } catch (error, trace) {
+        _sendAppEvent(app, 'stop', <String, dynamic>{
+          'error': _toJsonable(error),
+          'trace': '$trace',
+        });
       } finally {
         fs.currentDirectory = cwd;
         _apps.remove(app);
@@ -429,7 +440,7 @@
     if (_inProgressHotReload != null)
       throw 'hot restart already in progress';
 
-    _inProgressHotReload = app._runInZone(this, () {
+    _inProgressHotReload = app._runInZone<OperationResult>(this, () {
       return app.restart(fullRestart: fullRestart, pauseAfterRestart: pauseAfterRestart);
     });
     return _inProgressHotReload.whenComplete(() {
@@ -449,7 +460,7 @@
   Future<Map<String, dynamic>> callServiceExtension(Map<String, dynamic> args) async {
     final String appId = _getStringArg(args, 'appId', required: true);
     final String methodName = _getStringArg(args, 'methodName');
-    final Map<String, String> params = args['params'] ?? <String, String>{};
+    final Map<String, dynamic> params = args['params'] == null ? <String, dynamic>{} : castStringKeyedMap(args['params']);
 
     final AppInstance app = _getApp(appId);
     if (app == null)
@@ -741,10 +752,10 @@
     _logger.close();
   }
 
-  dynamic _runInZone(AppDomain domain, dynamic method()) {
+  Future<T> _runInZone<T>(AppDomain domain, dynamic method()) {
     _logger ??= new _AppRunLogger(domain, this, parent: logToStdout ? logger : null);
 
-    return context.run<dynamic>(
+    return context.run<T>(
       body: method,
       overrides: <Type, Generator>{
         Logger: () => _logger,
diff --git a/packages/flutter_tools/lib/src/dart/analysis.dart b/packages/flutter_tools/lib/src/dart/analysis.dart
index 65e6d10..104e2f9 100644
--- a/packages/flutter_tools/lib/src/dart/analysis.dart
+++ b/packages/flutter_tools/lib/src/dart/analysis.dart
@@ -10,6 +10,7 @@
 import '../base/io.dart';
 import '../base/platform.dart';
 import '../base/process_manager.dart';
+import '../base/utils.dart';
 import '../globals.dart';
 
 class AnalysisServer {
@@ -136,8 +137,10 @@
   void _handleAnalysisIssues(Map<String, dynamic> issueInfo) {
     // {"event":"analysis.errors","params":{"file":"/Users/.../lib/main.dart","errors":[]}}
     final String file = issueInfo['file'];
-    final List<AnalysisError> errors = issueInfo['errors']
-        .map((Map<String, dynamic> json) => new AnalysisError(json))
+    final List<dynamic> errorsList = issueInfo['errors'];
+    final List<AnalysisError> errors = errorsList
+        .map<Map<String, dynamic>>(castStringKeyedMap)
+        .map<AnalysisError>((Map<String, dynamic> json) => new AnalysisError(json))
         .toList();
     if (!_errorsController.isClosed)
       _errorsController.add(new FileAnalysisErrors(file, errors));
diff --git a/packages/flutter_tools/lib/src/flutter_manifest.dart b/packages/flutter_tools/lib/src/flutter_manifest.dart
index 80fef7a..5a26f6d 100644
--- a/packages/flutter_tools/lib/src/flutter_manifest.dart
+++ b/packages/flutter_tools/lib/src/flutter_manifest.dart
@@ -10,6 +10,7 @@
 import 'package:yaml/yaml.dart';
 
 import 'base/file_system.dart';
+import 'base/utils.dart';
 import 'cache.dart';
 import 'globals.dart';
 
@@ -33,13 +34,25 @@
     return _createFromYaml(loadYaml(manifest));
   }
 
-  static Future<FlutterManifest> _createFromYaml(Object yamlDocument) async {
+  static Future<FlutterManifest> _createFromYaml(dynamic yamlDocument) async {
     final FlutterManifest pubspec = new FlutterManifest._();
     if (yamlDocument != null && !await _validate(yamlDocument))
       return null;
 
-    pubspec._descriptor = yamlDocument ?? <String, dynamic>{};
-    pubspec._flutterDescriptor = pubspec._descriptor['flutter'] ?? <String, dynamic>{};
+    final Map<dynamic, dynamic> yamlMap = yamlDocument;
+    if (yamlMap != null) {
+      pubspec._descriptor = yamlMap.cast<String, dynamic>();
+    } else {
+      pubspec._descriptor = <String, dynamic>{};
+    }
+
+    final Map<dynamic, dynamic> flutterMap = pubspec._descriptor['flutter'];
+    if (flutterMap != null) {
+      pubspec._flutterDescriptor = flutterMap.cast<String, dynamic>();
+    } else {
+      pubspec._flutterDescriptor = <String, dynamic>{};
+    }
+
     return pubspec;
   }
 
@@ -105,11 +118,22 @@
   bool get isModule => moduleDescriptor != null;
 
   List<Map<String, dynamic>> get fontsDescriptor {
-   return _flutterDescriptor['fonts'] ?? const <Map<String, dynamic>>[];
+    final List<dynamic> fontList = _flutterDescriptor['fonts'];
+    return fontList == null
+        ? const <Map<String, dynamic>>[]
+        : fontList.map<Map<String, dynamic>>(castStringKeyedMap).toList();
   }
 
   List<Uri> get assets {
-    return _flutterDescriptor['assets']?.map(Uri.encodeFull)?.map(Uri.parse)?.toList() ?? const <Uri>[];
+    final List<dynamic> assets = _flutterDescriptor['assets'];
+    if (assets == null) {
+      return const <Uri>[];
+    }
+    return assets
+        .cast<String>()
+        .map<String>(Uri.encodeFull)
+        ?.map<Uri>(Uri.parse)
+        ?.toList();
   }
 
   List<Font> _fonts;
@@ -124,8 +148,8 @@
       return <Font>[];
 
     final List<Font> fonts = <Font>[];
-    for (Map<String, dynamic> fontFamily in _flutterDescriptor['fonts']) {
-      final List<Map<String, dynamic>> fontFiles = fontFamily['fonts'];
+    for (Map<String, dynamic> fontFamily in fontsDescriptor) {
+      final List<dynamic> fontFiles = fontFamily['fonts'];
       final String familyName = fontFamily['family'];
       if (familyName == null) {
         printError('Warning: Missing family name for font.', emphasis: true);
@@ -137,7 +161,7 @@
       }
 
       final List<FontAsset> fontAssets = <FontAsset>[];
-      for (Map<String, dynamic> fontFile in fontFiles) {
+      for (Map<dynamic, dynamic> fontFile in fontFiles) {
         final String asset = fontFile['asset'];
         if (asset == null) {
           printError('Warning: Missing asset in fonts for $familyName', emphasis: true);
@@ -216,7 +240,7 @@
   );
 }
 
-Future<bool> _validate(Object manifest) async {
+Future<bool> _validate(dynamic manifest) async {
   final String schemaPath = buildSchemaPath(fs);
 
   final String schemaData = fs.file(schemaPath).readAsStringSync();
diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart
index 2860303..a95f504 100644
--- a/packages/flutter_tools/lib/src/ios/mac.dart
+++ b/packages/flutter_tools/lib/src/ios/mac.dart
@@ -395,7 +395,7 @@
             '-allowProvisioningUpdates',
             '-allowProvisioningDeviceRegistration',
           ].contains(buildCommand);
-        }),
+        }).toList(),
     workingDirectory: app.appDirectory,
   ));
 
diff --git a/packages/flutter_tools/lib/src/ios/simulators.dart b/packages/flutter_tools/lib/src/ios/simulators.dart
index d80fc2a..af9d646 100644
--- a/packages/flutter_tools/lib/src/ios/simulators.dart
+++ b/packages/flutter_tools/lib/src/ios/simulators.dart
@@ -14,6 +14,7 @@
 import '../base/platform.dart';
 import '../base/process.dart';
 import '../base/process_manager.dart';
+import '../base/utils.dart';
 import '../build_info.dart';
 import '../bundle.dart' as bundle;
 import '../device.dart';
@@ -95,7 +96,7 @@
 
     for (String deviceCategory in devicesSection.keys) {
       final List<dynamic> devicesData = devicesSection[deviceCategory];
-      for (Map<String, dynamic> data in devicesData.map(_castStringKeyedMap)) {
+      for (Map<String, dynamic> data in devicesData.map<Map<String, dynamic>>(castStringKeyedMap)) {
         devices.add(new SimDevice(deviceCategory, data));
       }
     }
@@ -103,11 +104,6 @@
     return devices;
   }
 
-  Map<String, dynamic> _castStringKeyedMap(dynamic untyped) {
-    final Map<dynamic, dynamic> map = untyped;
-    return map.cast<String, dynamic>();
-  }
-
   /// Returns all the connected simulator devices.
   List<SimDevice> getConnectedDevices() {
     return getDevices().where((SimDevice device) => device.isBooted).toList();
@@ -123,23 +119,23 @@
     ]);
   }
 
-  Future<Null> install(String deviceId, String appPath) {
+  Future<RunResult> install(String deviceId, String appPath) {
     return runCheckedAsync(<String>[_xcrunPath, 'simctl', 'install', deviceId, appPath]);
   }
 
-  Future<Null> uninstall(String deviceId, String appId) {
+  Future<RunResult> uninstall(String deviceId, String appId) {
     return runCheckedAsync(<String>[_xcrunPath, 'simctl', 'uninstall', deviceId, appId]);
   }
 
-  Future<Null> launch(String deviceId, String appIdentifier, [List<String> launchArgs]) {
+  Future<RunResult> launch(String deviceId, String appIdentifier, [List<String> launchArgs]) {
     final List<String> args = <String>[_xcrunPath, 'simctl', 'launch', deviceId, appIdentifier];
     if (launchArgs != null)
       args.addAll(launchArgs);
     return runCheckedAsync(args);
   }
 
-  Future<void> takeScreenshot(String deviceId, String outputPath) {
-    return runCheckedAsync(<String>[_xcrunPath, 'simctl', 'io', deviceId, 'screenshot', outputPath]);
+  Future<void> takeScreenshot(String deviceId, String outputPath) async {
+    await runCheckedAsync(<String>[_xcrunPath, 'simctl', 'io', deviceId, 'screenshot', outputPath]);
   }
 }
 
@@ -350,14 +346,14 @@
     return criteria.reduce((bool a, bool b) => a && b);
   }
 
-  Future<Null> _setupUpdatedApplicationBundle(ApplicationPackage app, BuildInfo buildInfo, String mainPath, bool usesTerminalUi) async {
+  Future<void> _setupUpdatedApplicationBundle(ApplicationPackage app, BuildInfo buildInfo, String mainPath, bool usesTerminalUi) async {
     await _sideloadUpdatedAssetsForInstalledApplicationBundle(app, buildInfo, mainPath);
 
     if (!await _applicationIsInstalledAndRunning(app))
       return _buildAndInstallApplicationBundle(app, buildInfo, mainPath, usesTerminalUi);
   }
 
-  Future<Null> _buildAndInstallApplicationBundle(ApplicationPackage app, BuildInfo buildInfo, String mainPath, bool usesTerminalUi) async {
+  Future<void> _buildAndInstallApplicationBundle(ApplicationPackage app, BuildInfo buildInfo, String mainPath, bool usesTerminalUi) async {
     // Step 1: Build the Xcode project.
     // The build mode for the simulator is always debug.
 
@@ -389,7 +385,7 @@
     await SimControl.instance.install(id, fs.path.absolute(bundle.path));
   }
 
-  Future<Null> _sideloadUpdatedAssetsForInstalledApplicationBundle(ApplicationPackage app, BuildInfo buildInfo, String mainPath) {
+  Future<void> _sideloadUpdatedAssetsForInstalledApplicationBundle(ApplicationPackage app, BuildInfo buildInfo, String mainPath) {
     // When running in previewDart2 mode, we still need to run compiler to
     // produce kernel file for the application.
     return bundle.build(
diff --git a/packages/flutter_tools/lib/src/version.dart b/packages/flutter_tools/lib/src/version.dart
index c08c444..6947a27 100644
--- a/packages/flutter_tools/lib/src/version.dart
+++ b/packages/flutter_tools/lib/src/version.dart
@@ -388,7 +388,7 @@
     return const VersionCheckStamp();
   }
 
-  static VersionCheckStamp fromJson(Map<String, String> jsonObject) {
+  static VersionCheckStamp fromJson(Map<String, dynamic> jsonObject) {
     DateTime readDateTime(String property) {
       return jsonObject.containsKey(property)
           ? DateTime.parse(jsonObject[property])
diff --git a/packages/flutter_tools/lib/src/vmservice.dart b/packages/flutter_tools/lib/src/vmservice.dart
index 1be0bd7..d2c05d8 100644
--- a/packages/flutter_tools/lib/src/vmservice.dart
+++ b/packages/flutter_tools/lib/src/vmservice.dart
@@ -17,6 +17,7 @@
 import 'base/common.dart';
 import 'base/file_system.dart';
 import 'base/io.dart' as io;
+import 'base/utils.dart';
 import 'globals.dart';
 import 'vmservice_record_replay.dart';
 
@@ -256,7 +257,10 @@
 
   /// Whether our connection to the VM service has been closed;
   bool get isClosed => _peer.isClosed;
-  Future<Null> get done => _peer.done;
+
+  Future<Null> get done async {
+    await _peer.done;
+  }
 
   // Events
   Future<Stream<ServiceEvent>> get onDebugEvent => onEvent('Debug');
@@ -284,7 +288,7 @@
     Map<String, dynamic> params,
   ) {
     return Future.any(<Future<Map<String, dynamic>>>[
-      _peer.sendRequest(method, params),
+      _peer.sendRequest(method, params).then<Map<String, dynamic>>(castStringKeyedMap),
       _connectionError.future,
     ]);
   }
@@ -334,8 +338,8 @@
   }
 
   /// Reloads the VM.
-  Future<VM> getVM() {
-    return _vm.reload();
+  Future<VM> getVM() async {
+    return await _vm.reload();
   }
 
   Future<Null> waitForViews({int attempts = 5, int attemptSeconds = 1}) async {
@@ -683,7 +687,7 @@
     _embedder = map['_embedder'];
 
     // Remove any isolates which are now dead from the isolate cache.
-    _removeDeadIsolates(map['isolates']);
+    _removeDeadIsolates(map['isolates'].cast<Isolate>());
   }
 
   final Map<String, ServiceObject> _cache = <String,ServiceObject>{};
@@ -851,7 +855,7 @@
   }
 
   /// Invoke the RPC and return a [ServiceObject] response.
-  Future<ServiceObject> invokeRpc(String method, {
+  Future<T> invokeRpc<T extends ServiceObject>(String method, {
     Map<String, dynamic> params = const <String, dynamic>{},
     Duration timeout,
   }) async {
@@ -922,13 +926,13 @@
                                Uri packages,
                                Uri assetsDirectory) {
     // TODO(goderbauer): Transfer Uri (instead of file path) when remote end supports it.
-    return invokeRpc('_flutter.runInView',
-                    params: <String, dynamic> {
-                      'viewId': viewId,
-                      'mainScript': main.toFilePath(windows: false),
-                      'packagesFile': packages.toFilePath(windows: false),
-                      'assetDirectory': assetsDirectory.toFilePath(windows: false)
-                    });
+    return invokeRpc<ServiceMap>('_flutter.runInView',
+      params: <String, dynamic> {
+        'viewId': viewId,
+        'mainScript': main.toFilePath(windows: false),
+        'packagesFile': packages.toFilePath(windows: false),
+        'assetDirectory': assetsDirectory.toFilePath(windows: false)
+    });
   }
 
   Future<Map<String, dynamic>> clearVMTimeline() {
@@ -1324,7 +1328,7 @@
   }
 
   Future<String> flutterPlatformOverride([String platform]) async {
-    final Map<String, String> result = await invokeFlutterExtensionRpcRaw(
+    final Map<String, dynamic> result = await invokeFlutterExtensionRpcRaw(
       'ext.flutter.platformOverride',
       params: platform != null ? <String, dynamic>{ 'value': platform } : <String, String>{},
       timeout: const Duration(seconds: 5),