implicit-casts:false on flutter_tools/lib (#44447)

* implicit-casts:false on flutter_tools/lib

* address review comments

* use castStringKeyedMap

* introduce {bool,string,strings}Arg

* fix ci
This commit is contained in:
Alexandre Ardhuin 2019-11-19 07:57:42 +01:00 committed by GitHub
parent 152e6ec006
commit adc7351046
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
110 changed files with 796 additions and 773 deletions

View File

@ -57,11 +57,11 @@ Future<void> run(List<String> args) async {
} }
Cache.flutterRoot = platform.environment['FLUTTER_ROOT']; Cache.flutterRoot = platform.environment['FLUTTER_ROOT'];
final String assetDir = argResults[_kOptionAsset]; final String assetDir = argResults[_kOptionAsset] as String;
final AssetBundle assets = await buildAssets( final AssetBundle assets = await buildAssets(
manifestPath: argResults[_kOptionManifest] ?? defaultManifestPath, manifestPath: argResults[_kOptionManifest] as String ?? defaultManifestPath,
assetDirPath: assetDir, assetDirPath: assetDir,
packagesPath: argResults[_kOptionPackages], packagesPath: argResults[_kOptionPackages] as String,
includeDefaultFonts: false, includeDefaultFonts: false,
); );
@ -77,8 +77,8 @@ Future<void> run(List<String> args) async {
}); });
await Future.wait<void>(calls); await Future.wait<void>(calls);
final String outputMan = argResults[_kOptionAssetManifestOut]; final String outputMan = argResults[_kOptionAssetManifestOut] as String;
await writeFuchsiaManifest(assets, argResults[_kOptionAsset], outputMan, argResults[_kOptionComponentName]); await writeFuchsiaManifest(assets, argResults[_kOptionAsset] as String, outputMan, argResults[_kOptionComponentName] as String);
} }
Future<void> writeFuchsiaManifest(AssetBundle assets, String outputBase, String fileDest, String componentName) async { Future<void> writeFuchsiaManifest(AssetBundle assets, String outputBase, String fileDest, String componentName) async {

View File

@ -35,13 +35,13 @@ String originalWorkingDirectory;
Future<void> main(List<String> args) async { Future<void> main(List<String> args) async {
final ArgResults argResults = parser.parse(args); final ArgResults argResults = parser.parse(args);
final bool verbose = argResults['verbose']; final bool verbose = argResults['verbose'] as bool;
final String target = argResults['target']; final String target = argResults['target'] as String;
final List<String> targetParts = _extractPathAndName(target); final List<String> targetParts = _extractPathAndName(target);
final String path = targetParts[0]; final String path = targetParts[0];
final String name = targetParts[1]; final String name = targetParts[1];
final File dartSdk = fs.file(argResults['dart-sdk']); final File dartSdk = fs.file(argResults['dart-sdk']);
final String buildDirectory = argResults['build-dir']; final String buildDirectory = argResults['build-dir'] as String;
final File frontendServer = fs.file('$buildDirectory/host_x64/gen/third_party/flutter/frontend_server/frontend_server_tool.snapshot'); final File frontendServer = fs.file('$buildDirectory/host_x64/gen/third_party/flutter/frontend_server/frontend_server_tool.snapshot');
final File sshConfig = fs.file('$buildDirectory/ssh-keys/ssh_config'); final File sshConfig = fs.file('$buildDirectory/ssh-keys/ssh_config');
final File devFinder = fs.file(argResults['dev-finder']); final File devFinder = fs.file(argResults['dev-finder']);
@ -69,13 +69,13 @@ Future<void> main(List<String> args) async {
} }
// Check for a package with a lib directory. // Check for a package with a lib directory.
final String entrypoint = argResults['entrypoint']; final String entrypoint = argResults['entrypoint'] as String;
String targetFile = 'lib/$entrypoint'; String targetFile = 'lib/$entrypoint';
if (!fs.file(targetFile).existsSync()) { if (!fs.file(targetFile).existsSync()) {
// Otherwise assume the package is flat. // Otherwise assume the package is flat.
targetFile = entrypoint; targetFile = entrypoint;
} }
final String deviceName = argResults['device']; final String deviceName = argResults['device'] as String;
final List<String> command = <String>[ final List<String> command = <String>[
'attach', 'attach',
'--module', '--module',

View File

@ -86,7 +86,7 @@ Future<void> run(List<String> args) async {
throwToolExit('Cannot find SDK files at ${sdkRootSrc.path}'); throwToolExit('Cannot find SDK files at ${sdkRootSrc.path}');
} }
Directory coverageDirectory; Directory coverageDirectory;
final String coverageDirectoryPath = argResults[_kOptionCoverageDirectory]; final String coverageDirectoryPath = argResults[_kOptionCoverageDirectory] as String;
if (coverageDirectoryPath != null) { if (coverageDirectoryPath != null) {
if (!fs.isDirectorySync(coverageDirectoryPath)) { if (!fs.isDirectorySync(coverageDirectoryPath)) {
throwToolExit('Cannot find coverage directory at $coverageDirectoryPath'); throwToolExit('Cannot find coverage directory at $coverageDirectoryPath');
@ -111,11 +111,11 @@ Future<void> run(List<String> args) async {
fs.link(sdkRootDest.childFile('platform.dill').path).createSync('platform_strong.dill'); fs.link(sdkRootDest.childFile('platform.dill').path).createSync('platform_strong.dill');
PackageMap.globalPackagesPath = PackageMap.globalPackagesPath =
fs.path.normalize(fs.path.absolute(argResults[_kOptionPackages])); fs.path.normalize(fs.path.absolute(argResults[_kOptionPackages] as String));
Directory testDirectory; Directory testDirectory;
CoverageCollector collector; CoverageCollector collector;
if (argResults['coverage']) { if (argResults['coverage'] as bool) {
collector = CoverageCollector( collector = CoverageCollector(
libraryPredicate: (String libraryName) { libraryPredicate: (String libraryName) {
// If we have a specified coverage directory then accept all libraries. // If we have a specified coverage directory then accept all libraries.
@ -134,7 +134,7 @@ Future<void> run(List<String> args) async {
final Map<String, String> tests = <String, String>{}; final Map<String, String> tests = <String, String>{};
final List<Map<String, dynamic>> jsonList = List<Map<String, dynamic>>.from( final List<Map<String, dynamic>> jsonList = List<Map<String, dynamic>>.from(
json.decode(fs.file(argResults[_kOptionTests]).readAsStringSync())); json.decode(fs.file(argResults[_kOptionTests]).readAsStringSync()) as List<Map<String, dynamic>>);
for (Map<String, dynamic> map in jsonList) { for (Map<String, dynamic> map in jsonList) {
final String source = fs.file(map['source']).resolveSymbolicLinksSync(); final String source = fs.file(map['source']).resolveSymbolicLinksSync();
final String dill = fs.file(map['dill']).resolveSymbolicLinksSync(); final String dill = fs.file(map['dill']).resolveSymbolicLinksSync();
@ -150,7 +150,7 @@ Future<void> run(List<String> args) async {
buildMode: BuildMode.debug, buildMode: BuildMode.debug,
precompiledDillFiles: tests, precompiledDillFiles: tests,
concurrency: math.max(1, platform.numberOfProcessors - 2), concurrency: math.max(1, platform.numberOfProcessors - 2),
icudtlPath: fs.path.absolute(argResults[_kOptionIcudtl]), icudtlPath: fs.path.absolute(argResults[_kOptionIcudtl] as String),
coverageDirectory: coverageDirectory, coverageDirectory: coverageDirectory,
); );
@ -163,7 +163,7 @@ Future<void> run(List<String> args) async {
} else { } else {
fs.currentDirectory = testDirectory; fs.currentDirectory = testDirectory;
} }
if (!await collector.collectCoverageData(argResults[_kOptionCoveragePath], coverageDirectory: coverageDirectory)) { if (!await collector.collectCoverageData(argResults[_kOptionCoveragePath] as String, coverageDirectory: coverageDirectory)) {
throwToolExit('Failed to collect coverage data'); throwToolExit('Failed to collect coverage data');
} }
} }

View File

@ -105,10 +105,10 @@ class AndroidDevice extends Device {
stderrEncoding: latin1, stderrEncoding: latin1,
); );
if (result.exitCode == 0 || allowHeapCorruptionOnWindows(result.exitCode)) { if (result.exitCode == 0 || allowHeapCorruptionOnWindows(result.exitCode)) {
_properties = parseAdbDeviceProperties(result.stdout); _properties = parseAdbDeviceProperties(result.stdout as String);
} else { } else {
printError('Error ${result.exitCode} retrieving device properties for $name:'); printError('Error ${result.exitCode} retrieving device properties for $name:');
printError(result.stderr); printError(result.stderr as String);
} }
} on ProcessException catch (error) { } on ProcessException catch (error) {
printError('Error retrieving device properties for $name: $error'); printError('Error retrieving device properties for $name: $error');
@ -334,18 +334,17 @@ class AndroidDevice extends Device {
} }
} }
String _getDeviceSha1Path(ApplicationPackage app) { String _getDeviceSha1Path(AndroidApk apk) {
return '/data/local/tmp/sky.${app.id}.sha1'; return '/data/local/tmp/sky.${apk.id}.sha1';
} }
Future<String> _getDeviceApkSha1(ApplicationPackage app) async { Future<String> _getDeviceApkSha1(AndroidApk apk) async {
final RunResult result = await processUtils.run( final RunResult result = await processUtils.run(
adbCommandForDevice(<String>['shell', 'cat', _getDeviceSha1Path(app)])); adbCommandForDevice(<String>['shell', 'cat', _getDeviceSha1Path(apk)]));
return result.stdout; return result.stdout;
} }
String _getSourceSha1(ApplicationPackage app) { String _getSourceSha1(AndroidApk apk) {
final AndroidApk apk = app;
final File shaFile = fs.file('${apk.file.path}.sha1'); final File shaFile = fs.file('${apk.file.path}.sha1');
return shaFile.existsSync() ? shaFile.readAsStringSync() : ''; return shaFile.existsSync() ? shaFile.readAsStringSync() : '';
} }
@ -354,7 +353,7 @@ class AndroidDevice extends Device {
String get name => modelID; String get name => modelID;
@override @override
Future<bool> isAppInstalled(ApplicationPackage app) async { Future<bool> isAppInstalled(AndroidApk app) async {
// This call takes 400ms - 600ms. // This call takes 400ms - 600ms.
try { try {
final RunResult listOut = await runAdbCheckedAsync(<String>['shell', 'pm', 'list', 'packages', app.id]); final RunResult listOut = await runAdbCheckedAsync(<String>['shell', 'pm', 'list', 'packages', app.id]);
@ -366,16 +365,15 @@ class AndroidDevice extends Device {
} }
@override @override
Future<bool> isLatestBuildInstalled(ApplicationPackage app) async { Future<bool> isLatestBuildInstalled(AndroidApk app) async {
final String installedSha1 = await _getDeviceApkSha1(app); final String installedSha1 = await _getDeviceApkSha1(app);
return installedSha1.isNotEmpty && installedSha1 == _getSourceSha1(app); return installedSha1.isNotEmpty && installedSha1 == _getSourceSha1(app);
} }
@override @override
Future<bool> installApp(ApplicationPackage app) async { Future<bool> installApp(AndroidApk app) async {
final AndroidApk apk = app; if (!app.file.existsSync()) {
if (!apk.file.existsSync()) { printError('"${fs.path.relative(app.file.path)}" does not exist.');
printError('"${fs.path.relative(apk.file.path)}" does not exist.');
return false; return false;
} }
@ -384,9 +382,9 @@ class AndroidDevice extends Device {
return false; return false;
} }
final Status status = logger.startProgress('Installing ${fs.path.relative(apk.file.path)}...', timeout: timeoutConfiguration.slowOperation); final Status status = logger.startProgress('Installing ${fs.path.relative(app.file.path)}...', timeout: timeoutConfiguration.slowOperation);
final RunResult installResult = await processUtils.run( final RunResult installResult = await processUtils.run(
adbCommandForDevice(<String>['install', '-t', '-r', apk.file.path])); adbCommandForDevice(<String>['install', '-t', '-r', app.file.path]));
status.stop(); status.stop();
// Some versions of adb exit with exit code 0 even on failure :( // Some versions of adb exit with exit code 0 even on failure :(
// Parsing the output to check for failures. // Parsing the output to check for failures.
@ -413,7 +411,7 @@ class AndroidDevice extends Device {
} }
@override @override
Future<bool> uninstallApp(ApplicationPackage app) async { Future<bool> uninstallApp(AndroidApk app) async {
if (!await _checkForSupportedAdbVersion() || if (!await _checkForSupportedAdbVersion() ||
!await _checkForSupportedAndroidVersion()) { !await _checkForSupportedAndroidVersion()) {
return false; return false;
@ -440,7 +438,7 @@ class AndroidDevice extends Device {
return true; return true;
} }
Future<bool> _installLatestApp(ApplicationPackage package) async { Future<bool> _installLatestApp(AndroidApk package) async {
final bool wasInstalled = await isAppInstalled(package); final bool wasInstalled = await isAppInstalled(package);
if (wasInstalled) { if (wasInstalled) {
if (await isLatestBuildInstalled(package)) { if (await isLatestBuildInstalled(package)) {
@ -470,7 +468,7 @@ class AndroidDevice extends Device {
@override @override
Future<LaunchResult> startApp( Future<LaunchResult> startApp(
ApplicationPackage package, { AndroidApk package, {
String mainPath, String mainPath,
String route, String route,
DebuggingOptions debuggingOptions, DebuggingOptions debuggingOptions,
@ -537,8 +535,7 @@ class AndroidDevice extends Device {
return LaunchResult.failed(); return LaunchResult.failed();
} }
final bool traceStartup = platformArgs['trace-startup'] ?? false; final bool traceStartup = platformArgs['trace-startup'] as bool ?? false;
final AndroidApk apk = package;
printTrace('$this startApp'); printTrace('$this startApp');
ProtocolDiscovery observatoryDiscovery; ProtocolDiscovery observatoryDiscovery;
@ -595,7 +592,7 @@ class AndroidDevice extends Device {
if (debuggingOptions.verboseSystemLogs) if (debuggingOptions.verboseSystemLogs)
...<String>['--ez', 'verbose-logging', 'true'], ...<String>['--ez', 'verbose-logging', 'true'],
], ],
apk.launchActivity, package.launchActivity,
]; ];
final String result = (await runAdbCheckedAsync(cmd)).stdout; final String result = (await runAdbCheckedAsync(cmd)).stdout;
// This invocation returns 0 even when it fails. // This invocation returns 0 even when it fails.
@ -636,7 +633,7 @@ class AndroidDevice extends Device {
bool get supportsHotRestart => true; bool get supportsHotRestart => true;
@override @override
Future<bool> stopApp(ApplicationPackage app) { Future<bool> stopApp(AndroidApk app) {
final List<String> command = adbCommandForDevice(<String>['shell', 'am', 'force-stop', app.id]); final List<String> command = adbCommandForDevice(<String>['shell', 'am', 'force-stop', app.id]);
return processUtils.stream(command).then<bool>( return processUtils.stream(command).then<bool>(
(int exitCode) => exitCode == 0 || allowHeapCorruptionOnWindows(exitCode)); (int exitCode) => exitCode == 0 || allowHeapCorruptionOnWindows(exitCode));
@ -648,7 +645,7 @@ class AndroidDevice extends Device {
} }
@override @override
DeviceLogReader getLogReader({ ApplicationPackage app }) { DeviceLogReader getLogReader({ AndroidApk app }) {
// The Android log reader isn't app-specific. // The Android log reader isn't app-specific.
_logReader ??= _AdbLogReader(this); _logReader ??= _AdbLogReader(this);
return _logReader; return _logReader;

View File

@ -304,7 +304,7 @@ class AndroidSdk {
String findAndroidHomeDir() { String findAndroidHomeDir() {
String androidHomeDir; String androidHomeDir;
if (config.containsKey('android-sdk')) { if (config.containsKey('android-sdk')) {
androidHomeDir = config.getValue('android-sdk'); androidHomeDir = config.getValue('android-sdk') as String;
} else if (platform.environment.containsKey(kAndroidHome)) { } else if (platform.environment.containsKey(kAndroidHome)) {
androidHomeDir = platform.environment[kAndroidHome]; androidHomeDir = platform.environment[kAndroidHome];
} else if (platform.environment.containsKey(kAndroidSdkRoot)) { } else if (platform.environment.containsKey(kAndroidSdkRoot)) {

View File

@ -8,6 +8,7 @@ import '../base/file_system.dart';
import '../base/platform.dart'; import '../base/platform.dart';
import '../base/process.dart'; import '../base/process.dart';
import '../base/process_manager.dart'; import '../base/process_manager.dart';
import '../base/utils.dart';
import '../base/version.dart'; import '../base/version.dart';
import '../globals.dart'; import '../globals.dart';
import '../ios/plist_parser.dart'; import '../ios/plist_parser.dart';
@ -45,14 +46,14 @@ class AndroidStudio implements Comparable<AndroidStudio> {
Map<String, dynamic> plistValues = PlistParser.instance.parseFile(plistFile); Map<String, dynamic> plistValues = PlistParser.instance.parseFile(plistFile);
// As AndroidStudio managed by JetBrainsToolbox could have a wrapper pointing to the real Android Studio. // As AndroidStudio managed by JetBrainsToolbox could have a wrapper pointing to the real Android Studio.
// Check if we've found a JetBrainsToolbox wrapper and deal with it properly. // Check if we've found a JetBrainsToolbox wrapper and deal with it properly.
final String jetBrainsToolboxAppBundlePath = plistValues['JetBrainsToolboxApp']; final String jetBrainsToolboxAppBundlePath = plistValues['JetBrainsToolboxApp'] as String;
if (jetBrainsToolboxAppBundlePath != null) { if (jetBrainsToolboxAppBundlePath != null) {
studioPath = fs.path.join(jetBrainsToolboxAppBundlePath, 'Contents'); studioPath = fs.path.join(jetBrainsToolboxAppBundlePath, 'Contents');
plistFile = fs.path.join(studioPath, 'Info.plist'); plistFile = fs.path.join(studioPath, 'Info.plist');
plistValues = PlistParser.instance.parseFile(plistFile); plistValues = PlistParser.instance.parseFile(plistFile);
} }
final String versionString = plistValues[PlistParser.kCFBundleShortVersionStringKey]; final String versionString = plistValues[PlistParser.kCFBundleShortVersionStringKey] as String;
Version version; Version version;
if (versionString != null) { if (versionString != null) {
@ -60,11 +61,11 @@ class AndroidStudio implements Comparable<AndroidStudio> {
} }
String pathsSelectorValue; String pathsSelectorValue;
final Map<String, dynamic> jvmOptions = plistValues['JVMOptions']; final Map<String, dynamic> jvmOptions = castStringKeyedMap(plistValues['JVMOptions']);
if (jvmOptions != null) { if (jvmOptions != null) {
final Map<String, dynamic> jvmProperties = jvmOptions['Properties']; final Map<String, dynamic> jvmProperties = castStringKeyedMap(jvmOptions['Properties']);
if (jvmProperties != null) { if (jvmProperties != null) {
pathsSelectorValue = jvmProperties['idea.paths.selector']; pathsSelectorValue = jvmProperties['idea.paths.selector'] as String;
} }
} }
final String presetPluginsPath = pathsSelectorValue == null final String presetPluginsPath = pathsSelectorValue == null
@ -149,7 +150,7 @@ class AndroidStudio implements Comparable<AndroidStudio> {
/// Locates the newest, valid version of Android Studio. /// Locates the newest, valid version of Android Studio.
static AndroidStudio latestValid() { static AndroidStudio latestValid() {
final String configuredStudio = config.getValue('android-studio-dir'); final String configuredStudio = config.getValue('android-studio-dir') as String;
if (configuredStudio != null) { if (configuredStudio != null) {
String configuredStudioPath = configuredStudio; String configuredStudioPath = configuredStudio;
if (platform.isMacOS && !configuredStudioPath.endsWith('Contents')) { if (platform.isMacOS && !configuredStudioPath.endsWith('Contents')) {
@ -201,7 +202,7 @@ class AndroidStudio implements Comparable<AndroidStudio> {
_checkForStudio('/Applications'); _checkForStudio('/Applications');
_checkForStudio(fs.path.join(homeDirPath, 'Applications')); _checkForStudio(fs.path.join(homeDirPath, 'Applications'));
final String configuredStudioDir = config.getValue('android-studio-dir'); final String configuredStudioDir = config.getValue('android-studio-dir') as String;
if (configuredStudioDir != null) { if (configuredStudioDir != null) {
FileSystemEntity configuredStudio = fs.file(configuredStudioDir); FileSystemEntity configuredStudio = fs.file(configuredStudioDir);
if (configuredStudio.basename == 'Contents') { if (configuredStudio.basename == 'Contents') {
@ -248,7 +249,7 @@ class AndroidStudio implements Comparable<AndroidStudio> {
} }
} }
final String configuredStudioDir = config.getValue('android-studio-dir'); final String configuredStudioDir = config.getValue('android-studio-dir') as String;
if (configuredStudioDir != null && !_hasStudioAt(configuredStudioDir)) { if (configuredStudioDir != null && !_hasStudioAt(configuredStudioDir)) {
studios.add(AndroidStudio(configuredStudioDir, studios.add(AndroidStudio(configuredStudioDir,
configured: configuredStudioDir)); configured: configuredStudioDir));

View File

@ -71,7 +71,7 @@ class NoAndroidStudioValidator extends DoctorValidator {
Future<ValidationResult> validate() async { Future<ValidationResult> validate() async {
final List<ValidationMessage> messages = <ValidationMessage>[]; final List<ValidationMessage> messages = <ValidationMessage>[];
final String cfgAndroidStudio = config.getValue('android-studio-dir'); final String cfgAndroidStudio = config.getValue('android-studio-dir') as String;
if (cfgAndroidStudio != null) { if (cfgAndroidStudio != null) {
messages.add(ValidationMessage.error(userMessages.androidStudioMissing(cfgAndroidStudio))); messages.add(ValidationMessage.error(userMessages.androidStudioMissing(cfgAndroidStudio)));
} }

View File

@ -83,7 +83,7 @@ class AndroidValidator extends DoctorValidator {
printTrace('java -version'); printTrace('java -version');
final ProcessResult result = await processManager.run(<String>[javaBinary, '-version']); final ProcessResult result = await processManager.run(<String>[javaBinary, '-version']);
if (result.exitCode == 0) { if (result.exitCode == 0) {
final List<String> versionLines = result.stderr.split('\n'); final List<String> versionLines = (result.stderr as String).split('\n');
javaVersionText = versionLines.length >= 2 ? versionLines[1] : versionLines[0]; javaVersionText = versionLines.length >= 2 ? versionLines[1] : versionLines[0];
} }
} catch (error) { } catch (error) {
@ -236,7 +236,7 @@ class AndroidLicenseValidator extends DoctorValidator {
try { try {
final ProcessResult result = await processManager.run(<String>[javaBinary, '-version']); final ProcessResult result = await processManager.run(<String>[javaBinary, '-version']);
if (result.exitCode == 0) { if (result.exitCode == 0) {
final List<String> versionLines = result.stderr.split('\n'); final List<String> versionLines = (result.stderr as String).split('\n');
javaVersion = versionLines.length >= 2 ? versionLines[1] : versionLines[0]; javaVersion = versionLines.length >= 2 ? versionLines[1] : versionLines[0];
} }
} catch (error) { } catch (error) {

View File

@ -281,7 +281,7 @@ Future<void> buildGradleApp({
command.add('-q'); command.add('-q');
} }
if (artifacts is LocalEngineArtifacts) { if (artifacts is LocalEngineArtifacts) {
final LocalEngineArtifacts localEngineArtifacts = artifacts; final LocalEngineArtifacts localEngineArtifacts = artifacts as LocalEngineArtifacts;
final Directory localEngineRepo = _getLocalEngineRepo( final Directory localEngineRepo = _getLocalEngineRepo(
engineOutPath: localEngineArtifacts.engineOutPath, engineOutPath: localEngineArtifacts.engineOutPath,
androidBuildInfo: androidBuildInfo, androidBuildInfo: androidBuildInfo,
@ -526,7 +526,7 @@ Future<void> buildGradleAar({
command.add('-Ptarget-platform=$targetPlatforms'); command.add('-Ptarget-platform=$targetPlatforms');
} }
if (artifacts is LocalEngineArtifacts) { if (artifacts is LocalEngineArtifacts) {
final LocalEngineArtifacts localEngineArtifacts = artifacts; final LocalEngineArtifacts localEngineArtifacts = artifacts as LocalEngineArtifacts;
final Directory localEngineRepo = _getLocalEngineRepo( final Directory localEngineRepo = _getLocalEngineRepo(
engineOutPath: localEngineArtifacts.engineOutPath, engineOutPath: localEngineArtifacts.engineOutPath,
androidBuildInfo: androidBuildInfo, androidBuildInfo: androidBuildInfo,

View File

@ -48,7 +48,7 @@ class ApplicationPackageFactory {
: AndroidApk.fromApk(applicationBinary); : AndroidApk.fromApk(applicationBinary);
case TargetPlatform.ios: case TargetPlatform.ios:
return applicationBinary == null return applicationBinary == null
? IOSApp.fromIosProject(FlutterProject.current().ios) ? await IOSApp.fromIosProject(FlutterProject.current().ios)
: IOSApp.fromPrebuiltApp(applicationBinary); : IOSApp.fromPrebuiltApp(applicationBinary);
case TargetPlatform.tester: case TargetPlatform.tester:
return FlutterTesterApp.fromCurrentDirectory(); return FlutterTesterApp.fromCurrentDirectory();
@ -225,7 +225,7 @@ class AndroidApk extends ApplicationPackage {
if (!(node is xml.XmlElement)) { if (!(node is xml.XmlElement)) {
continue; continue;
} }
final xml.XmlElement xmlElement = node; final xml.XmlElement xmlElement = node as xml.XmlElement;
final String name = xmlElement.getAttribute('android:name'); final String name = xmlElement.getAttribute('android:name');
if (name == 'android.intent.action.MAIN') { if (name == 'android.intent.action.MAIN') {
actionName = name; actionName = name;
@ -262,9 +262,8 @@ class AndroidApk extends ApplicationPackage {
String get name => file.basename; String get name => file.basename;
} }
/// Tests whether a [FileSystemEntity] is an iOS bundle directory /// Tests whether a [Directory] is an iOS bundle directory
bool _isBundleDirectory(FileSystemEntity entity) => bool _isBundleDirectory(Directory dir) => dir.path.endsWith('.app');
entity is Directory && entity.path.endsWith('.app');
abstract class IOSApp extends ApplicationPackage { abstract class IOSApp extends ApplicationPackage {
IOSApp({@required String projectBundleId}) : super(id: projectBundleId); IOSApp({@required String projectBundleId}) : super(id: projectBundleId);
@ -301,7 +300,7 @@ abstract class IOSApp extends ApplicationPackage {
return null; return null;
} }
try { try {
bundleDir = payloadDir.listSync().singleWhere(_isBundleDirectory); bundleDir = payloadDir.listSync().whereType<Directory>().singleWhere(_isBundleDirectory);
} on StateError { } on StateError {
printError( printError(
'Invalid prebuilt iOS ipa. Does not contain a single app bundle.'); 'Invalid prebuilt iOS ipa. Does not contain a single app bundle.');
@ -469,22 +468,21 @@ class _Element extends _Entry {
} }
_Attribute firstAttribute(String name) { _Attribute firstAttribute(String name) {
return children.firstWhere( return children.whereType<_Attribute>().firstWhere(
(_Entry e) => e is _Attribute && e.key.startsWith(name), (_Attribute e) => e.key.startsWith(name),
orElse: () => null, orElse: () => null,
); );
} }
_Element firstElement(String name) { _Element firstElement(String name) {
return children.firstWhere( return children.whereType<_Element>().firstWhere(
(_Entry e) => e is _Element && e.name.startsWith(name), (_Element e) => e.name.startsWith(name),
orElse: () => null, orElse: () => null,
); );
} }
Iterable<_Entry> allElements(String name) { Iterable<_Element> allElements(String name) {
return children.where( return children.whereType<_Element>().where((_Element e) => e.name.startsWith(name));
(_Entry e) => e is _Element && e.name.startsWith(name));
} }
} }
@ -510,8 +508,7 @@ class ApkManifestData {
static bool isAttributeWithValuePresent(_Element baseElement, static bool isAttributeWithValuePresent(_Element baseElement,
String childElement, String attributeName, String attributeValue) { String childElement, String attributeName, String attributeValue) {
final Iterable<_Element> allElements = baseElement.allElements( final Iterable<_Element> allElements = baseElement.allElements(childElement);
childElement).cast<_Element>();
for (_Element oneElement in allElements) { for (_Element oneElement in allElements) {
final String elementAttributeValue = oneElement final String elementAttributeValue = oneElement
?.firstAttribute(attributeName) ?.firstAttribute(attributeName)
@ -562,14 +559,12 @@ class ApkManifestData {
final _Element application = manifest.firstElement('application'); final _Element application = manifest.firstElement('application');
assert(application != null); assert(application != null);
final Iterable<_Entry> activities = application.allElements('activity'); final Iterable<_Element> activities = application.allElements('activity');
_Element launchActivity; _Element launchActivity;
for (_Element activity in activities) { for (_Element activity in activities) {
final _Attribute enabled = activity.firstAttribute('android:enabled'); final _Attribute enabled = activity.firstAttribute('android:enabled');
final Iterable<_Element> intentFilters = activity final Iterable<_Element> intentFilters = activity.allElements('intent-filter');
.allElements('intent-filter')
.cast<_Element>();
final bool isEnabledByDefault = enabled == null; final bool isEnabledByDefault = enabled == null;
final bool isExplicitlyEnabled = enabled != null && enabled.value.contains('0xffffffff'); final bool isExplicitlyEnabled = enabled != null && enabled.value.contains('0xffffffff');
if (!(isEnabledByDefault || isExplicitlyEnabled)) { if (!(isEnabledByDefault || isExplicitlyEnabled)) {

View File

@ -291,10 +291,10 @@ class _Asset {
if (other.runtimeType != runtimeType) { if (other.runtimeType != runtimeType) {
return false; return false;
} }
final _Asset otherAsset = other; return other is _Asset
return otherAsset.baseDir == baseDir && other.baseDir == baseDir
&& otherAsset.relativeUri == relativeUri && other.relativeUri == relativeUri
&& otherAsset.entryUri == entryUri; && other.entryUri == entryUri;
} }
@override @override
@ -315,7 +315,7 @@ Map<String, dynamic> _readMaterialFontsManifest() {
final Map<String, dynamic> _materialFontsManifest = _readMaterialFontsManifest(); final Map<String, dynamic> _materialFontsManifest = _readMaterialFontsManifest();
List<Map<String, dynamic>> _getMaterialFonts(String fontSet) { List<Map<String, dynamic>> _getMaterialFonts(String fontSet) {
final List<dynamic> fontsList = _materialFontsManifest[fontSet]; final List<dynamic> fontsList = _materialFontsManifest[fontSet] as List<dynamic>;
return fontsList?.map<Map<String, dynamic>>(castStringKeyedMap)?.toList(); return fontsList?.map<Map<String, dynamic>>(castStringKeyedMap)?.toList();
} }
@ -324,7 +324,7 @@ List<_Asset> _getMaterialAssets(String fontSet) {
for (Map<String, dynamic> family in _getMaterialFonts(fontSet)) { for (Map<String, dynamic> family in _getMaterialFonts(fontSet)) {
for (Map<dynamic, dynamic> font in family['fonts']) { for (Map<dynamic, dynamic> font in family['fonts']) {
final Uri entryUri = fs.path.toUri(font['asset']); final Uri entryUri = fs.path.toUri(font['asset'] as String);
result.add(_Asset( result.add(_Asset(
baseDir: fs.path.join(Cache.flutterRoot, 'bin', 'cache', 'artifacts', 'material_fonts'), baseDir: fs.path.join(Cache.flutterRoot, 'bin', 'cache', 'artifacts', 'material_fonts'),
relativeUri: Uri(path: entryUri.pathSegments.last), relativeUri: Uri(path: entryUri.pathSegments.last),

View File

@ -99,9 +99,9 @@ Future<T> asyncGuard<T>(
completer.completeError(e, s); completer.completeError(e, s);
return; return;
} }
if (onError is _BinaryOnError) { if (onError is _BinaryOnError<T>) {
completer.complete(onError(e, s)); completer.complete(onError(e, s));
} else if (onError is _UnaryOnError) { } else if (onError is _UnaryOnError<T>) {
completer.complete(onError(e)); completer.complete(onError(e));
} }
} }

View File

@ -5,12 +5,13 @@
import '../convert.dart'; import '../convert.dart';
import 'context.dart'; import 'context.dart';
import 'file_system.dart'; import 'file_system.dart';
import 'utils.dart';
class Config { class Config {
Config([File configFile]) { Config([File configFile]) {
_configFile = configFile ?? fs.file(fs.path.join(userHomePath(), '.flutter_settings')); _configFile = configFile ?? fs.file(fs.path.join(userHomePath(), '.flutter_settings'));
if (_configFile.existsSync()) { if (_configFile.existsSync()) {
_values = json.decode(_configFile.readAsStringSync()); _values = castStringKeyedMap(json.decode(_configFile.readAsStringSync()));
} }
} }

View File

@ -11,6 +11,7 @@ import '../globals.dart';
import '../version.dart'; import '../version.dart';
import 'file_system.dart'; import 'file_system.dart';
import 'platform.dart'; import 'platform.dart';
import 'utils.dart';
typedef FingerprintPathFilter = bool Function(String path); typedef FingerprintPathFilter = bool Function(String path);
@ -130,14 +131,14 @@ class Fingerprint {
/// Throws [ArgumentError], if there is a version mismatch between the /// Throws [ArgumentError], if there is a version mismatch between the
/// serializing framework and this framework. /// serializing framework and this framework.
Fingerprint.fromJson(String jsonData) { Fingerprint.fromJson(String jsonData) {
final Map<String, dynamic> content = json.decode(jsonData); final Map<String, dynamic> content = castStringKeyedMap(json.decode(jsonData));
final String version = content['version']; final String version = content['version'] as String;
if (version != FlutterVersion.instance.frameworkRevision) { if (version != FlutterVersion.instance.frameworkRevision) {
throw ArgumentError('Incompatible fingerprint version: $version'); throw ArgumentError('Incompatible fingerprint version: $version');
} }
_checksums = content['files']?.cast<String,String>() ?? <String, String>{}; _checksums = castStringKeyedMap(content['files'])?.cast<String,String>() ?? <String, String>{};
_properties = content['properties']?.cast<String,String>() ?? <String, String>{}; _properties = castStringKeyedMap(content['properties'])?.cast<String,String>() ?? <String, String>{};
} }
Map<String, String> _checksums; Map<String, String> _checksums;
@ -157,9 +158,9 @@ class Fingerprint {
if (other.runtimeType != runtimeType) { if (other.runtimeType != runtimeType) {
return false; return false;
} }
final Fingerprint typedOther = other; return other is Fingerprint
return _equalMaps(typedOther._checksums, _checksums) && _equalMaps(other._checksums, _checksums)
&& _equalMaps(typedOther._properties, _properties); && _equalMaps(other._properties, _properties);
} }
bool _equalMaps(Map<String, String> a, Map<String, String> b) { bool _equalMaps(Map<String, String> a, Map<String, String> b) {

View File

@ -198,7 +198,7 @@ class Stdio {
if (stdin is! io.Stdin) { if (stdin is! io.Stdin) {
return _stdinHasTerminal = false; return _stdinHasTerminal = false;
} }
final io.Stdin ioStdin = stdin; final io.Stdin ioStdin = stdin as io.Stdin;
if (!ioStdin.hasTerminal) { if (!ioStdin.hasTerminal) {
return _stdinHasTerminal = false; return _stdinHasTerminal = false;
} }

View File

@ -151,7 +151,7 @@ class _PosixUtils extends OperatingSystemUtils {
if (result.exitCode != 0) { if (result.exitCode != 0) {
return const <File>[]; return const <File>[];
} }
final String stdout = result.stdout; final String stdout = result.stdout as String;
return stdout.trim().split('\n').map<File>((String path) => fs.file(path.trim())).toList(); return stdout.trim().split('\n').map<File>((String path) => fs.file(path.trim())).toList();
} }
@ -240,7 +240,7 @@ class _WindowsUtils extends OperatingSystemUtils {
if (result.exitCode != 0) { if (result.exitCode != 0) {
return const <File>[]; return const <File>[];
} }
final List<String> lines = result.stdout.trim().split('\n'); final List<String> lines = (result.stdout as String).trim().split('\n');
if (all) { if (all) {
return lines.map<File>((String path) => fs.file(path.trim())).toList(); return lines.map<File>((String path) => fs.file(path.trim())).toList();
} }
@ -254,7 +254,7 @@ class _WindowsUtils extends OperatingSystemUtils {
if (entity is! File) { if (entity is! File) {
continue; continue;
} }
final File file = entity; final File file = entity as File;
final String path = file.fileSystem.path.relative(file.path, from: data.path); final String path = file.fileSystem.path.relative(file.path, from: data.path);
final List<int> bytes = file.readAsBytesSync(); final List<int> bytes = file.readAsBytesSync();
archive.addFile(ArchiveFile(path, bytes.length, bytes)); archive.addFile(ArchiveFile(path, bytes.length, bytes));
@ -311,7 +311,7 @@ class _WindowsUtils extends OperatingSystemUtils {
if (!destFile.parent.existsSync()) { if (!destFile.parent.existsSync()) {
destFile.parent.createSync(recursive: true); destFile.parent.createSync(recursive: true);
} }
destFile.writeAsBytesSync(archiveFile.content); destFile.writeAsBytesSync(archiveFile.content as List<int>);
} }
} }
@ -328,7 +328,7 @@ class _WindowsUtils extends OperatingSystemUtils {
final ProcessResult result = processManager.runSync( final ProcessResult result = processManager.runSync(
<String>['ver'], runInShell: true); <String>['ver'], runInShell: true);
if (result.exitCode == 0) { if (result.exitCode == 0) {
_name = result.stdout.trim(); _name = (result.stdout as String).trim();
} else { } else {
_name = super.name; _name = super.name;
} }

View File

@ -121,17 +121,17 @@ class RunResult {
final List<String> _command; final List<String> _command;
int get exitCode => processResult.exitCode; int get exitCode => processResult.exitCode;
String get stdout => processResult.stdout; String get stdout => processResult.stdout as String;
String get stderr => processResult.stderr; String get stderr => processResult.stderr as String;
@override @override
String toString() { String toString() {
final StringBuffer out = StringBuffer(); final StringBuffer out = StringBuffer();
if (processResult.stdout.isNotEmpty) { if (stdout.isNotEmpty) {
out.writeln(processResult.stdout); out.writeln(stdout);
} }
if (processResult.stderr.isNotEmpty) { if (stderr.isNotEmpty) {
out.writeln(processResult.stderr); out.writeln(stderr);
} }
return out.toString().trimRight(); return out.toString().trimRight();
} }

View File

@ -51,5 +51,5 @@ Future<ReplayProcessManager> getReplayProcessManager(String location) async {
throwToolExit('Invalid replay-from: $error'); throwToolExit('Invalid replay-from: $error');
} }
return manager; return manager as ReplayProcessManager;
} }

View File

@ -116,7 +116,7 @@ class _DefaultSignals implements Signals {
Future<void> _handleSignal(ProcessSignal s) async { Future<void> _handleSignal(ProcessSignal s) async {
for (SignalHandler handler in _handlersList[s]) { for (SignalHandler handler in _handlersList[s]) {
try { try {
await asyncGuard<void>(() => handler(s)); await asyncGuard<void>(() async => handler(s));
} catch (e) { } catch (e) {
if (_errorStreamController.hasListener) { if (_errorStreamController.hasListener) {
_errorStreamController.add(e); _errorStreamController.add(e);

View File

@ -169,7 +169,7 @@ class AnsiTerminal {
if (!io.stdinHasTerminal) { if (!io.stdinHasTerminal) {
return; return;
} }
final io.Stdin stdin = io.stdin; final io.Stdin stdin = io.stdin as io.Stdin;
// The order of setting lineMode and echoMode is important on Windows. // The order of setting lineMode and echoMode is important on Windows.
if (value) { if (value) {
stdin.echoMode = false; stdin.echoMode = false;

View File

@ -251,8 +251,8 @@ class Uuid {
/// Given a data structure which is a Map of String to dynamic values, return /// 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. /// the same structure (`Map<String, dynamic>`) with the correct runtime types.
Map<String, dynamic> castStringKeyedMap(dynamic untyped) { Map<String, dynamic> castStringKeyedMap(dynamic untyped) {
final Map<dynamic, dynamic> map = untyped; final Map<dynamic, dynamic> map = untyped as Map<dynamic, dynamic>;
return map.cast<String, dynamic>(); return map?.cast<String, dynamic>();
} }
typedef AsyncCallback = Future<void> Function(); typedef AsyncCallback = Future<void> Function();

View File

@ -506,7 +506,7 @@ String getBuildDirectory() {
return 'build'; return 'build';
} }
final String buildDir = config.getValue('build-dir') ?? 'build'; final String buildDir = config.getValue('build-dir') as String ?? 'build';
if (fs.path.isAbsolute(buildDir)) { if (fs.path.isAbsolute(buildDir)) {
throw Exception( throw Exception(
'build-dir config setting in ${config.configPath} must be relative'); 'build-dir config setting in ${config.configPath} must be relative');

View File

@ -80,14 +80,14 @@ class BuildRunner extends CodeGenerator {
stringBuffer.writeln('dependencies:'); stringBuffer.writeln('dependencies:');
final YamlMap builders = flutterProject.builders; final YamlMap builders = flutterProject.builders;
if (builders != null) { if (builders != null) {
for (String name in builders.keys) { for (String name in builders.keys.cast<String>()) {
final Object node = builders[name]; final Object node = builders[name];
// For relative paths, make sure it is accounted for // For relative paths, make sure it is accounted for
// parent directories. // parent directories.
if (node is YamlMap && node['path'] != null) { if (node is YamlMap && node['path'] != null) {
final String path = node['path']; final String path = node['path'] as String;
if (fs.path.isRelative(path)) { if (fs.path.isRelative(path)) {
final String convertedPath = fs.path.join('..', '..', node['path']); final String convertedPath = fs.path.join('..', '..', path);
stringBuffer.writeln(' $name:'); stringBuffer.writeln(' $name:');
stringBuffer.writeln(' path: $convertedPath'); stringBuffer.writeln(' path: $convertedPath');
} else { } else {

View File

@ -118,12 +118,12 @@ final List<core.BuilderApplication> builders = <core.BuilderApplication>[
'flutter_tools:ddc', 'flutter_tools:ddc',
<Builder Function(BuilderOptions)>[ <Builder Function(BuilderOptions)>[
(BuilderOptions builderOptions) => KernelBuilder( (BuilderOptions builderOptions) => KernelBuilder(
platformSdk: builderOptions.config['flutterWebSdk'], platformSdk: builderOptions.config['flutterWebSdk'] as String,
summaryOnly: true, summaryOnly: true,
sdkKernelPath: path.join('kernel', 'flutter_ddc_sdk.dill'), sdkKernelPath: path.join('kernel', 'flutter_ddc_sdk.dill'),
outputExtension: ddcKernelExtension, outputExtension: ddcKernelExtension,
platform: flutterWebPlatform, platform: flutterWebPlatform,
librariesPath: path.absolute(path.join(builderOptions.config['flutterWebSdk'], 'libraries.json')), librariesPath: path.absolute(path.join(builderOptions.config['flutterWebSdk'] as String, 'libraries.json')),
kernelTargetName: 'ddc', kernelTargetName: 'ddc',
useIncrementalCompiler: true, useIncrementalCompiler: true,
trackUnusedInputs: true, trackUnusedInputs: true,
@ -132,9 +132,9 @@ final List<core.BuilderApplication> builders = <core.BuilderApplication>[
useIncrementalCompiler: true, useIncrementalCompiler: true,
trackUnusedInputs: true, trackUnusedInputs: true,
platform: flutterWebPlatform, platform: flutterWebPlatform,
platformSdk: builderOptions.config['flutterWebSdk'], platformSdk: builderOptions.config['flutterWebSdk'] as String,
sdkKernelPath: path.url.join('kernel', 'flutter_ddc_sdk.dill'), sdkKernelPath: path.url.join('kernel', 'flutter_ddc_sdk.dill'),
librariesPath: path.absolute(path.join(builderOptions.config['flutterWebSdk'], 'libraries.json')), librariesPath: path.absolute(path.join(builderOptions.config['flutterWebSdk'] as String, 'libraries.json')),
), ),
], ],
core.toAllPackages(), core.toAllPackages(),
@ -145,9 +145,9 @@ final List<core.BuilderApplication> builders = <core.BuilderApplication>[
'flutter_tools:entrypoint', 'flutter_tools:entrypoint',
<BuilderFactory>[ <BuilderFactory>[
(BuilderOptions options) => FlutterWebEntrypointBuilder( (BuilderOptions options) => FlutterWebEntrypointBuilder(
options.config[kReleaseFlag] ?? false, options.config[kReleaseFlag] as bool ?? false,
options.config[kProfileFlag] ?? false, options.config[kProfileFlag] as bool ?? false,
options.config['flutterWebSdk'], options.config['flutterWebSdk'] as String,
), ),
], ],
core.toRoot(), core.toRoot(),

View File

@ -227,7 +227,7 @@ abstract class ResidentWebRunner extends ResidentRunner {
try { try {
final vmservice.Response response = await _vmService final vmservice.Response response = await _vmService
?.callServiceExtension('ext.flutter.platformOverride'); ?.callServiceExtension('ext.flutter.platformOverride');
final String currentPlatform = response.json['value']; final String currentPlatform = response.json['value'] as String;
String nextPlatform; String nextPlatform;
switch (currentPlatform) { switch (currentPlatform) {
case 'android': case 'android':

View File

@ -427,7 +427,7 @@ class DebugAssetServer extends AssetServer {
partFiles = fs.systemTempDirectory.createTempSync('flutter_tool.') partFiles = fs.systemTempDirectory.createTempSync('flutter_tool.')
..createSync(); ..createSync();
for (ArchiveFile file in archive) { for (ArchiveFile file in archive) {
partFiles.childFile(file.name).writeAsBytesSync(file.content); partFiles.childFile(file.name).writeAsBytesSync(file.content as List<int>);
} }
} }
} }

View File

@ -13,6 +13,7 @@ import 'package:pool/pool.dart';
import '../base/context.dart'; import '../base/context.dart';
import '../base/file_system.dart'; import '../base/file_system.dart';
import '../base/platform.dart'; import '../base/platform.dart';
import '../base/utils.dart';
import '../cache.dart'; import '../cache.dart';
import '../convert.dart'; import '../convert.dart';
import '../globals.dart'; import '../globals.dart';
@ -464,7 +465,7 @@ class _BuildInstance {
final BuildSystemConfig buildSystemConfig; final BuildSystemConfig buildSystemConfig;
final Pool resourcePool; final Pool resourcePool;
final Map<String, AsyncMemoizer<void>> pending = <String, AsyncMemoizer<void>>{}; final Map<String, AsyncMemoizer<bool>> pending = <String, AsyncMemoizer<bool>>{};
final Environment environment; final Environment environment;
final FileHashStore fileCache; final FileHashStore fileCache;
final Map<String, File> inputFiles = <String, File>{}; final Map<String, File> inputFiles = <String, File>{};
@ -671,7 +672,7 @@ class Node {
} }
Map<String, Object> values; Map<String, Object> values;
try { try {
values = json.decode(content); values = castStringKeyedMap(json.decode(content));
} on FormatException { } on FormatException {
// The json is malformed in some way. // The json is malformed in some way.
_dirty = true; _dirty = true;

View File

@ -10,6 +10,7 @@ import 'package:crypto/crypto.dart';
import 'package:pool/pool.dart'; import 'package:pool/pool.dart';
import '../base/file_system.dart'; import '../base/file_system.dart';
import '../base/utils.dart';
import '../convert.dart'; import '../convert.dart';
import '../globals.dart'; import '../globals.dart';
import 'build_system.dart'; import 'build_system.dart';
@ -19,9 +20,9 @@ class FileStorage {
FileStorage(this.version, this.files); FileStorage(this.version, this.files);
factory FileStorage.fromBuffer(Uint8List buffer) { factory FileStorage.fromBuffer(Uint8List buffer) {
final Map<String, Object> json = jsonDecode(utf8.decode(buffer)); final Map<String, dynamic> json = castStringKeyedMap(jsonDecode(utf8.decode(buffer)));
final int version = json['version']; final int version = json['version'] as int;
final List<Object> rawCachedFiles = json['files']; final List<Map<String, Object>> rawCachedFiles = (json['files'] as List<dynamic>).cast<Map<String, Object>>();
final List<FileHash> cachedFiles = <FileHash>[ final List<FileHash> cachedFiles = <FileHash>[
for (Map<String, Object> rawFile in rawCachedFiles) FileHash.fromJson(rawFile), for (Map<String, Object> rawFile in rawCachedFiles) FileHash.fromJson(rawFile),
]; ];
@ -47,7 +48,7 @@ class FileHash {
FileHash(this.path, this.hash); FileHash(this.path, this.hash);
factory FileHash.fromJson(Map<String, Object> json) { factory FileHash.fromJson(Map<String, Object> json) {
return FileHash(json['path'], json['hash']); return FileHash(json['path'] as String, json['hash'] as String);
} }
final String path; final String path;
@ -92,7 +93,7 @@ class FileHashStore {
if (!cacheFile.existsSync()) { if (!cacheFile.existsSync()) {
return; return;
} }
List<int> data; Uint8List data;
try { try {
data = cacheFile.readAsBytesSync(); data = cacheFile.readAsBytesSync();
} on FileSystemException catch (err) { } on FileSystemException catch (err) {
@ -138,7 +139,7 @@ class FileHashStore {
_kVersion, _kVersion,
fileHashes, fileHashes,
); );
final Uint8List buffer = fileStorage.toBuffer(); final List<int> buffer = fileStorage.toBuffer();
try { try {
cacheFile.writeAsBytesSync(buffer); cacheFile.writeAsBytesSync(buffer);
} on FileSystemException catch (err) { } on FileSystemException catch (err) {

View File

@ -153,11 +153,11 @@ class SourceVisitor implements ResolvedFiles {
} else if (wildcardSegments.length == 1) { } else if (wildcardSegments.length == 1) {
if (filename.startsWith(wildcardSegments[0]) || if (filename.startsWith(wildcardSegments[0]) ||
filename.endsWith(wildcardSegments[0])) { filename.endsWith(wildcardSegments[0])) {
sources.add(entity.absolute); sources.add(fs.file(entity.absolute));
} }
} else if (filename.startsWith(wildcardSegments[0])) { } else if (filename.startsWith(wildcardSegments[0])) {
if (filename.substring(wildcardSegments[0].length).endsWith(wildcardSegments[1])) { if (filename.substring(wildcardSegments[0].length).endsWith(wildcardSegments[1])) {
sources.add(entity.absolute); sources.add(fs.file(entity.absolute));
} }
} }
} }

View File

@ -390,7 +390,7 @@ List<String> parseDartDefines(Environment environment) {
final String dartDefinesJson = environment.defines[kDartDefines]; final String dartDefinesJson = environment.defines[kDartDefines];
try { try {
final List<Object> parsedDefines = jsonDecode(dartDefinesJson); final List<Object> parsedDefines = jsonDecode(dartDefinesJson) as List<Object>;
return parsedDefines.cast<String>(); return parsedDefines.cast<String>();
} on FormatException catch (_) { } on FormatException catch (_) {
throw Exception( throw Exception(

View File

@ -379,7 +379,7 @@ class Cache {
final bool includeAllPlatformsState = cache.includeAllPlatforms; final bool includeAllPlatformsState = cache.includeAllPlatforms;
bool allAvailible = true; bool allAvailible = true;
cache.includeAllPlatforms = includeAllPlatforms; cache.includeAllPlatforms = includeAllPlatforms;
for (CachedArtifact cachedArtifact in _artifacts) { for (ArtifactSet cachedArtifact in _artifacts) {
if (cachedArtifact is EngineCachedArtifact) { if (cachedArtifact is EngineCachedArtifact) {
allAvailible &= await cachedArtifact.checkForArtifacts(engineVersion); allAvailible &= await cachedArtifact.checkForArtifacts(engineVersion);
} }

View File

@ -72,7 +72,7 @@ class AnalyzeCommand extends FlutterCommand {
@override @override
bool get shouldRunPub { bool get shouldRunPub {
// If they're not analyzing the current project. // If they're not analyzing the current project.
if (!argResults['current-package']) { if (!boolArg('current-package')) {
return false; return false;
} }
@ -86,7 +86,7 @@ class AnalyzeCommand extends FlutterCommand {
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
if (argResults['watch']) { if (boolArg('watch')) {
await AnalyzeContinuously( await AnalyzeContinuously(
argResults, argResults,
runner.getRepoRoots(), runner.getRepoRoots(),

View File

@ -50,7 +50,7 @@ abstract class AnalyzeBase {
printStatus('Analysis benchmark written to $benchmarkOut ($data).'); printStatus('Analysis benchmark written to $benchmarkOut ($data).');
} }
bool get isBenchmarking => argResults['benchmark']; bool get isBenchmarking => argResults['benchmark'] as bool;
} }
/// Return true if [fileList] contains a path that resides inside the Flutter repository. /// Return true if [fileList] contains a path that resides inside the Flutter repository.
@ -172,10 +172,18 @@ class PackageDependencyTracker {
// we are analyzing the actual canonical source for this package; // we are analyzing the actual canonical source for this package;
// make sure we remember that, in case all the packages are actually // make sure we remember that, in case all the packages are actually
// pointing elsewhere somehow. // pointing elsewhere somehow.
final yaml.YamlMap pubSpecYaml = yaml.loadYaml(fs.file(pubSpecYamlPath).readAsStringSync()); final dynamic pubSpecYaml = yaml.loadYaml(fs.file(pubSpecYamlPath).readAsStringSync());
final String packageName = pubSpecYaml['name']; if (pubSpecYaml is yaml.YamlMap) {
final dynamic packageName = pubSpecYaml['name'];
if (packageName is String) {
final String packagePath = fs.path.normalize(fs.path.absolute(fs.path.join(directory.path, 'lib'))); final String packagePath = fs.path.normalize(fs.path.absolute(fs.path.join(directory.path, 'lib')));
dependencies.addCanonicalCase(packageName, packagePath, pubSpecYamlPath); dependencies.addCanonicalCase(packageName, packagePath, pubSpecYamlPath);
} else {
throwToolExit('pubspec.yaml is malformed. The name should be a String.');
}
} else {
throwToolExit('pubspec.yaml is malformed.');
}
} }
dependencies.addDependenciesFromPackagesFileIn(directory); dependencies.addDependenciesFromPackagesFileIn(directory);
} }

View File

@ -36,7 +36,7 @@ class AnalyzeContinuously extends AnalyzeBase {
Future<void> analyze() async { Future<void> analyze() async {
List<String> directories; List<String> directories;
if (argResults['flutter-repo']) { if (argResults['flutter-repo'] as bool) {
final PackageDependencyTracker dependencies = PackageDependencyTracker(); final PackageDependencyTracker dependencies = PackageDependencyTracker();
dependencies.checkForConflictingDependencies(repoPackages, dependencies); dependencies.checkForConflictingDependencies(repoPackages, dependencies);
@ -52,7 +52,7 @@ class AnalyzeContinuously extends AnalyzeBase {
analysisTarget = fs.currentDirectory.path; analysisTarget = fs.currentDirectory.path;
} }
final String sdkPath = argResults['dart-sdk'] ?? sdk.dartSdkPath; final String sdkPath = argResults['dart-sdk'] as String ?? sdk.dartSdkPath;
final AnalysisServer server = AnalysisServer(sdkPath, directories); final AnalysisServer server = AnalysisServer(sdkPath, directories);
server.onAnalyzing.listen((bool isAnalyzing) => _handleAnalysisStatus(server, isAnalyzing)); server.onAnalyzing.listen((bool isAnalyzing) => _handleAnalysisStatus(server, isAnalyzing));
@ -106,7 +106,7 @@ class AnalyzeContinuously extends AnalyzeBase {
final int undocumentedMembers = errors.where((AnalysisError error) { final int undocumentedMembers = errors.where((AnalysisError error) {
return error.code == 'public_member_api_docs'; return error.code == 'public_member_api_docs';
}).length; }).length;
if (!argResults['dartdocs']) { if (!(argResults['dartdocs'] as bool)) {
errors.removeWhere((AnalysisError error) => error.code == 'public_member_api_docs'); errors.removeWhere((AnalysisError error) => error.code == 'public_member_api_docs');
issueCount -= undocumentedMembers; issueCount -= undocumentedMembers;
} }

View File

@ -52,16 +52,16 @@ class AnalyzeOnce extends AnalyzeBase {
} }
} }
if (argResults['flutter-repo']) { if (argResults['flutter-repo'] as bool) {
// check for conflicting dependencies // check for conflicting dependencies
final PackageDependencyTracker dependencies = PackageDependencyTracker(); final PackageDependencyTracker dependencies = PackageDependencyTracker();
dependencies.checkForConflictingDependencies(repoPackages, dependencies); dependencies.checkForConflictingDependencies(repoPackages, dependencies);
directories.addAll(repoRoots); directories.addAll(repoRoots);
if (argResults.wasParsed('current-package') && argResults['current-package']) { if (argResults.wasParsed('current-package') && (argResults['current-package'] as bool)) {
directories.add(currentDirectory); directories.add(currentDirectory);
} }
} else { } else {
if (argResults['current-package']) { if (argResults['current-package'] as bool) {
directories.add(currentDirectory); directories.add(currentDirectory);
} }
} }
@ -74,7 +74,7 @@ class AnalyzeOnce extends AnalyzeBase {
final Completer<void> analysisCompleter = Completer<void>(); final Completer<void> analysisCompleter = Completer<void>();
final List<AnalysisError> errors = <AnalysisError>[]; final List<AnalysisError> errors = <AnalysisError>[];
final String sdkPath = argResults['dart-sdk'] ?? sdk.dartSdkPath; final String sdkPath = argResults['dart-sdk'] as String ?? sdk.dartSdkPath;
final AnalysisServer server = AnalysisServer( final AnalysisServer server = AnalysisServer(
sdkPath, sdkPath,
@ -109,7 +109,7 @@ class AnalyzeOnce extends AnalyzeBase {
final String message = directories.length > 1 final String message = directories.length > 1
? '${directories.length} ${directories.length == 1 ? 'directory' : 'directories'}' ? '${directories.length} ${directories.length == 1 ? 'directory' : 'directories'}'
: fs.path.basename(directories.first); : fs.path.basename(directories.first);
final Status progress = argResults['preamble'] final Status progress = argResults['preamble'] as bool
? logger.startProgress('Analyzing $message...', timeout: timeoutConfiguration.slowOperation) ? logger.startProgress('Analyzing $message...', timeout: timeoutConfiguration.slowOperation)
: null; : null;
@ -121,7 +121,7 @@ class AnalyzeOnce extends AnalyzeBase {
final int undocumentedMembers = errors.where((AnalysisError error) { final int undocumentedMembers = errors.where((AnalysisError error) {
return error.code == 'public_member_api_docs'; return error.code == 'public_member_api_docs';
}).length; }).length;
if (!argResults['dartdocs']) { if (!(argResults['dartdocs'] as bool)) {
errors.removeWhere((AnalysisError error) => error.code == 'public_member_api_docs'); errors.removeWhere((AnalysisError error) => error.code == 'public_member_api_docs');
} }
@ -134,7 +134,7 @@ class AnalyzeOnce extends AnalyzeBase {
dumpErrors(errors.map<String>((AnalysisError error) => error.toLegacyString())); dumpErrors(errors.map<String>((AnalysisError error) => error.toLegacyString()));
// report errors // report errors
if (errors.isNotEmpty && argResults['preamble']) { if (errors.isNotEmpty && (argResults['preamble'] as bool)) {
printStatus(''); printStatus('');
} }
errors.sort(); errors.sort();
@ -166,7 +166,7 @@ class AnalyzeOnce extends AnalyzeBase {
throwToolExit('Server error(s) occurred. (ran in ${seconds}s)'); throwToolExit('Server error(s) occurred. (ran in ${seconds}s)');
} }
if (argResults['congratulate']) { if (argResults['congratulate'] as bool) {
if (undocumentedMembers > 0) { if (undocumentedMembers > 0) {
printStatus('No issues found! (ran in ${seconds}s; $dartdocMessage)'); printStatus('No issues found! (ran in ${seconds}s; $dartdocMessage)');
} else { } else {

View File

@ -116,7 +116,7 @@ class AssembleCommand extends FlutterCommand {
/// The environmental configuration for a build invocation. /// The environmental configuration for a build invocation.
Environment get environment { Environment get environment {
final FlutterProject flutterProject = FlutterProject.current(); final FlutterProject flutterProject = FlutterProject.current();
String output = argResults['output']; String output = stringArg('output');
if (output == null) { if (output == null) {
throwToolExit('--output directory is required for assemble.'); throwToolExit('--output directory is required for assemble.');
} }
@ -130,7 +130,7 @@ class AssembleCommand extends FlutterCommand {
.childDirectory('.dart_tool') .childDirectory('.dart_tool')
.childDirectory('flutter_build'), .childDirectory('flutter_build'),
projectDir: flutterProject.directory, projectDir: flutterProject.directory,
defines: _parseDefines(argResults['define']), defines: _parseDefines(stringsArg('define')),
); );
return result; return result;
} }
@ -152,7 +152,7 @@ class AssembleCommand extends FlutterCommand {
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
final BuildResult result = await buildSystem.build(target, environment, buildSystemConfig: BuildSystemConfig( final BuildResult result = await buildSystem.build(target, environment, buildSystemConfig: BuildSystemConfig(
resourcePoolSize: argResults['resource-pool-size'], resourcePoolSize: argResults.wasParsed('resource-pool-size') ? int.parse(stringArg('resource-pool-size')) : null,
)); ));
if (!result.success) { if (!result.success) {
for (ExceptionMeasurement measurement in result.exceptions.values) { for (ExceptionMeasurement measurement in result.exceptions.values) {
@ -166,13 +166,13 @@ class AssembleCommand extends FlutterCommand {
} }
printTrace('build succeeded.'); printTrace('build succeeded.');
if (argResults.wasParsed('build-inputs')) { if (argResults.wasParsed('build-inputs')) {
writeListIfChanged(result.inputFiles, argResults['build-inputs']); writeListIfChanged(result.inputFiles, stringArg('build-inputs'));
} }
if (argResults.wasParsed('build-outputs')) { if (argResults.wasParsed('build-outputs')) {
writeListIfChanged(result.outputFiles, argResults['build-outputs']); writeListIfChanged(result.outputFiles, stringArg('build-outputs'));
} }
if (argResults.wasParsed('depfile')) { if (argResults.wasParsed('depfile')) {
final File depfileFile = fs.file(argResults['depfile']); final File depfileFile = fs.file(stringArg('depfile'));
final Depfile depfile = Depfile(result.inputFiles, result.outputFiles); final Depfile depfile = Depfile(result.inputFiles, result.outputFiles);
depfile.writeToFile(fs.file(depfileFile)); depfile.writeToFile(fs.file(depfileFile));
} }

View File

@ -113,7 +113,7 @@ class AttachCommand extends FlutterCommand {
return null; return null;
} }
try { try {
return int.parse(argResults['debug-port']); return int.parse(stringArg('debug-port'));
} catch (error) { } catch (error) {
throwToolExit('Invalid port for `--debug-port`: $error'); throwToolExit('Invalid port for `--debug-port`: $error');
} }
@ -124,7 +124,7 @@ class AttachCommand extends FlutterCommand {
if (argResults['debug-uri'] == null) { if (argResults['debug-uri'] == null) {
return null; return null;
} }
final Uri uri = Uri.parse(argResults['debug-uri']); final Uri uri = Uri.parse(stringArg('debug-uri'));
if (!uri.hasPort) { if (!uri.hasPort) {
throwToolExit('Port not specified for `--debug-uri`: $uri'); throwToolExit('Port not specified for `--debug-uri`: $uri');
} }
@ -132,7 +132,7 @@ class AttachCommand extends FlutterCommand {
} }
String get appId { String get appId {
return argResults['app-id']; return stringArg('app-id');
} }
@override @override
@ -166,7 +166,7 @@ class AttachCommand extends FlutterCommand {
await _validateArguments(); await _validateArguments();
writePidFile(argResults['pid-file']); writePidFile(stringArg('pid-file'));
final Device device = await findTargetDevice(); final Device device = await findTargetDevice();
@ -195,7 +195,7 @@ class AttachCommand extends FlutterCommand {
} }
final int devicePort = await getDevicePort(); final int devicePort = await getDevicePort();
final Daemon daemon = argResults['machine'] final Daemon daemon = boolArg('machine')
? Daemon(stdinCommandStream, stdoutCommandResponse, ? Daemon(stdinCommandStream, stdoutCommandResponse,
notifyingLogger: NotifyingLogger(), logToStdout: true) notifyingLogger: NotifyingLogger(), logToStdout: true)
: null; : null;
@ -210,7 +210,7 @@ class AttachCommand extends FlutterCommand {
if (devicePort == null && debugUri == null) { if (devicePort == null && debugUri == null) {
if (device is FuchsiaDevice) { if (device is FuchsiaDevice) {
attachLogger = true; attachLogger = true;
final String module = argResults['module']; final String module = stringArg('module');
if (module == null) { if (module == null) {
throwToolExit('\'--module\' is required for attaching to a Fuchsia device'); throwToolExit('\'--module\' is required for attaching to a Fuchsia device');
} }
@ -272,12 +272,12 @@ class AttachCommand extends FlutterCommand {
final FlutterDevice flutterDevice = await FlutterDevice.create( final FlutterDevice flutterDevice = await FlutterDevice.create(
device, device,
flutterProject: flutterProject, flutterProject: flutterProject,
trackWidgetCreation: argResults['track-widget-creation'], trackWidgetCreation: boolArg('track-widget-creation'),
fileSystemRoots: argResults['filesystem-root'], fileSystemRoots: stringsArg('filesystem-root'),
fileSystemScheme: argResults['filesystem-scheme'], fileSystemScheme: stringArg('filesystem-scheme'),
viewFilter: argResults['isolate-filter'], viewFilter: stringArg('isolate-filter'),
target: argResults['target'], target: stringArg('target'),
targetModel: TargetModel(argResults['target-model']), targetModel: TargetModel(stringArg('target-model')),
buildMode: getBuildMode(), buildMode: getBuildMode(),
dartDefines: dartDefines, dartDefines: dartDefines,
); );
@ -290,9 +290,9 @@ class AttachCommand extends FlutterCommand {
flutterDevices, flutterDevices,
target: targetFile, target: targetFile,
debuggingOptions: debuggingOptions, debuggingOptions: debuggingOptions,
packagesFilePath: globalResults['packages'], packagesFilePath: globalResults['packages'] as String,
projectRootPath: argResults['project-root'], projectRootPath: stringArg('project-root'),
dillOutputPath: argResults['output-dill'], dillOutputPath: stringArg('output-dill'),
ipv6: usesIpv6, ipv6: usesIpv6,
flutterProject: flutterProject, flutterProject: flutterProject,
) )

View File

@ -72,8 +72,7 @@ class BuildAarCommand extends BuildSubCommand {
} else { } else {
usage[CustomDimensions.commandBuildAarProjectType] = 'app'; usage[CustomDimensions.commandBuildAarProjectType] = 'app';
} }
usage[CustomDimensions.commandBuildAarTargetPlatform] = usage[CustomDimensions.commandBuildAarTargetPlatform] = stringsArg('target-platform').join(',');
(argResults['target-platform'] as List<String>).join(',');
return usage; return usage;
} }
@ -87,14 +86,14 @@ class BuildAarCommand extends BuildSubCommand {
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
final Set<AndroidBuildInfo> androidBuildInfo = <AndroidBuildInfo>{}; final Set<AndroidBuildInfo> androidBuildInfo = <AndroidBuildInfo>{};
final Iterable<AndroidArch> targetArchitectures = argResults['target-platform'] final Iterable<AndroidArch> targetArchitectures = stringsArg('target-platform')
.map<AndroidArch>(getAndroidArchForName); .map<AndroidArch>(getAndroidArchForName);
for (String buildMode in const <String>['debug', 'profile', 'release']) { for (String buildMode in const <String>['debug', 'profile', 'release']) {
if (argResults[buildMode]) { if (boolArg(buildMode)) {
androidBuildInfo.add( androidBuildInfo.add(
AndroidBuildInfo( AndroidBuildInfo(
BuildInfo(BuildMode.fromName(buildMode), argResults['flavor']), BuildInfo(BuildMode.fromName(buildMode), stringArg('flavor')),
targetArchs: targetArchitectures, targetArchs: targetArchitectures,
) )
); );
@ -107,7 +106,7 @@ class BuildAarCommand extends BuildSubCommand {
project: _getProject(), project: _getProject(),
target: '', // Not needed because this command only builds Android's code. target: '', // Not needed because this command only builds Android's code.
androidBuildInfo: androidBuildInfo, androidBuildInfo: androidBuildInfo,
outputDirectoryPath: argResults['output-dir'], outputDirectoryPath: stringArg('output-dir'),
); );
return null; return null;
} }

View File

@ -66,9 +66,9 @@ class BuildAotCommand extends BuildSubCommand with TargetPlatformBasedDevelopmen
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
final String targetPlatform = argResults['target-platform']; final String targetPlatform = stringArg('target-platform');
final TargetPlatform platform = getTargetPlatformForName(targetPlatform); final TargetPlatform platform = getTargetPlatformForName(targetPlatform);
final String outputPath = argResults['output-dir'] ?? getAotBuildDirectory(); final String outputPath = stringArg('output-dir') ?? getAotBuildDirectory();
final BuildMode buildMode = getBuildMode(); final BuildMode buildMode = getBuildMode();
if (platform == null) { if (platform == null) {
throwToolExit('Unknown platform: $targetPlatform'); throwToolExit('Unknown platform: $targetPlatform');
@ -81,12 +81,12 @@ class BuildAotCommand extends BuildSubCommand with TargetPlatformBasedDevelopmen
outputPath: outputPath, outputPath: outputPath,
buildMode: buildMode, buildMode: buildMode,
mainDartFile: findMainDartFile(targetFile), mainDartFile: findMainDartFile(targetFile),
bitcode: argResults['bitcode'], bitcode: boolArg('bitcode'),
quiet: argResults['quiet'], quiet: boolArg('quiet'),
reportTimings: argResults['report-timings'], reportTimings: boolArg('report-timings'),
iosBuildArchs: argResults['ios-arch'].map<DarwinArch>(getIOSArchForName), iosBuildArchs: stringsArg('ios-arch').map<DarwinArch>(getIOSArchForName),
extraFrontEndOptions: argResults[FlutterOptions.kExtraFrontEndOptions], extraFrontEndOptions: stringsArg(FlutterOptions.kExtraFrontEndOptions),
extraGenSnapshotOptions: argResults[FlutterOptions.kExtraGenSnapshotOptions], extraGenSnapshotOptions: stringsArg(FlutterOptions.kExtraGenSnapshotOptions),
dartDefines: dartDefines, dartDefines: dartDefines,
); );
return null; return null;

View File

@ -59,15 +59,15 @@ class BuildApkCommand extends BuildSubCommand {
final Map<CustomDimensions, String> usage = <CustomDimensions, String>{}; final Map<CustomDimensions, String> usage = <CustomDimensions, String>{};
usage[CustomDimensions.commandBuildApkTargetPlatform] = usage[CustomDimensions.commandBuildApkTargetPlatform] =
(argResults['target-platform'] as List<String>).join(','); stringsArg('target-platform').join(',');
usage[CustomDimensions.commandBuildApkSplitPerAbi] = usage[CustomDimensions.commandBuildApkSplitPerAbi] =
argResults['split-per-abi'].toString(); boolArg('split-per-abi').toString();
if (argResults['release']) { if (boolArg('release')) {
usage[CustomDimensions.commandBuildApkBuildMode] = 'release'; usage[CustomDimensions.commandBuildApkBuildMode] = 'release';
} else if (argResults['debug']) { } else if (boolArg('debug')) {
usage[CustomDimensions.commandBuildApkBuildMode] = 'debug'; usage[CustomDimensions.commandBuildApkBuildMode] = 'debug';
} else if (argResults['profile']) { } else if (boolArg('profile')) {
usage[CustomDimensions.commandBuildApkBuildMode] = 'profile'; usage[CustomDimensions.commandBuildApkBuildMode] = 'profile';
} else { } else {
// The build defaults to release. // The build defaults to release.
@ -81,13 +81,13 @@ class BuildApkCommand extends BuildSubCommand {
final BuildInfo buildInfo = getBuildInfo(); final BuildInfo buildInfo = getBuildInfo();
final AndroidBuildInfo androidBuildInfo = AndroidBuildInfo( final AndroidBuildInfo androidBuildInfo = AndroidBuildInfo(
buildInfo, buildInfo,
splitPerAbi: argResults['split-per-abi'], splitPerAbi: boolArg('split-per-abi'),
targetArchs: argResults['target-platform'].map<AndroidArch>(getAndroidArchForName), targetArchs: stringsArg('target-platform').map<AndroidArch>(getAndroidArchForName),
shrink: argResults['shrink'], shrink: boolArg('shrink'),
); );
if (buildInfo.isRelease && !androidBuildInfo.splitPerAbi && androidBuildInfo.targetArchs.length > 1) { if (buildInfo.isRelease && !androidBuildInfo.splitPerAbi && androidBuildInfo.targetArchs.length > 1) {
final String targetPlatforms = argResults['target-platform'].join(', '); final String targetPlatforms = stringsArg('target-platform').join(', ');
printStatus('You are building a fat APK that includes binaries for ' printStatus('You are building a fat APK that includes binaries for '
'$targetPlatforms.', emphasis: true, color: TerminalColor.green); '$targetPlatforms.', emphasis: true, color: TerminalColor.green);

View File

@ -53,13 +53,13 @@ class BuildAppBundleCommand extends BuildSubCommand {
final Map<CustomDimensions, String> usage = <CustomDimensions, String>{}; final Map<CustomDimensions, String> usage = <CustomDimensions, String>{};
usage[CustomDimensions.commandBuildAppBundleTargetPlatform] = usage[CustomDimensions.commandBuildAppBundleTargetPlatform] =
(argResults['target-platform'] as List<String>).join(','); stringsArg('target-platform').join(',');
if (argResults['release']) { if (boolArg('release')) {
usage[CustomDimensions.commandBuildAppBundleBuildMode] = 'release'; usage[CustomDimensions.commandBuildAppBundleBuildMode] = 'release';
} else if (argResults['debug']) { } else if (boolArg('debug')) {
usage[CustomDimensions.commandBuildAppBundleBuildMode] = 'debug'; usage[CustomDimensions.commandBuildAppBundleBuildMode] = 'debug';
} else if (argResults['profile']) { } else if (boolArg('profile')) {
usage[CustomDimensions.commandBuildAppBundleBuildMode] = 'profile'; usage[CustomDimensions.commandBuildAppBundleBuildMode] = 'profile';
} else { } else {
// The build defaults to release. // The build defaults to release.
@ -71,8 +71,8 @@ class BuildAppBundleCommand extends BuildSubCommand {
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
final AndroidBuildInfo androidBuildInfo = AndroidBuildInfo(getBuildInfo(), final AndroidBuildInfo androidBuildInfo = AndroidBuildInfo(getBuildInfo(),
targetArchs: argResults['target-platform'].map<AndroidArch>(getAndroidArchForName), targetArchs: stringsArg('target-platform').map<AndroidArch>(getAndroidArchForName),
shrink: argResults['shrink'], shrink: boolArg('shrink'),
); );
await androidBuilder.buildAab( await androidBuilder.buildAab(
project: FlutterProject.current(), project: FlutterProject.current(),

View File

@ -88,14 +88,14 @@ class BuildBundleCommand extends BuildSubCommand {
return const <CustomDimensions, String>{}; return const <CustomDimensions, String>{};
} }
return <CustomDimensions, String>{ return <CustomDimensions, String>{
CustomDimensions.commandBuildBundleTargetPlatform: argResults['target-platform'], CustomDimensions.commandBuildBundleTargetPlatform: stringArg('target-platform'),
CustomDimensions.commandBuildBundleIsModule: '${futterProject.isModule}', CustomDimensions.commandBuildBundleIsModule: '${futterProject.isModule}',
}; };
} }
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
final String targetPlatform = argResults['target-platform']; final String targetPlatform = stringArg('target-platform');
final TargetPlatform platform = getTargetPlatformForName(targetPlatform); final TargetPlatform platform = getTargetPlatformForName(targetPlatform);
if (platform == null) { if (platform == null) {
throwToolExit('Unknown platform: $targetPlatform'); throwToolExit('Unknown platform: $targetPlatform');
@ -127,17 +127,17 @@ class BuildBundleCommand extends BuildSubCommand {
platform: platform, platform: platform,
buildMode: buildMode, buildMode: buildMode,
mainPath: targetFile, mainPath: targetFile,
manifestPath: argResults['manifest'], manifestPath: stringArg('manifest'),
depfilePath: argResults['depfile'], depfilePath: stringArg('depfile'),
privateKeyPath: argResults['private-key'], privateKeyPath: stringArg('private-key'),
assetDirPath: argResults['asset-dir'], assetDirPath: stringArg('asset-dir'),
precompiledSnapshot: argResults['precompiled'], precompiledSnapshot: boolArg('precompiled'),
reportLicensedPackages: argResults['report-licensed-packages'], reportLicensedPackages: boolArg('report-licensed-packages'),
trackWidgetCreation: argResults['track-widget-creation'], trackWidgetCreation: boolArg('track-widget-creation'),
extraFrontEndOptions: argResults[FlutterOptions.kExtraFrontEndOptions], extraFrontEndOptions: stringsArg(FlutterOptions.kExtraFrontEndOptions),
extraGenSnapshotOptions: argResults[FlutterOptions.kExtraGenSnapshotOptions], extraGenSnapshotOptions: stringsArg(FlutterOptions.kExtraGenSnapshotOptions),
fileSystemScheme: argResults['filesystem-scheme'], fileSystemScheme: stringArg('filesystem-scheme'),
fileSystemRoots: argResults['filesystem-root'], fileSystemRoots: stringsArg('filesystem-root'),
); );
return null; return null;
} }

View File

@ -70,7 +70,7 @@ class BuildFuchsiaCommand extends BuildSubCommand {
fuchsiaProject: flutterProject.fuchsia, fuchsiaProject: flutterProject.fuchsia,
target: targetFile, target: targetFile,
buildInfo: buildInfo, buildInfo: buildInfo,
runnerPackageSource: argResults['runner-source'], runnerPackageSource: stringArg('runner-source'),
); );
return null; return null;
} }

View File

@ -60,20 +60,20 @@ class BuildIOSCommand extends BuildSubCommand {
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
final bool forSimulator = argResults['simulator']; final bool forSimulator = boolArg('simulator');
defaultBuildMode = forSimulator ? BuildMode.debug : BuildMode.release; defaultBuildMode = forSimulator ? BuildMode.debug : BuildMode.release;
if (!platform.isMacOS) { if (!platform.isMacOS) {
throwToolExit('Building for iOS is only supported on the Mac.'); throwToolExit('Building for iOS is only supported on the Mac.');
} }
final BuildableIOSApp app = await applicationPackages.getPackageForPlatform(TargetPlatform.ios); final BuildableIOSApp app = await applicationPackages.getPackageForPlatform(TargetPlatform.ios) as BuildableIOSApp;
if (app == null) { if (app == null) {
throwToolExit('Application not configured for iOS'); throwToolExit('Application not configured for iOS');
} }
final bool shouldCodesign = argResults['codesign']; final bool shouldCodesign = boolArg('codesign');
if (!forSimulator && !shouldCodesign) { if (!forSimulator && !shouldCodesign) {
printStatus('Warning: Building for device with codesigning disabled. You will ' printStatus('Warning: Building for device with codesigning disabled. You will '

View File

@ -94,13 +94,13 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
List<BuildMode> get buildModes { List<BuildMode> get buildModes {
final List<BuildMode> buildModes = <BuildMode>[]; final List<BuildMode> buildModes = <BuildMode>[];
if (argResults['debug']) { if (boolArg('debug')) {
buildModes.add(BuildMode.debug); buildModes.add(BuildMode.debug);
} }
if (argResults['profile']) { if (boolArg('profile')) {
buildModes.add(BuildMode.profile); buildModes.add(BuildMode.profile);
} }
if (argResults['release']) { if (boolArg('release')) {
buildModes.add(BuildMode.release); buildModes.add(BuildMode.release);
} }
@ -119,10 +119,10 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
throwToolExit('Building frameworks for iOS is only supported on the Mac.'); throwToolExit('Building frameworks for iOS is only supported on the Mac.');
} }
if (!argResults['universal'] && !argResults['xcframework']) { if (!boolArg('universal') && !boolArg('xcframework')) {
throwToolExit('--universal or --xcframework is required.'); throwToolExit('--universal or --xcframework is required.');
} }
if (argResults['xcframework'] && xcode.majorVersion < 11) { if (boolArg('xcframework') && xcode.majorVersion < 11) {
throwToolExit('--xcframework requires Xcode 11.'); throwToolExit('--xcframework requires Xcode 11.');
} }
if (buildModes.isEmpty) { if (buildModes.isEmpty) {
@ -134,14 +134,14 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
Cache.releaseLockEarly(); Cache.releaseLockEarly();
final String outputArgument = argResults['output'] final String outputArgument = stringArg('output')
?? fs.path.join(fs.currentDirectory.path, 'build', 'ios', 'framework'); ?? fs.path.join(fs.currentDirectory.path, 'build', 'ios', 'framework');
if (outputArgument.isEmpty) { if (outputArgument.isEmpty) {
throwToolExit('--output is required.'); throwToolExit('--output is required.');
} }
final BuildableIOSApp iosProject = await applicationPackages.getPackageForPlatform(TargetPlatform.ios); final BuildableIOSApp iosProject = await applicationPackages.getPackageForPlatform(TargetPlatform.ios) as BuildableIOSApp;
if (iosProject == null) { if (iosProject == null) {
throwToolExit("Module's iOS folder missing"); throwToolExit("Module's iOS folder missing");
@ -201,7 +201,7 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
final Directory fatFlutterFrameworkCopy = modeDirectory.childDirectory(flutterFrameworkFileName); final Directory fatFlutterFrameworkCopy = modeDirectory.childDirectory(flutterFrameworkFileName);
copyDirectorySync(fs.directory(engineCacheFlutterFrameworkDirectory), fatFlutterFrameworkCopy); copyDirectorySync(fs.directory(engineCacheFlutterFrameworkDirectory), fatFlutterFrameworkCopy);
if (argResults['xcframework']) { if (boolArg('xcframework')) {
// Copy universal framework to variant directory. // Copy universal framework to variant directory.
final Directory armFlutterFrameworkDirectory = iPhoneBuildOutput.childDirectory(flutterFrameworkFileName); final Directory armFlutterFrameworkDirectory = iPhoneBuildOutput.childDirectory(flutterFrameworkFileName);
final File armFlutterFrameworkBinary = armFlutterFrameworkDirectory.childFile('Flutter'); final File armFlutterFrameworkBinary = armFlutterFrameworkDirectory.childFile('Flutter');
@ -249,7 +249,7 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
); );
} }
if (!argResults['universal']) { if (!boolArg('universal')) {
fatFlutterFrameworkCopy.deleteSync(recursive: true); fatFlutterFrameworkCopy.deleteSync(recursive: true);
} }
status.stop(); status.stop();
@ -359,8 +359,8 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
final String podFrameworkName = podProduct.basename; final String podFrameworkName = podProduct.basename;
if (fs.path.extension(podFrameworkName) == '.framework') { if (fs.path.extension(podFrameworkName) == '.framework') {
final String binaryName = fs.path.basenameWithoutExtension(podFrameworkName); final String binaryName = fs.path.basenameWithoutExtension(podFrameworkName);
if (argResults['universal']) { if (boolArg('universal')) {
copyDirectorySync(podProduct, modeDirectory.childDirectory(podFrameworkName)); copyDirectorySync(podProduct as Directory, modeDirectory.childDirectory(podFrameworkName));
final List<String> lipoCommand = <String>[ final List<String> lipoCommand = <String>[
'xcrun', 'xcrun',
'lipo', 'lipo',
@ -378,7 +378,7 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
); );
} }
if (argResults['xcframework']) { if (boolArg('xcframework')) {
final List<String> xcframeworkCommand = <String>[ final List<String> xcframeworkCommand = <String>[
'xcrun', 'xcrun',
'xcodebuild', 'xcodebuild',

View File

@ -49,7 +49,7 @@ class BuildWebCommand extends BuildSubCommand {
throwToolExit('"build web" is not currently supported.'); throwToolExit('"build web" is not currently supported.');
} }
final FlutterProject flutterProject = FlutterProject.current(); final FlutterProject flutterProject = FlutterProject.current();
final String target = argResults['target']; final String target = stringArg('target');
final BuildInfo buildInfo = getBuildInfo(); final BuildInfo buildInfo = getBuildInfo();
if (buildInfo.isDebug) { if (buildInfo.isDebug) {
throwToolExit('debug builds cannot be built directly for the web. Try using "flutter run"'); throwToolExit('debug builds cannot be built directly for the web. Try using "flutter run"');
@ -58,7 +58,7 @@ class BuildWebCommand extends BuildSubCommand {
flutterProject, flutterProject,
target, target,
buildInfo, buildInfo,
argResults['web-initialize-platform'], boolArg('web-initialize-platform'),
dartDefines, dartDefines,
); );
return null; return null;

View File

@ -39,8 +39,8 @@ class ChannelCommand extends FlutterCommand {
switch (argResults.rest.length) { switch (argResults.rest.length) {
case 0: case 0:
await _listChannels( await _listChannels(
showAll: argResults['all'], showAll: boolArg('all'),
verbose: globalResults['verbose'], verbose: globalResults['verbose'] as bool,
); );
return null; return null;
case 1: case 1:

View File

@ -100,12 +100,12 @@ class ConfigCommand extends FlutterCommand {
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
if (argResults['machine']) { if (boolArg('machine')) {
await handleMachine(); await handleMachine();
return null; return null;
} }
if (argResults['clear-features']) { if (boolArg('clear-features')) {
for (Feature feature in allFeatures) { for (Feature feature in allFeatures) {
if (feature.configSetting != null) { if (feature.configSetting != null) {
config.removeValue(feature.configSetting); config.removeValue(feature.configSetting);
@ -115,18 +115,18 @@ class ConfigCommand extends FlutterCommand {
} }
if (argResults.wasParsed('analytics')) { if (argResults.wasParsed('analytics')) {
final bool value = argResults['analytics']; final bool value = boolArg('analytics');
flutterUsage.enabled = value; flutterUsage.enabled = value;
AnalyticsConfigEvent(enabled: value).send(); AnalyticsConfigEvent(enabled: value).send();
printStatus('Analytics reporting ${value ? 'enabled' : 'disabled'}.'); printStatus('Analytics reporting ${value ? 'enabled' : 'disabled'}.');
} }
if (argResults.wasParsed('android-sdk')) { if (argResults.wasParsed('android-sdk')) {
_updateConfig('android-sdk', argResults['android-sdk']); _updateConfig('android-sdk', stringArg('android-sdk'));
} }
if (argResults.wasParsed('android-studio-dir')) { if (argResults.wasParsed('android-studio-dir')) {
_updateConfig('android-studio-dir', argResults['android-studio-dir']); _updateConfig('android-studio-dir', stringArg('android-studio-dir'));
} }
if (argResults.wasParsed('clear-ios-signing-cert')) { if (argResults.wasParsed('clear-ios-signing-cert')) {
@ -134,7 +134,7 @@ class ConfigCommand extends FlutterCommand {
} }
if (argResults.wasParsed('build-dir')) { if (argResults.wasParsed('build-dir')) {
final String buildDir = argResults['build-dir']; final String buildDir = stringArg('build-dir');
if (fs.path.isAbsolute(buildDir)) { if (fs.path.isAbsolute(buildDir)) {
throwToolExit('build-dir should be a relative path'); throwToolExit('build-dir should be a relative path');
} }
@ -146,7 +146,7 @@ class ConfigCommand extends FlutterCommand {
continue; continue;
} }
if (argResults.wasParsed(feature.configSetting)) { if (argResults.wasParsed(feature.configSetting)) {
final bool keyValue = argResults[feature.configSetting]; final bool keyValue = boolArg(feature.configSetting);
config.setValue(feature.configSetting, keyValue); config.setValue(feature.configSetting, keyValue);
printStatus('Setting "${feature.configSetting}" value to "$keyValue".'); printStatus('Setting "${feature.configSetting}" value to "$keyValue".');
} }

View File

@ -177,9 +177,9 @@ class CreateCommand extends FlutterCommand {
@override @override
Future<Map<CustomDimensions, String>> get usageValues async { Future<Map<CustomDimensions, String>> get usageValues async {
return <CustomDimensions, String>{ return <CustomDimensions, String>{
CustomDimensions.commandCreateProjectType: argResults['template'], CustomDimensions.commandCreateProjectType: stringArg('template'),
CustomDimensions.commandCreateAndroidLanguage: argResults['android-language'], CustomDimensions.commandCreateAndroidLanguage: stringArg('android-language'),
CustomDimensions.commandCreateIosLanguage: argResults['ios-language'], CustomDimensions.commandCreateIosLanguage: stringArg('ios-language'),
}; };
} }
@ -197,7 +197,13 @@ class CreateCommand extends FlutterCommand {
if (!metadataFile.existsSync()) { if (!metadataFile.existsSync()) {
return null; return null;
} }
return yaml.loadYaml(metadataFile.readAsStringSync()); final dynamic metadataYaml = yaml.loadYaml(metadataFile.readAsStringSync());
if (metadataYaml is yaml.YamlMap) {
return metadataYaml;
} else {
throwToolExit('pubspec.yaml is malformed.');
return null;
}
} }
bool exists(List<String> path) { bool exists(List<String> path) {
@ -207,7 +213,13 @@ class CreateCommand extends FlutterCommand {
// If it exists, the project type in the metadata is definitive. // If it exists, the project type in the metadata is definitive.
final yaml.YamlMap metadata = loadMetadata(projectDir); final yaml.YamlMap metadata = loadMetadata(projectDir);
if (metadata != null && metadata['project_type'] != null) { if (metadata != null && metadata['project_type'] != null) {
return _stringToProjectType(metadata['project_type']); final dynamic projectType = metadata['project_type'];
if (projectType is String) {
return _stringToProjectType(projectType);
} else {
throwToolExit('.metadata is malformed.');
return null;
}
} }
// There either wasn't any metadata, or it didn't contain the project type, // There either wasn't any metadata, or it didn't contain the project type,
@ -270,7 +282,7 @@ class CreateCommand extends FlutterCommand {
_ProjectType detectedProjectType; _ProjectType detectedProjectType;
final bool metadataExists = projectDir.absolute.childFile('.metadata').existsSync(); final bool metadataExists = projectDir.absolute.childFile('.metadata').existsSync();
if (argResults['template'] != null) { if (argResults['template'] != null) {
template = _stringToProjectType(argResults['template']); template = _stringToProjectType(stringArg('template'));
} else { } else {
// If the project directory exists and isn't empty, then try to determine the template // If the project directory exists and isn't empty, then try to determine the template
// type from the project directory. // type from the project directory.
@ -301,7 +313,7 @@ class CreateCommand extends FlutterCommand {
// _writeSamplesJson can potentially be long-lived. // _writeSamplesJson can potentially be long-lived.
Cache.releaseLockEarly(); Cache.releaseLockEarly();
await _writeSamplesJson(argResults['list-samples']); await _writeSamplesJson(stringArg('list-samples'));
return null; return null;
} }
@ -346,12 +358,12 @@ class CreateCommand extends FlutterCommand {
String sampleCode; String sampleCode;
if (argResults['sample'] != null) { if (argResults['sample'] != null) {
if (argResults['template'] != null && if (argResults['template'] != null &&
_stringToProjectType(argResults['template'] ?? 'app') != _ProjectType.app) { _stringToProjectType(stringArg('template') ?? 'app') != _ProjectType.app) {
throwToolExit('Cannot specify --sample with a project type other than ' throwToolExit('Cannot specify --sample with a project type other than '
'"${getEnumName(_ProjectType.app)}"'); '"${getEnumName(_ProjectType.app)}"');
} }
// Fetch the sample from the server. // Fetch the sample from the server.
sampleCode = await _fetchSampleFromServer(argResults['sample']); sampleCode = await _fetchSampleFromServer(stringArg('sample'));
} }
final _ProjectType template = _getProjectType(projectDir); final _ProjectType template = _getProjectType(projectDir);
@ -359,7 +371,7 @@ class CreateCommand extends FlutterCommand {
final bool generatePlugin = template == _ProjectType.plugin; final bool generatePlugin = template == _ProjectType.plugin;
final bool generatePackage = template == _ProjectType.package; final bool generatePackage = template == _ProjectType.package;
String organization = argResults['org']; String organization = stringArg('org');
if (!argResults.wasParsed('org')) { if (!argResults.wasParsed('org')) {
final FlutterProject project = FlutterProject.fromDirectory(projectDir); final FlutterProject project = FlutterProject.fromDirectory(projectDir);
final Set<String> existingOrganizations = await project.organizationNames; final Set<String> existingOrganizations = await project.organizationNames;
@ -373,12 +385,13 @@ class CreateCommand extends FlutterCommand {
} }
} }
String error = _validateProjectDir(projectDirPath, flutterRoot: flutterRoot, overwrite: argResults['overwrite']); final bool overwrite = boolArg('overwrite');
String error = _validateProjectDir(projectDirPath, flutterRoot: flutterRoot, overwrite: overwrite);
if (error != null) { if (error != null) {
throwToolExit(error); throwToolExit(error);
} }
final String projectName = argResults['project-name'] ?? fs.path.basename(projectDirPath); final String projectName = stringArg('project-name') ?? fs.path.basename(projectDirPath);
error = _validateProjectName(projectName); error = _validateProjectName(projectName);
if (error != null) { if (error != null) {
throwToolExit(error); throwToolExit(error);
@ -387,22 +400,22 @@ class CreateCommand extends FlutterCommand {
final Map<String, dynamic> templateContext = _templateContext( final Map<String, dynamic> templateContext = _templateContext(
organization: organization, organization: organization,
projectName: projectName, projectName: projectName,
projectDescription: argResults['description'], projectDescription: stringArg('description'),
flutterRoot: flutterRoot, flutterRoot: flutterRoot,
renderDriverTest: argResults['with-driver-test'], renderDriverTest: boolArg('with-driver-test'),
withPluginHook: generatePlugin, withPluginHook: generatePlugin,
androidX: argResults['androidx'], androidX: boolArg('androidx'),
androidLanguage: argResults['android-language'], androidLanguage: stringArg('android-language'),
iosLanguage: argResults['ios-language'], iosLanguage: stringArg('ios-language'),
web: featureFlags.isWebEnabled, web: featureFlags.isWebEnabled,
macos: argResults['macos'], macos: boolArg('macos'),
); );
final String relativeDirPath = fs.path.relative(projectDirPath); final String relativeDirPath = fs.path.relative(projectDirPath);
if (!projectDir.existsSync() || projectDir.listSync().isEmpty) { if (!projectDir.existsSync() || projectDir.listSync().isEmpty) {
printStatus('Creating project $relativeDirPath... androidx: ${argResults['androidx']}'); printStatus('Creating project $relativeDirPath... androidx: ${boolArg('androidx')}');
} else { } else {
if (sampleCode != null && !argResults['overwrite']) { if (sampleCode != null && !overwrite) {
throwToolExit('Will not overwrite existing project in $relativeDirPath: ' throwToolExit('Will not overwrite existing project in $relativeDirPath: '
'must specify --overwrite for samples to overwrite.'); 'must specify --overwrite for samples to overwrite.');
} }
@ -413,16 +426,16 @@ class CreateCommand extends FlutterCommand {
int generatedFileCount = 0; int generatedFileCount = 0;
switch (template) { switch (template) {
case _ProjectType.app: case _ProjectType.app:
generatedFileCount += await _generateApp(relativeDir, templateContext, overwrite: argResults['overwrite']); generatedFileCount += await _generateApp(relativeDir, templateContext, overwrite: overwrite);
break; break;
case _ProjectType.module: case _ProjectType.module:
generatedFileCount += await _generateModule(relativeDir, templateContext, overwrite: argResults['overwrite']); generatedFileCount += await _generateModule(relativeDir, templateContext, overwrite: overwrite);
break; break;
case _ProjectType.package: case _ProjectType.package:
generatedFileCount += await _generatePackage(relativeDir, templateContext, overwrite: argResults['overwrite']); generatedFileCount += await _generatePackage(relativeDir, templateContext, overwrite: overwrite);
break; break;
case _ProjectType.plugin: case _ProjectType.plugin:
generatedFileCount += await _generatePlugin(relativeDir, templateContext, overwrite: argResults['overwrite']); generatedFileCount += await _generatePlugin(relativeDir, templateContext, overwrite: overwrite);
break; break;
} }
if (sampleCode != null) { if (sampleCode != null) {
@ -495,15 +508,15 @@ To edit platform code in an IDE see https://flutter.dev/developing-packages/#edi
Future<int> _generateModule(Directory directory, Map<String, dynamic> templateContext, { bool overwrite = false }) async { Future<int> _generateModule(Directory directory, Map<String, dynamic> templateContext, { bool overwrite = false }) async {
int generatedCount = 0; int generatedCount = 0;
final String description = argResults.wasParsed('description') final String description = argResults.wasParsed('description')
? argResults['description'] ? stringArg('description')
: 'A new flutter module project.'; : 'A new flutter module project.';
templateContext['description'] = description; templateContext['description'] = description;
generatedCount += _renderTemplate(fs.path.join('module', 'common'), directory, templateContext, overwrite: overwrite); generatedCount += _renderTemplate(fs.path.join('module', 'common'), directory, templateContext, overwrite: overwrite);
if (argResults['pub']) { if (boolArg('pub')) {
await pub.get( await pub.get(
context: PubContext.create, context: PubContext.create,
directory: directory.path, directory: directory.path,
offline: argResults['offline'], offline: boolArg('offline'),
); );
final FlutterProject project = FlutterProject.fromDirectory(directory); final FlutterProject project = FlutterProject.fromDirectory(directory);
await project.ensureReadyForPlatformSpecificTooling(checkProjects: false); await project.ensureReadyForPlatformSpecificTooling(checkProjects: false);
@ -514,15 +527,15 @@ To edit platform code in an IDE see https://flutter.dev/developing-packages/#edi
Future<int> _generatePackage(Directory directory, Map<String, dynamic> templateContext, { bool overwrite = false }) async { Future<int> _generatePackage(Directory directory, Map<String, dynamic> templateContext, { bool overwrite = false }) async {
int generatedCount = 0; int generatedCount = 0;
final String description = argResults.wasParsed('description') final String description = argResults.wasParsed('description')
? argResults['description'] ? stringArg('description')
: 'A new Flutter package project.'; : 'A new Flutter package project.';
templateContext['description'] = description; templateContext['description'] = description;
generatedCount += _renderTemplate('package', directory, templateContext, overwrite: overwrite); generatedCount += _renderTemplate('package', directory, templateContext, overwrite: overwrite);
if (argResults['pub']) { if (boolArg('pub')) {
await pub.get( await pub.get(
context: PubContext.createPackage, context: PubContext.createPackage,
directory: directory.path, directory: directory.path,
offline: argResults['offline'], offline: boolArg('offline'),
); );
} }
return generatedCount; return generatedCount;
@ -531,23 +544,23 @@ To edit platform code in an IDE see https://flutter.dev/developing-packages/#edi
Future<int> _generatePlugin(Directory directory, Map<String, dynamic> templateContext, { bool overwrite = false }) async { Future<int> _generatePlugin(Directory directory, Map<String, dynamic> templateContext, { bool overwrite = false }) async {
int generatedCount = 0; int generatedCount = 0;
final String description = argResults.wasParsed('description') final String description = argResults.wasParsed('description')
? argResults['description'] ? stringArg('description')
: 'A new flutter plugin project.'; : 'A new flutter plugin project.';
templateContext['description'] = description; templateContext['description'] = description;
generatedCount += _renderTemplate('plugin', directory, templateContext, overwrite: overwrite); generatedCount += _renderTemplate('plugin', directory, templateContext, overwrite: overwrite);
if (argResults['pub']) { if (boolArg('pub')) {
await pub.get( await pub.get(
context: PubContext.createPlugin, context: PubContext.createPlugin,
directory: directory.path, directory: directory.path,
offline: argResults['offline'], offline: boolArg('offline'),
); );
} }
final FlutterProject project = FlutterProject.fromDirectory(directory); final FlutterProject project = FlutterProject.fromDirectory(directory);
gradle.updateLocalProperties(project: project, requireAndroidSdk: false); gradle.updateLocalProperties(project: project, requireAndroidSdk: false);
final String projectName = templateContext['projectName']; final String projectName = templateContext['projectName'] as String;
final String organization = templateContext['organization']; final String organization = templateContext['organization'] as String;
final String androidPluginIdentifier = templateContext['androidIdentifier']; final String androidPluginIdentifier = templateContext['androidIdentifier'] as String;
final String exampleProjectName = projectName + '_example'; final String exampleProjectName = projectName + '_example';
templateContext['projectName'] = exampleProjectName; templateContext['projectName'] = exampleProjectName;
templateContext['androidIdentifier'] = _createAndroidIdentifier(organization, exampleProjectName); templateContext['androidIdentifier'] = _createAndroidIdentifier(organization, exampleProjectName);
@ -566,13 +579,13 @@ To edit platform code in an IDE see https://flutter.dev/developing-packages/#edi
final FlutterProject project = FlutterProject.fromDirectory(directory); final FlutterProject project = FlutterProject.fromDirectory(directory);
generatedCount += _injectGradleWrapper(project); generatedCount += _injectGradleWrapper(project);
if (argResults['with-driver-test']) { if (boolArg('with-driver-test')) {
final Directory testDirectory = directory.childDirectory('test_driver'); final Directory testDirectory = directory.childDirectory('test_driver');
generatedCount += _renderTemplate('driver', testDirectory, templateContext, overwrite: overwrite); generatedCount += _renderTemplate('driver', testDirectory, templateContext, overwrite: overwrite);
} }
if (argResults['pub']) { if (boolArg('pub')) {
await pub.get(context: PubContext.create, directory: directory.path, offline: argResults['offline']); await pub.get(context: PubContext.create, directory: directory.path, offline: boolArg('offline'));
await project.ensureReadyForPlatformSpecificTooling(checkProjects: false); await project.ensureReadyForPlatformSpecificTooling(checkProjects: false);
} }

View File

@ -135,7 +135,7 @@ class Daemon {
} }
try { try {
final String method = request['method']; final String method = request['method'] as String;
if (!method.contains('.')) { if (!method.contains('.')) {
throw 'method not understood: $method'; throw 'method not understood: $method';
} }
@ -146,7 +146,7 @@ class Daemon {
throw 'no domain for method: $method'; throw 'no domain for method: $method';
} }
_domainMap[prefix].handleCommand(name, id, request['params'] ?? const <String, dynamic>{}); _domainMap[prefix].handleCommand(name, id, castStringKeyedMap(request['params']) ?? const <String, dynamic>{});
} catch (error, trace) { } catch (error, trace) {
_send(<String, dynamic>{ _send(<String, dynamic>{
'id': id, 'id': id,
@ -228,7 +228,7 @@ abstract class Domain {
if (val != null && val is! String) { if (val != null && val is! String) {
throw '$name is not a String'; throw '$name is not a String';
} }
return val; return val as String;
} }
bool _getBoolArg(Map<String, dynamic> args, String name, { bool required = false }) { bool _getBoolArg(Map<String, dynamic> args, String name, { bool required = false }) {
@ -239,7 +239,7 @@ abstract class Domain {
if (val != null && val is! bool) { if (val != null && val is! bool) {
throw '$name is not a bool'; throw '$name is not a bool';
} }
return val; return val as bool;
} }
int _getIntArg(Map<String, dynamic> args, String name, { bool required = false }) { int _getIntArg(Map<String, dynamic> args, String name, { bool required = false }) {
@ -250,7 +250,7 @@ abstract class Domain {
if (val != null && val is! int) { if (val != null && val is! int) {
throw '$name is not an int'; throw '$name is not an int';
} }
return val; return val as int;
} }
void dispose() { } void dispose() { }
@ -681,8 +681,8 @@ class DeviceDomain extends Domain {
return; return;
} }
_discoverers.add(discoverer);
if (discoverer is PollingDeviceDiscovery) { if (discoverer is PollingDeviceDiscovery) {
_discoverers.add(discoverer);
discoverer.onAdded.listen(_onDeviceEvent('device.added')); discoverer.onAdded.listen(_onDeviceEvent('device.added'));
discoverer.onRemoved.listen(_onDeviceEvent('device.removed')); discoverer.onRemoved.listen(_onDeviceEvent('device.removed'));
} }
@ -786,7 +786,7 @@ Stream<Map<String, dynamic>> get stdinCommandStream => stdin
.where((String line) => line.startsWith('[{') && line.endsWith('}]')) .where((String line) => line.startsWith('[{') && line.endsWith('}]'))
.map<Map<String, dynamic>>((String line) { .map<Map<String, dynamic>>((String line) {
line = line.substring(1, line.length - 1); line = line.substring(1, line.length - 1);
return json.decode(line); return castStringKeyedMap(json.decode(line));
}); });
void stdoutCommandResponse(Map<String, dynamic> command) { void stdoutCommandResponse(Map<String, dynamic> command) {
@ -924,7 +924,7 @@ class AppInstance {
_logger.close(); _logger.close();
} }
Future<T> _runInZone<T>(AppDomain domain, dynamic method()) { Future<T> _runInZone<T>(AppDomain domain, FutureOr<T> method()) {
_logger ??= _AppRunLogger(domain, this, parent: logToStdout ? logger : null); _logger ??= _AppRunLogger(domain, this, parent: logToStdout ? logger : null);
return context.run<T>( return context.run<T>(

View File

@ -44,7 +44,7 @@ class DoctorCommand extends FlutterCommand {
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
if (argResults.wasParsed('check-for-remote-artifacts')) { if (argResults.wasParsed('check-for-remote-artifacts')) {
final String engineRevision = argResults['check-for-remote-artifacts']; final String engineRevision = stringArg('check-for-remote-artifacts');
if (engineRevision.startsWith(RegExp(r'[a-f0-9]{1,40}'))) { if (engineRevision.startsWith(RegExp(r'[a-f0-9]{1,40}'))) {
final bool success = await doctor.checkRemoteArtifacts(engineRevision); final bool success = await doctor.checkRemoteArtifacts(engineRevision);
if (!success) { if (!success) {
@ -56,7 +56,7 @@ class DoctorCommand extends FlutterCommand {
'git hash.'); 'git hash.');
} }
} }
final bool success = await doctor.diagnose(androidLicenses: argResults['android-licenses'], verbose: verbose); final bool success = await doctor.diagnose(androidLicenses: boolArg('android-licenses'), verbose: verbose);
return FlutterCommandResult(success ? ExitStatus.success : ExitStatus.warning); return FlutterCommandResult(success ? ExitStatus.success : ExitStatus.warning);
} }
} }

View File

@ -83,9 +83,9 @@ class DriveCommand extends RunCommandBase {
Device _device; Device _device;
Device get device => _device; Device get device => _device;
bool get shouldBuild => argResults['build']; bool get shouldBuild => boolArg('build');
bool get verboseSystemLogs => argResults['verbose-system-logs']; bool get verboseSystemLogs => boolArg('verbose-system-logs');
/// Subscription to log messages printed on the device or simulator. /// Subscription to log messages printed on the device or simulator.
// ignore: cancel_subscriptions // ignore: cancel_subscriptions
@ -128,7 +128,7 @@ class DriveCommand extends RunCommandBase {
observatoryUri = result.observatoryUri.toString(); observatoryUri = result.observatoryUri.toString();
} else { } else {
printStatus('Will connect to already running application instance.'); printStatus('Will connect to already running application instance.');
observatoryUri = argResults['use-existing-app']; observatoryUri = stringArg('use-existing-app');
} }
Cache.releaseLockEarly(); Cache.releaseLockEarly();
@ -141,7 +141,7 @@ class DriveCommand extends RunCommandBase {
} }
throwToolExit('CAUGHT EXCEPTION: $error\n$stackTrace'); throwToolExit('CAUGHT EXCEPTION: $error\n$stackTrace');
} finally { } finally {
if (argResults['keep-app-running'] ?? (argResults['use-existing-app'] != null)) { if (boolArg('keep-app-running') ?? (argResults['use-existing-app'] != null)) {
printStatus('Leaving the application running.'); printStatus('Leaving the application running.');
} else { } else {
printStatus('Stopping application instance.'); printStatus('Stopping application instance.');
@ -154,7 +154,7 @@ class DriveCommand extends RunCommandBase {
String _getTestFile() { String _getTestFile() {
if (argResults['driver'] != null) { if (argResults['driver'] != null) {
return argResults['driver']; return stringArg('driver');
} }
// If the --driver argument wasn't provided, then derive the value from // If the --driver argument wasn't provided, then derive the value from

View File

@ -44,9 +44,9 @@ class EmulatorsCommand extends FlutterCommand {
} }
if (argResults.wasParsed('launch')) { if (argResults.wasParsed('launch')) {
await _launchEmulator(argResults['launch']); await _launchEmulator(stringArg('launch'));
} else if (argResults.wasParsed('create')) { } else if (argResults.wasParsed('create')) {
await _createEmulator(name: argResults['name']); await _createEmulator(name: stringArg('name'));
} else { } else {
final String searchText = final String searchText =
argResults.rest != null && argResults.rest.isNotEmpty argResults.rest != null && argResults.rest.isNotEmpty

View File

@ -68,11 +68,11 @@ class FormatCommand extends FlutterCommand {
final String dartfmt = sdkBinaryName('dartfmt'); final String dartfmt = sdkBinaryName('dartfmt');
final List<String> command = <String>[ final List<String> command = <String>[
dartfmt, dartfmt,
if (argResults['dry-run']) '-n', if (boolArg('dry-run')) '-n',
if (argResults['machine']) '-m', if (boolArg('machine')) '-m',
if (argResults['line-length'] != null) '-l ${argResults['line-length']}', if (argResults['line-length'] != null) '-l ${argResults['line-length']}',
if (!argResults['dry-run'] && !argResults['machine']) '-w', if (!boolArg('dry-run') && !boolArg('machine')) '-w',
if (argResults['set-exit-if-changed']) '--set-exit-if-changed', if (boolArg('set-exit-if-changed')) '--set-exit-if-changed',
...argResults.rest, ...argResults.rest,
]; ];

View File

@ -42,8 +42,8 @@ class GenerateCommand extends FlutterCommand {
} }
// Check for errors output in the build_runner cache. // Check for errors output in the build_runner cache.
final Directory buildDirectory = flutterProject.dartTool.childDirectory('build'); final Directory buildDirectory = flutterProject.dartTool.childDirectory('build');
final Directory errorCacheParent = buildDirectory.listSync().firstWhere((FileSystemEntity entity) { final Directory errorCacheParent = buildDirectory.listSync().whereType<Directory>().firstWhere((Directory dir) {
return entity is Directory && entity.childDirectory('error_cache').existsSync(); return dir.childDirectory('error_cache').existsSync();
}, orElse: () => null); }, orElse: () => null);
if (errorCacheParent == null) { if (errorCacheParent == null) {
return null; return null;
@ -51,12 +51,12 @@ class GenerateCommand extends FlutterCommand {
final Directory errorCache = errorCacheParent.childDirectory('error_cache'); final Directory errorCache = errorCacheParent.childDirectory('error_cache');
for (File errorFile in errorCache.listSync(recursive: true).whereType<File>()) { for (File errorFile in errorCache.listSync(recursive: true).whereType<File>()) {
try { try {
final List<Object> errorData = json.decode(errorFile.readAsStringSync()); final List<Object> errorData = json.decode(errorFile.readAsStringSync()) as List<Object>;
final List<Object> stackData = errorData[1]; final List<Object> stackData = errorData[1] as List<Object>;
printError(errorData.first); printError(errorData.first as String);
printError(stackData[0]); printError(stackData[0] as String);
printError(stackData[1]); printError(stackData[1] as String);
printError(StackTrace.fromString(stackData[2]).toString()); printError(StackTrace.fromString(stackData[2] as String).toString());
} catch (err) { } catch (err) {
printError('Error reading error in ${errorFile.path}'); printError('Error reading error in ${errorFile.path}');
} }

View File

@ -125,14 +125,9 @@ class IdeConfigCommand extends FlutterCommand {
} }
final Set<String> manifest = <String>{}; final Set<String> manifest = <String>{};
final List<FileSystemEntity> flutterFiles = _flutterRoot.listSync(recursive: true); final Iterable<File> flutterFiles = _flutterRoot.listSync(recursive: true).whereType<File>();
for (FileSystemEntity entity in flutterFiles) { for (File srcFile in flutterFiles) {
final String relativePath = fs.path.relative(entity.path, from: _flutterRoot.absolute.path); final String relativePath = fs.path.relative(srcFile.path, from: _flutterRoot.absolute.path);
if (entity is! File) {
continue;
}
final File srcFile = entity;
// Skip template files in both the ide_templates and templates // Skip template files in both the ide_templates and templates
// directories to avoid copying onto themselves. // directories to avoid copying onto themselves.
@ -163,7 +158,7 @@ class IdeConfigCommand extends FlutterCommand {
manifest.add('$relativePath${Template.copyTemplateExtension}'); manifest.add('$relativePath${Template.copyTemplateExtension}');
continue; continue;
} }
if (argResults['overwrite']) { if (boolArg('overwrite')) {
finalDestinationFile.deleteSync(); finalDestinationFile.deleteSync();
printStatus(' $relativeDestination (overwritten)'); printStatus(' $relativeDestination (overwritten)');
} else { } else {
@ -184,18 +179,14 @@ class IdeConfigCommand extends FlutterCommand {
} }
// If we're not overwriting, then we're not going to remove missing items either. // If we're not overwriting, then we're not going to remove missing items either.
if (!argResults['overwrite']) { if (!boolArg('overwrite')) {
return; return;
} }
// Look for any files under the template dir that don't exist in the manifest and remove // Look for any files under the template dir that don't exist in the manifest and remove
// them. // them.
final List<FileSystemEntity> templateFiles = _templateDirectory.listSync(recursive: true); final Iterable<File> templateFiles = _templateDirectory.listSync(recursive: true).whereType<File>();
for (FileSystemEntity entity in templateFiles) { for (File templateFile in templateFiles) {
if (entity is! File) {
continue;
}
final File templateFile = entity;
final String relativePath = fs.path.relative( final String relativePath = fs.path.relative(
templateFile.absolute.path, templateFile.absolute.path,
from: _templateDirectory.absolute.path, from: _templateDirectory.absolute.path,
@ -228,7 +219,7 @@ class IdeConfigCommand extends FlutterCommand {
await Cache.instance.updateAll(<DevelopmentArtifact>{ DevelopmentArtifact.universal }); await Cache.instance.updateAll(<DevelopmentArtifact>{ DevelopmentArtifact.universal });
if (argResults['update-templates']) { if (boolArg('update-templates')) {
_handleTemplateUpdate(); _handleTemplateUpdate();
return null; return null;
} }
@ -246,7 +237,7 @@ class IdeConfigCommand extends FlutterCommand {
printStatus('Updating IDE configuration for Flutter tree at $dirPath...'); printStatus('Updating IDE configuration for Flutter tree at $dirPath...');
int generatedCount = 0; int generatedCount = 0;
generatedCount += _renderTemplate(_ideName, dirPath, <String, dynamic>{ generatedCount += _renderTemplate(_ideName, dirPath, <String, dynamic>{
'withRootModule': argResults['with-root-module'], 'withRootModule': boolArg('with-root-module'),
}); });
printStatus('Wrote $generatedCount files.'); printStatus('Wrote $generatedCount files.');
@ -262,7 +253,7 @@ class IdeConfigCommand extends FlutterCommand {
return template.render( return template.render(
fs.directory(dirPath), fs.directory(dirPath),
context, context,
overwriteExisting: argResults['overwrite'], overwriteExisting: boolArg('overwrite'),
); );
} }
} }

View File

@ -42,7 +42,7 @@ class LogsCommand extends FlutterCommand {
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
if (argResults['clear']) { if (boolArg('clear')) {
device.clearLogs(); device.clearLogs();
} }

View File

@ -46,8 +46,8 @@ class MakeHostAppEditableCommand extends FlutterCommand {
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
await _project.ensureReadyForPlatformSpecificTooling(checkProjects: false); await _project.ensureReadyForPlatformSpecificTooling(checkProjects: false);
final bool isAndroidRequested = argResults['android']; final bool isAndroidRequested = boolArg('android');
final bool isIOSRequested = argResults['ios']; final bool isIOSRequested = boolArg('ios');
if (isAndroidRequested == isIOSRequested) { if (isAndroidRequested == isIOSRequested) {
// No flags provided, or both flags provided. Make Android and iOS host // No flags provided, or both flags provided. Make Android and iOS host

View File

@ -98,7 +98,7 @@ class PackagesGetCommand extends FlutterCommand {
await pub.get(context: PubContext.pubGet, await pub.get(context: PubContext.pubGet,
directory: directory, directory: directory,
upgrade: upgrade , upgrade: upgrade ,
offline: argResults['offline'], offline: boolArg('offline'),
checkLastModified: false, checkLastModified: false,
); );
pubGetTimer.stop(); pubGetTimer.stop();
@ -203,8 +203,8 @@ class PackagesPublishCommand extends FlutterCommand {
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
final List<String> args = <String>[ final List<String> args = <String>[
...argResults.rest, ...argResults.rest,
if (argResults['dry-run']) '--dry-run', if (boolArg('dry-run')) '--dry-run',
if (argResults['force']) '--force', if (boolArg('force')) '--force',
]; ];
Cache.releaseLockEarly(); Cache.releaseLockEarly();
await pub.interactively(<String>['publish', ...args]); await pub.interactively(<String>['publish', ...args]);

View File

@ -59,10 +59,10 @@ class PrecacheCommand extends FlutterCommand {
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
if (argResults['all-platforms']) { if (boolArg('all-platforms')) {
cache.includeAllPlatforms = true; cache.includeAllPlatforms = true;
} }
if (argResults['use-unsigned-mac-binaries']) { if (boolArg('use-unsigned-mac-binaries')) {
cache.useUnsignedMacBinaries = true; cache.useUnsignedMacBinaries = true;
} }
final Set<DevelopmentArtifact> requiredArtifacts = <DevelopmentArtifact>{}; final Set<DevelopmentArtifact> requiredArtifacts = <DevelopmentArtifact>{};
@ -74,15 +74,15 @@ class PrecacheCommand extends FlutterCommand {
if (artifact.feature != null && !featureFlags.isEnabled(artifact.feature)) { if (artifact.feature != null && !featureFlags.isEnabled(artifact.feature)) {
continue; continue;
} }
if (argResults[artifact.name]) { if (boolArg(artifact.name)) {
requiredArtifacts.add(artifact); requiredArtifacts.add(artifact);
} }
// The `android` flag expands to android_gen_snapshot, android_maven, android_internal_build. // The `android` flag expands to android_gen_snapshot, android_maven, android_internal_build.
if (artifact.name.startsWith('android_') && argResults['android']) { if (artifact.name.startsWith('android_') && boolArg('android')) {
requiredArtifacts.add(artifact); requiredArtifacts.add(artifact);
} }
} }
final bool forceUpdate = argResults['force']; final bool forceUpdate = boolArg('force');
if (forceUpdate || !cache.isUpToDate()) { if (forceUpdate || !cache.isUpToDate()) {
await cache.updateAll(requiredArtifacts); await cache.updateAll(requiredArtifacts);
} else { } else {

View File

@ -70,11 +70,11 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
usesIsolateFilterOption(hide: !verboseHelp); usesIsolateFilterOption(hide: !verboseHelp);
} }
bool get traceStartup => argResults['trace-startup']; bool get traceStartup => boolArg('trace-startup');
bool get cacheSkSL => argResults['cache-sksl']; bool get cacheSkSL => boolArg('cache-sksl');
bool get dumpSkpOnShaderCompilation => argResults['dump-skp-on-shader-compilation']; bool get dumpSkpOnShaderCompilation => boolArg('dump-skp-on-shader-compilation');
String get route => argResults['route']; String get route => stringArg('route');
} }
class RunCommand extends RunCommandBase { class RunCommand extends RunCommandBase {
@ -266,7 +266,7 @@ class RunCommand extends RunCommandBase {
} }
bool shouldUseHotMode() { bool shouldUseHotMode() {
final bool hotArg = argResults['hot'] ?? false; final bool hotArg = boolArg('hot') ?? false;
final bool shouldUseHotMode = hotArg && !traceStartup; final bool shouldUseHotMode = hotArg && !traceStartup;
return getBuildInfo().isDebug && shouldUseHotMode; return getBuildInfo().isDebug && shouldUseHotMode;
} }
@ -274,8 +274,8 @@ class RunCommand extends RunCommandBase {
bool get runningWithPrebuiltApplication => bool get runningWithPrebuiltApplication =>
argResults['use-application-binary'] != null; argResults['use-application-binary'] != null;
bool get stayResident => argResults['resident']; bool get stayResident => boolArg('resident');
bool get awaitFirstFrameWhenTracing => argResults['await-first-frame-when-tracing']; bool get awaitFirstFrameWhenTracing => boolArg('await-first-frame-when-tracing');
@override @override
Future<void> validateCommand() async { Future<void> validateCommand() async {
@ -298,31 +298,31 @@ class RunCommand extends RunCommandBase {
if (buildInfo.isRelease) { if (buildInfo.isRelease) {
return DebuggingOptions.disabled( return DebuggingOptions.disabled(
buildInfo, buildInfo,
initializePlatform: argResults['web-initialize-platform'], initializePlatform: boolArg('web-initialize-platform'),
hostname: featureFlags.isWebEnabled ? argResults['web-hostname'] : '', hostname: featureFlags.isWebEnabled ? stringArg('web-hostname') : '',
port: featureFlags.isWebEnabled ? argResults['web-port'] : '', port: featureFlags.isWebEnabled ? stringArg('web-port') : '',
); );
} else { } else {
return DebuggingOptions.enabled( return DebuggingOptions.enabled(
buildInfo, buildInfo,
startPaused: argResults['start-paused'], startPaused: boolArg('start-paused'),
disableServiceAuthCodes: argResults['disable-service-auth-codes'], disableServiceAuthCodes: boolArg('disable-service-auth-codes'),
dartFlags: argResults['dart-flags'] ?? '', dartFlags: stringArg('dart-flags') ?? '',
useTestFonts: argResults['use-test-fonts'], useTestFonts: boolArg('use-test-fonts'),
enableSoftwareRendering: argResults['enable-software-rendering'], enableSoftwareRendering: boolArg('enable-software-rendering'),
skiaDeterministicRendering: argResults['skia-deterministic-rendering'], skiaDeterministicRendering: boolArg('skia-deterministic-rendering'),
traceSkia: argResults['trace-skia'], traceSkia: boolArg('trace-skia'),
traceSystrace: argResults['trace-systrace'], traceSystrace: boolArg('trace-systrace'),
dumpSkpOnShaderCompilation: dumpSkpOnShaderCompilation, dumpSkpOnShaderCompilation: dumpSkpOnShaderCompilation,
cacheSkSL: cacheSkSL, cacheSkSL: cacheSkSL,
deviceVmServicePort: deviceVmservicePort, deviceVmServicePort: deviceVmservicePort,
hostVmServicePort: hostVmservicePort, hostVmServicePort: hostVmservicePort,
verboseSystemLogs: argResults['verbose-system-logs'], verboseSystemLogs: boolArg('verbose-system-logs'),
initializePlatform: argResults['web-initialize-platform'], initializePlatform: boolArg('web-initialize-platform'),
hostname: featureFlags.isWebEnabled ? argResults['web-hostname'] : '', hostname: featureFlags.isWebEnabled ? stringArg('web-hostname') : '',
port: featureFlags.isWebEnabled ? argResults['web-port'] : '', port: featureFlags.isWebEnabled ? stringArg('web-port') : '',
browserLaunch: featureFlags.isWebEnabled ? argResults['web-browser-launch'] : null, browserLaunch: featureFlags.isWebEnabled ? boolArg('web-browser-launch') : null,
vmserviceOutFile: argResults['vmservice-out-file'], vmserviceOutFile: stringArg('vmservice-out-file'),
); );
} }
} }
@ -335,9 +335,9 @@ class RunCommand extends RunCommandBase {
// debug mode. // debug mode.
final bool hotMode = shouldUseHotMode(); final bool hotMode = shouldUseHotMode();
writePidFile(argResults['pid-file']); writePidFile(stringArg('pid-file'));
if (argResults['machine']) { if (boolArg('machine')) {
if (devices.length > 1) { if (devices.length > 1) {
throwToolExit('--machine does not support -d all.'); throwToolExit('--machine does not support -d all.');
} }
@ -345,17 +345,17 @@ class RunCommand extends RunCommandBase {
notifyingLogger: NotifyingLogger(), logToStdout: true); notifyingLogger: NotifyingLogger(), logToStdout: true);
AppInstance app; AppInstance app;
try { try {
final String applicationBinaryPath = argResults['use-application-binary']; final String applicationBinaryPath = stringArg('use-application-binary');
app = await daemon.appDomain.startApp( app = await daemon.appDomain.startApp(
devices.first, fs.currentDirectory.path, targetFile, route, devices.first, fs.currentDirectory.path, targetFile, route,
_createDebuggingOptions(), hotMode, _createDebuggingOptions(), hotMode,
applicationBinary: applicationBinaryPath == null applicationBinary: applicationBinaryPath == null
? null ? null
: fs.file(applicationBinaryPath), : fs.file(applicationBinaryPath),
trackWidgetCreation: argResults['track-widget-creation'], trackWidgetCreation: boolArg('track-widget-creation'),
projectRootPath: argResults['project-root'], projectRootPath: stringArg('project-root'),
packagesFilePath: globalResults['packages'], packagesFilePath: globalResults['packages'] as String,
dillOutputPath: argResults['output-dill'], dillOutputPath: stringArg('output-dill'),
ipv6: ipv6, ipv6: ipv6,
); );
} catch (error) { } catch (error) {
@ -382,7 +382,7 @@ class RunCommand extends RunCommandBase {
for (Device device in devices) { for (Device device in devices) {
if (await device.isLocalEmulator) { if (await device.isLocalEmulator) {
if (await device.supportsHardwareRendering) { if (await device.supportsHardwareRendering) {
final bool enableSoftwareRendering = argResults['enable-software-rendering'] == true; final bool enableSoftwareRendering = boolArg('enable-software-rendering') == true;
if (enableSoftwareRendering) { if (enableSoftwareRendering) {
printStatus( printStatus(
'Using software rendering with device ${device.name}. You may get better performance ' 'Using software rendering with device ${device.name}. You may get better performance '
@ -412,8 +412,8 @@ class RunCommand extends RunCommandBase {
List<String> expFlags; List<String> expFlags;
if (argParser.options.containsKey(FlutterOptions.kEnableExperiment) && if (argParser.options.containsKey(FlutterOptions.kEnableExperiment) &&
argResults[FlutterOptions.kEnableExperiment].isNotEmpty) { stringsArg(FlutterOptions.kEnableExperiment).isNotEmpty) {
expFlags = argResults[FlutterOptions.kEnableExperiment]; expFlags = stringsArg(FlutterOptions.kEnableExperiment);
} }
final FlutterProject flutterProject = FlutterProject.current(); final FlutterProject flutterProject = FlutterProject.current();
final List<FlutterDevice> flutterDevices = <FlutterDevice>[ final List<FlutterDevice> flutterDevices = <FlutterDevice>[
@ -421,12 +421,12 @@ class RunCommand extends RunCommandBase {
await FlutterDevice.create( await FlutterDevice.create(
device, device,
flutterProject: flutterProject, flutterProject: flutterProject,
trackWidgetCreation: argResults['track-widget-creation'], trackWidgetCreation: boolArg('track-widget-creation'),
fileSystemRoots: argResults['filesystem-root'], fileSystemRoots: stringsArg('filesystem-root'),
fileSystemScheme: argResults['filesystem-scheme'], fileSystemScheme: stringArg('filesystem-scheme'),
viewFilter: argResults['isolate-filter'], viewFilter: stringArg('isolate-filter'),
experimentalFlags: expFlags, experimentalFlags: expFlags,
target: argResults['target'], target: stringArg('target'),
buildMode: getBuildMode(), buildMode: getBuildMode(),
dartDefines: dartDefines, dartDefines: dartDefines,
), ),
@ -438,19 +438,19 @@ class RunCommand extends RunCommandBase {
await devices.single.targetPlatform == TargetPlatform.web_javascript; await devices.single.targetPlatform == TargetPlatform.web_javascript;
ResidentRunner runner; ResidentRunner runner;
final String applicationBinaryPath = argResults['use-application-binary']; final String applicationBinaryPath = stringArg('use-application-binary');
if (hotMode && !webMode) { if (hotMode && !webMode) {
runner = HotRunner( runner = HotRunner(
flutterDevices, flutterDevices,
target: targetFile, target: targetFile,
debuggingOptions: _createDebuggingOptions(), debuggingOptions: _createDebuggingOptions(),
benchmarkMode: argResults['benchmark'], benchmarkMode: boolArg('benchmark'),
applicationBinary: applicationBinaryPath == null applicationBinary: applicationBinaryPath == null
? null ? null
: fs.file(applicationBinaryPath), : fs.file(applicationBinaryPath),
projectRootPath: argResults['project-root'], projectRootPath: stringArg('project-root'),
packagesFilePath: globalResults['packages'], packagesFilePath: globalResults['packages'] as String,
dillOutputPath: argResults['output-dill'], dillOutputPath: stringArg('output-dill'),
stayResident: stayResident, stayResident: stayResident,
ipv6: ipv6, ipv6: ipv6,
); );

View File

@ -83,7 +83,7 @@ class ScreenshotCommand extends FlutterCommand {
@override @override
Future<FlutterCommandResult> verifyThenRunCommand(String commandPath) async { Future<FlutterCommandResult> verifyThenRunCommand(String commandPath) async {
device = await findTargetDevice(); device = await findTargetDevice();
validateOptions(argResults[_kType], device, argResults[_kObservatoryUri]); validateOptions(stringArg(_kType), device, stringArg(_kObservatoryUri));
return super.verifyThenRunCommand(commandPath); return super.verifyThenRunCommand(commandPath);
} }
@ -91,10 +91,10 @@ class ScreenshotCommand extends FlutterCommand {
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
File outputFile; File outputFile;
if (argResults.wasParsed(_kOut)) { if (argResults.wasParsed(_kOut)) {
outputFile = fs.file(argResults[_kOut]); outputFile = fs.file(stringArg(_kOut));
} }
switch (argResults[_kType]) { switch (stringArg(_kType)) {
case _kDeviceType: case _kDeviceType:
await runScreenshot(outputFile); await runScreenshot(outputFile);
return null; return null;
@ -123,7 +123,7 @@ class ScreenshotCommand extends FlutterCommand {
final Map<String, dynamic> skp = await _invokeVmServiceRpc('_flutter.screenshotSkp'); final Map<String, dynamic> skp = await _invokeVmServiceRpc('_flutter.screenshotSkp');
outputFile ??= getUniqueFile(fs.currentDirectory, 'flutter', 'skp'); outputFile ??= getUniqueFile(fs.currentDirectory, 'flutter', 'skp');
final IOSink sink = outputFile.openWrite(); final IOSink sink = outputFile.openWrite();
sink.add(base64.decode(skp['skp'])); sink.add(base64.decode(skp['skp'] as String));
await sink.close(); await sink.close();
_showOutputFileInfo(outputFile); _showOutputFileInfo(outputFile);
_ensureOutputIsNotJsonRpcError(outputFile); _ensureOutputIsNotJsonRpcError(outputFile);
@ -133,14 +133,14 @@ class ScreenshotCommand extends FlutterCommand {
final Map<String, dynamic> response = await _invokeVmServiceRpc('_flutter.screenshot'); final Map<String, dynamic> response = await _invokeVmServiceRpc('_flutter.screenshot');
outputFile ??= getUniqueFile(fs.currentDirectory, 'flutter', 'png'); outputFile ??= getUniqueFile(fs.currentDirectory, 'flutter', 'png');
final IOSink sink = outputFile.openWrite(); final IOSink sink = outputFile.openWrite();
sink.add(base64.decode(response['screenshot'])); sink.add(base64.decode(response['screenshot'] as String));
await sink.close(); await sink.close();
_showOutputFileInfo(outputFile); _showOutputFileInfo(outputFile);
_ensureOutputIsNotJsonRpcError(outputFile); _ensureOutputIsNotJsonRpcError(outputFile);
} }
Future<Map<String, dynamic>> _invokeVmServiceRpc(String method) async { Future<Map<String, dynamic>> _invokeVmServiceRpc(String method) async {
final Uri observatoryUri = Uri.parse(argResults[_kObservatoryUri]); final Uri observatoryUri = Uri.parse(stringArg(_kObservatoryUri));
final VMService vmService = await VMService.connect(observatoryUri); final VMService vmService = await VMService.connect(observatoryUri);
return await vmService.vm.invokeRpcRaw(method); return await vmService.vm.invokeRpcRaw(method);
} }

View File

@ -53,7 +53,7 @@ class ShellCompletionCommand extends FlutterCommand {
} }
final File outputFile = fs.file(argResults.rest.first); final File outputFile = fs.file(argResults.rest.first);
if (outputFile.existsSync() && !argResults['overwrite']) { if (outputFile.existsSync() && !boolArg('overwrite')) {
throwToolExit( throwToolExit(
'Output file ${outputFile.path} already exists, will not overwrite. ' 'Output file ${outputFile.path} already exists, will not overwrite. '
'Use --overwrite to force overwriting existing output file.', 'Use --overwrite to force overwriting existing output file.',

View File

@ -109,7 +109,7 @@ class TestCommand extends FastFlutterCommand {
final Set<DevelopmentArtifact> results = <DevelopmentArtifact>{ final Set<DevelopmentArtifact> results = <DevelopmentArtifact>{
DevelopmentArtifact.universal, DevelopmentArtifact.universal,
}; };
if (argResults['platform'] == 'chrome') { if (stringArg('platform') == 'chrome') {
results.add(DevelopmentArtifact.web); results.add(DevelopmentArtifact.web);
} }
return results; return results;
@ -134,18 +134,18 @@ class TestCommand extends FastFlutterCommand {
if (shouldRunPub) { if (shouldRunPub) {
await pub.get(context: PubContext.getVerifyContext(name), skipPubspecYamlCheck: true); await pub.get(context: PubContext.getVerifyContext(name), skipPubspecYamlCheck: true);
} }
final bool buildTestAssets = argResults['test-assets']; final bool buildTestAssets = boolArg('test-assets');
final List<String> names = argResults['name']; final List<String> names = stringsArg('name');
final List<String> plainNames = argResults['plain-name']; final List<String> plainNames = stringsArg('plain-name');
final FlutterProject flutterProject = FlutterProject.current(); final FlutterProject flutterProject = FlutterProject.current();
if (buildTestAssets && flutterProject.manifest.assets.isNotEmpty) { if (buildTestAssets && flutterProject.manifest.assets.isNotEmpty) {
await _buildTestAsset(); await _buildTestAsset();
} }
Iterable<String> files = argResults.rest.map<String>((String testPath) => fs.path.absolute(testPath)).toList(); List<String> files = argResults.rest.map<String>((String testPath) => fs.path.absolute(testPath)).toList();
final bool startPaused = argResults['start-paused']; final bool startPaused = boolArg('start-paused');
if (startPaused && files.length != 1) { if (startPaused && files.length != 1) {
throwToolExit( throwToolExit(
'When using --start-paused, you must specify a single test file to run.', 'When using --start-paused, you must specify a single test file to run.',
@ -153,7 +153,7 @@ class TestCommand extends FastFlutterCommand {
); );
} }
final int jobs = int.tryParse(argResults['concurrency']); final int jobs = int.tryParse(stringArg('concurrency'));
if (jobs == null || jobs <= 0 || !jobs.isFinite) { if (jobs == null || jobs <= 0 || !jobs.isFinite) {
throwToolExit( throwToolExit(
'Could not parse -j/--concurrency argument. It must be an integer greater than zero.' 'Could not parse -j/--concurrency argument. It must be an integer greater than zero.'
@ -186,14 +186,14 @@ class TestCommand extends FastFlutterCommand {
} }
CoverageCollector collector; CoverageCollector collector;
if (argResults['coverage'] || argResults['merge-coverage']) { if (boolArg('coverage') || boolArg('merge-coverage')) {
final String projectName = FlutterProject.current().manifest.appName; final String projectName = FlutterProject.current().manifest.appName;
collector = CoverageCollector( collector = CoverageCollector(
libraryPredicate: (String libraryName) => libraryName.contains(projectName), libraryPredicate: (String libraryName) => libraryName.contains(projectName),
); );
} }
final bool machine = argResults['machine']; final bool machine = boolArg('machine');
if (collector != null && machine) { if (collector != null && machine) {
throwToolExit("The test command doesn't support --machine and coverage together"); throwToolExit("The test command doesn't support --machine and coverage together");
} }
@ -222,7 +222,7 @@ class TestCommand extends FastFlutterCommand {
} }
final bool disableServiceAuthCodes = final bool disableServiceAuthCodes =
argResults['disable-service-auth-codes']; boolArg('disable-service-auth-codes');
final int result = await runTests( final int result = await runTests(
files, files,
@ -233,21 +233,21 @@ class TestCommand extends FastFlutterCommand {
enableObservatory: collector != null || startPaused, enableObservatory: collector != null || startPaused,
startPaused: startPaused, startPaused: startPaused,
disableServiceAuthCodes: disableServiceAuthCodes, disableServiceAuthCodes: disableServiceAuthCodes,
ipv6: argResults['ipv6'], ipv6: boolArg('ipv6'),
machine: machine, machine: machine,
buildMode: BuildMode.debug, buildMode: BuildMode.debug,
trackWidgetCreation: argResults['track-widget-creation'], trackWidgetCreation: boolArg('track-widget-creation'),
updateGoldens: argResults['update-goldens'], updateGoldens: boolArg('update-goldens'),
concurrency: jobs, concurrency: jobs,
buildTestAssets: buildTestAssets, buildTestAssets: buildTestAssets,
flutterProject: flutterProject, flutterProject: flutterProject,
web: argResults['platform'] == 'chrome', web: stringArg('platform') == 'chrome',
); );
if (collector != null) { if (collector != null) {
final bool collectionResult = await collector.collectCoverageData( final bool collectionResult = await collector.collectCoverageData(
argResults['coverage-path'], stringArg('coverage-path'),
mergeCoverageData: argResults['merge-coverage'], mergeCoverageData: boolArg('merge-coverage'),
); );
if (!collectionResult) { if (!collectionResult) {
throwToolExit(null); throwToolExit(null);

View File

@ -58,7 +58,7 @@ class UnpackCommand extends FlutterCommand {
final Set<DevelopmentArtifact> result = <DevelopmentArtifact>{ final Set<DevelopmentArtifact> result = <DevelopmentArtifact>{
DevelopmentArtifact.universal, DevelopmentArtifact.universal,
}; };
final TargetPlatform targetPlatform = getTargetPlatformForName(argResults['target-platform']); final TargetPlatform targetPlatform = getTargetPlatformForName(stringArg('target-platform'));
switch (targetPlatform) { switch (targetPlatform) {
case TargetPlatform.windows_x64: case TargetPlatform.windows_x64:
result.add(DevelopmentArtifact.windows); result.add(DevelopmentArtifact.windows);
@ -73,8 +73,8 @@ class UnpackCommand extends FlutterCommand {
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
final String targetName = argResults['target-platform']; final String targetName = stringArg('target-platform');
final String targetDirectory = argResults['cache-dir']; final String targetDirectory = stringArg('cache-dir');
if (!fs.directory(targetDirectory).existsSync()) { if (!fs.directory(targetDirectory).existsSync()) {
fs.directory(targetDirectory).createSync(recursive: true); fs.directory(targetDirectory).createSync(recursive: true);
} }
@ -82,7 +82,7 @@ class UnpackCommand extends FlutterCommand {
final ArtifactUnpacker flutterArtifactFetcher = ArtifactUnpacker(targetPlatform); final ArtifactUnpacker flutterArtifactFetcher = ArtifactUnpacker(targetPlatform);
bool success = true; bool success = true;
if (artifacts is LocalEngineArtifacts) { if (artifacts is LocalEngineArtifacts) {
final LocalEngineArtifacts localEngineArtifacts = artifacts; final LocalEngineArtifacts localEngineArtifacts = artifacts as LocalEngineArtifacts;
success = flutterArtifactFetcher.copyLocalBuildArtifacts( success = flutterArtifactFetcher.copyLocalBuildArtifacts(
localEngineArtifacts.engineOutPath, localEngineArtifacts.engineOutPath,
targetDirectory, targetDirectory,
@ -203,8 +203,8 @@ class ArtifactUnpacker {
printTrace('Copied artifacts from $sourceDirectory.'); printTrace('Copied artifacts from $sourceDirectory.');
} catch (e, stackTrace) { } catch (e, stackTrace) {
printError(e.message as String);
printError(stackTrace.toString()); printError(stackTrace.toString());
printError(e.message);
return false; return false;
} }
return true; return true;

View File

@ -114,11 +114,11 @@ class UpdatePackagesCommand extends FlutterCommand {
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
final List<Directory> packages = runner.getRepoPackages(); final List<Directory> packages = runner.getRepoPackages();
final bool upgrade = argResults['force-upgrade']; final bool upgrade = boolArg('force-upgrade');
final bool isPrintPaths = argResults['paths']; final bool isPrintPaths = boolArg('paths');
final bool isPrintTransitiveClosure = argResults['transitive-closure']; final bool isPrintTransitiveClosure = boolArg('transitive-closure');
final bool isVerifyOnly = argResults['verify-only']; final bool isVerifyOnly = boolArg('verify-only');
final bool isConsumerOnly = argResults['consumer-only']; final bool isConsumerOnly = boolArg('consumer-only');
// "consumer" packages are those that constitute our public API (e.g. flutter, flutter_test, flutter_driver, flutter_localizations). // "consumer" packages are those that constitute our public API (e.g. flutter, flutter_test, flutter_driver, flutter_localizations).
if (isConsumerOnly) { if (isConsumerOnly) {
@ -298,7 +298,7 @@ class UpdatePackagesCommand extends FlutterCommand {
} }
if (isPrintPaths) { if (isPrintPaths) {
showDependencyPaths(from: argResults['from'], to: argResults['to'], tree: tree); showDependencyPaths(from: stringArg('from'), to: stringArg('to'), tree: tree);
return null; return null;
} }

View File

@ -59,8 +59,8 @@ class UpgradeCommand extends FlutterCommand {
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
await _commandRunner.runCommand( await _commandRunner.runCommand(
argResults['force'], boolArg('force'),
argResults['continue'], boolArg('continue'),
GitTagVersion.determine(), GitTagVersion.determine(),
FlutterVersion.instance, FlutterVersion.instance,
); );

View File

@ -72,7 +72,7 @@ class VersionCommand extends FlutterCommand {
bool withForce = false; bool withForce = false;
if (targetVersion < minSupportedVersion) { if (targetVersion < minSupportedVersion) {
if (!argResults['force']) { if (!boolArg('force')) {
printError( printError(
'Version command is not supported in $targetVersion and it is supported since version $minSupportedVersion' 'Version command is not supported in $targetVersion and it is supported since version $minSupportedVersion'
'which means if you switch to version $minSupportedVersion then you can not use version command.' 'which means if you switch to version $minSupportedVersion then you can not use version command.'

View File

@ -85,27 +85,27 @@ class AnalysisServer {
final dynamic response = json.decode(line); final dynamic response = json.decode(line);
if (response is Map<dynamic, dynamic>) { if (response is Map<String, dynamic>) {
if (response['event'] != null) { if (response['event'] != null) {
final String event = response['event']; final String event = response['event'] as String;
final dynamic params = response['params']; final dynamic params = response['params'];
if (params is Map<dynamic, dynamic>) { if (params is Map<String, dynamic>) {
if (event == 'server.status') { if (event == 'server.status') {
_handleStatus(response['params']); _handleStatus(castStringKeyedMap(response['params']));
} else if (event == 'analysis.errors') { } else if (event == 'analysis.errors') {
_handleAnalysisIssues(response['params']); _handleAnalysisIssues(castStringKeyedMap(response['params']));
} else if (event == 'server.error') { } else if (event == 'server.error') {
_handleServerError(response['params']); _handleServerError(castStringKeyedMap(response['params']));
} }
} }
} else if (response['error'] != null) { } else if (response['error'] != null) {
// Fields are 'code', 'message', and 'stackTrace'. // Fields are 'code', 'message', and 'stackTrace'.
final Map<String, dynamic> error = response['error']; final Map<String, dynamic> error = castStringKeyedMap(response['error']);
printError( printError(
'Error response from the server: ${error['code']} ${error['message']}'); 'Error response from the server: ${error['code']} ${error['message']}');
if (error['stackTrace'] != null) { if (error['stackTrace'] != null) {
printError(error['stackTrace']); printError(error['stackTrace'] as String);
} }
} }
} }
@ -114,7 +114,7 @@ class AnalysisServer {
void _handleStatus(Map<String, dynamic> statusInfo) { void _handleStatus(Map<String, dynamic> statusInfo) {
// {"event":"server.status","params":{"analysis":{"isAnalyzing":true}}} // {"event":"server.status","params":{"analysis":{"isAnalyzing":true}}}
if (statusInfo['analysis'] != null && !_analyzingController.isClosed) { if (statusInfo['analysis'] != null && !_analyzingController.isClosed) {
final bool isAnalyzing = statusInfo['analysis']['isAnalyzing']; final bool isAnalyzing = statusInfo['analysis']['isAnalyzing'] as bool;
_analyzingController.add(isAnalyzing); _analyzingController.add(isAnalyzing);
} }
} }
@ -123,15 +123,15 @@ class AnalysisServer {
// Fields are 'isFatal', 'message', and 'stackTrace'. // Fields are 'isFatal', 'message', and 'stackTrace'.
printError('Error from the analysis server: ${error['message']}'); printError('Error from the analysis server: ${error['message']}');
if (error['stackTrace'] != null) { if (error['stackTrace'] != null) {
printError(error['stackTrace']); printError(error['stackTrace'] as String);
} }
_didServerErrorOccur = true; _didServerErrorOccur = true;
} }
void _handleAnalysisIssues(Map<String, dynamic> issueInfo) { void _handleAnalysisIssues(Map<String, dynamic> issueInfo) {
// {"event":"analysis.errors","params":{"file":"/Users/.../lib/main.dart","errors":[]}} // {"event":"analysis.errors","params":{"file":"/Users/.../lib/main.dart","errors":[]}}
final String file = issueInfo['file']; final String file = issueInfo['file'] as String;
final List<dynamic> errorsList = issueInfo['errors']; final List<dynamic> errorsList = issueInfo['errors'] as List<dynamic>;
final List<AnalysisError> errors = errorsList final List<AnalysisError> errors = errorsList
.map<Map<String, dynamic>>(castStringKeyedMap) .map<Map<String, dynamic>>(castStringKeyedMap)
.map<AnalysisError>((Map<String, dynamic> json) => AnalysisError(json)) .map<AnalysisError>((Map<String, dynamic> json) => AnalysisError(json))
@ -171,7 +171,7 @@ class AnalysisError implements Comparable<AnalysisError> {
// },"message":"...","hasFix":false} // },"message":"...","hasFix":false}
Map<String, dynamic> json; Map<String, dynamic> json;
String get severity => json['severity']; String get severity => json['severity'] as String;
String get colorSeverity { String get colorSeverity {
switch(_severityLevel) { switch(_severityLevel) {
case _AnalysisSeverity.error: case _AnalysisSeverity.error:
@ -185,14 +185,14 @@ class AnalysisError implements Comparable<AnalysisError> {
return null; return null;
} }
_AnalysisSeverity get _severityLevel => _severityMap[severity] ?? _AnalysisSeverity.none; _AnalysisSeverity get _severityLevel => _severityMap[severity] ?? _AnalysisSeverity.none;
String get type => json['type']; String get type => json['type'] as String;
String get message => json['message']; String get message => json['message'] as String;
String get code => json['code']; String get code => json['code'] as String;
String get file => json['location']['file']; String get file => json['location']['file'] as String;
int get startLine => json['location']['startLine']; int get startLine => json['location']['startLine'] as int;
int get startColumn => json['location']['startColumn']; int get startColumn => json['location']['startColumn'] as int;
int get offset => json['location']['offset']; int get offset => json['location']['offset'] as int;
String get messageSentenceFragment { String get messageSentenceFragment {
if (message.endsWith('.')) { if (message.endsWith('.')) {

View File

@ -166,7 +166,7 @@ class _DefaultPub implements Pub {
'Running "flutter pub $command" in ${fs.path.basename(directory)}...', 'Running "flutter pub $command" in ${fs.path.basename(directory)}...',
timeout: timeoutConfiguration.slowOperation, timeout: timeoutConfiguration.slowOperation,
); );
final bool verbose = FlutterCommand.current != null && FlutterCommand.current.globalResults['verbose']; final bool verbose = FlutterCommand.current != null && FlutterCommand.current.globalResults['verbose'] as bool;
final List<String> args = <String>[ final List<String> args = <String>[
if (verbose) '--verbose' else '--verbosity=warning', if (verbose) '--verbose' else '--verbosity=warning',
...<String>[command, '--no-precompile'], ...<String>[command, '--no-precompile'],

View File

@ -58,7 +58,7 @@ class DevFSFileContent extends DevFSContent {
DevFSFileContent(this.file); DevFSFileContent(this.file);
final FileSystemEntity file; final FileSystemEntity file;
FileSystemEntity _linkTarget; File _linkTarget;
FileStat _fileStat; FileStat _fileStat;
File _getFile() { File _getFile() {
@ -69,7 +69,7 @@ class DevFSFileContent extends DevFSContent {
// The link target. // The link target.
return fs.file(file.resolveSymbolicLinksSync()); return fs.file(file.resolveSymbolicLinksSync());
} }
return file; return file as File;
} }
void _stat() { void _stat() {
@ -88,7 +88,7 @@ class DevFSFileContent extends DevFSContent {
if (_fileStat != null && _fileStat.type == FileSystemEntityType.link) { if (_fileStat != null && _fileStat.type == FileSystemEntityType.link) {
// Resolve, stat, and maybe cache the symlink target. // Resolve, stat, and maybe cache the symlink target.
final String resolved = file.resolveSymbolicLinksSync(); final String resolved = file.resolveSymbolicLinksSync();
final FileSystemEntity linkTarget = fs.file(resolved); final File linkTarget = fs.file(resolved);
// Stat the link target. // Stat the link target.
final FileStat fileStat = linkTarget.statSync(); final FileStat fileStat = linkTarget.statSync();
if (fileStat.type == FileSystemEntityType.notFound) { if (fileStat.type == FileSystemEntityType.notFound) {
@ -224,7 +224,7 @@ class ServiceProtocolDevFSOperations implements DevFSOperations {
@override @override
Future<Uri> create(String fsName) async { Future<Uri> create(String fsName) async {
final Map<String, dynamic> response = await vmService.vm.createDevFS(fsName); final Map<String, dynamic> response = await vmService.vm.createDevFS(fsName);
return Uri.parse(response['uri']); return Uri.parse(response['uri'] as String);
} }
@override @override

View File

@ -303,7 +303,6 @@ abstract class PollingDeviceDiscovery extends DeviceDiscovery {
} }
abstract class Device { abstract class Device {
Device(this.id, {@required this.category, @required this.platformType, @required this.ephemeral}); Device(this.id, {@required this.category, @required this.platformType, @required this.ephemeral});
final String id; final String id;
@ -356,16 +355,16 @@ abstract class Device {
bool isSupportedForProject(FlutterProject flutterProject); bool isSupportedForProject(FlutterProject flutterProject);
/// Check if a version of the given app is already installed /// Check if a version of the given app is already installed
Future<bool> isAppInstalled(ApplicationPackage app); Future<bool> isAppInstalled(covariant ApplicationPackage app);
/// Check if the latest build of the [app] is already installed. /// Check if the latest build of the [app] is already installed.
Future<bool> isLatestBuildInstalled(ApplicationPackage app); Future<bool> isLatestBuildInstalled(covariant ApplicationPackage app);
/// Install an app package on the current device /// Install an app package on the current device
Future<bool> installApp(ApplicationPackage app); Future<bool> installApp(covariant ApplicationPackage app);
/// Uninstall an app package from the current device /// Uninstall an app package from the current device
Future<bool> uninstallApp(ApplicationPackage app); Future<bool> uninstallApp(covariant ApplicationPackage app);
/// Check if the device is supported by Flutter /// Check if the device is supported by Flutter
bool isSupported(); bool isSupported();
@ -382,7 +381,7 @@ abstract class Device {
/// Get a log reader for this device. /// Get a log reader for this device.
/// If [app] is specified, this will return a log reader specific to that /// If [app] is specified, this will return a log reader specific to that
/// application. Otherwise, a global log reader will be returned. /// application. Otherwise, a global log reader will be returned.
DeviceLogReader getLogReader({ ApplicationPackage app }); DeviceLogReader getLogReader({ covariant ApplicationPackage app });
/// Get the port forwarder for this device. /// Get the port forwarder for this device.
DevicePortForwarder get portForwarder; DevicePortForwarder get portForwarder;
@ -398,7 +397,7 @@ abstract class Device {
/// [platformArgs] allows callers to pass platform-specific arguments to the /// [platformArgs] allows callers to pass platform-specific arguments to the
/// start call. The build mode is not used by all platforms. /// start call. The build mode is not used by all platforms.
Future<LaunchResult> startApp( Future<LaunchResult> startApp(
ApplicationPackage package, { covariant ApplicationPackage package, {
String mainPath, String mainPath,
String route, String route,
DebuggingOptions debuggingOptions, DebuggingOptions debuggingOptions,
@ -422,7 +421,7 @@ abstract class Device {
bool get supportsScreenshot => false; bool get supportsScreenshot => false;
/// Stop an app package on the current device. /// Stop an app package on the current device.
Future<bool> stopApp(ApplicationPackage app); Future<bool> stopApp(covariant ApplicationPackage app);
Future<void> takeScreenshot(File outputFile) => Future<void>.error('unimplemented'); Future<void> takeScreenshot(File outputFile) => Future<void>.error('unimplemented');
@ -582,17 +581,15 @@ class ForwardedPort {
final int hostPort; final int hostPort;
final int devicePort; final int devicePort;
final dynamic context; final Process context;
@override @override
String toString() => 'ForwardedPort HOST:$hostPort to DEVICE:$devicePort'; String toString() => 'ForwardedPort HOST:$hostPort to DEVICE:$devicePort';
/// Kill subprocess (if present) used in forwarding. /// Kill subprocess (if present) used in forwarding.
void dispose() { void dispose() {
final Process process = context; if (context != null) {
context.kill();
if (process != null) {
process.kill();
} }
} }
} }

View File

@ -571,9 +571,9 @@ class ValidationMessage {
if (other.runtimeType != runtimeType) { if (other.runtimeType != runtimeType) {
return false; return false;
} }
final ValidationMessage typedOther = other; return other is ValidationMessage
return typedOther.message == message && other.message == message
&& typedOther.type == type; && other.type == type;
} }
@override @override

View File

@ -53,7 +53,7 @@ class FeatureFlags {
} }
bool isEnabled = featureSetting.enabledByDefault; bool isEnabled = featureSetting.enabledByDefault;
if (feature.configSetting != null) { if (feature.configSetting != null) {
final bool configOverride = Config.instance.getValue(feature.configSetting); final bool configOverride = Config.instance.getValue(feature.configSetting) as bool;
if (configOverride != null) { if (configOverride != null) {
isEnabled = configOverride; isEnabled = configOverride;
} }

View File

@ -37,10 +37,10 @@ class FlutterManifest {
/// Returns null on missing or invalid manifest /// Returns null on missing or invalid manifest
@visibleForTesting @visibleForTesting
static FlutterManifest createFromString(String manifest) { static FlutterManifest createFromString(String manifest) {
return _createFromYaml(loadYaml(manifest)); return _createFromYaml(loadYaml(manifest) as YamlMap);
} }
static FlutterManifest _createFromYaml(dynamic yamlDocument) { static FlutterManifest _createFromYaml(YamlMap yamlDocument) {
final FlutterManifest pubspec = FlutterManifest._(); final FlutterManifest pubspec = FlutterManifest._();
if (yamlDocument != null && !_validate(yamlDocument)) { if (yamlDocument != null && !_validate(yamlDocument)) {
return null; return null;
@ -53,7 +53,7 @@ class FlutterManifest {
pubspec._descriptor = <String, dynamic>{}; pubspec._descriptor = <String, dynamic>{};
} }
final Map<dynamic, dynamic> flutterMap = pubspec._descriptor['flutter']; final Map<dynamic, dynamic> flutterMap = pubspec._descriptor['flutter'] as Map<dynamic, dynamic>;
if (flutterMap != null) { if (flutterMap != null) {
pubspec._flutterDescriptor = flutterMap.cast<String, dynamic>(); pubspec._flutterDescriptor = flutterMap.cast<String, dynamic>();
} else { } else {
@ -73,7 +73,7 @@ class FlutterManifest {
bool get isEmpty => _descriptor.isEmpty; bool get isEmpty => _descriptor.isEmpty;
/// The string value of the top-level `name` property in the `pubspec.yaml` file. /// The string value of the top-level `name` property in the `pubspec.yaml` file.
String get appName => _descriptor['name'] ?? ''; String get appName => _descriptor['name'] as String ?? '';
// Flag to avoid printing multiple invalid version messages. // Flag to avoid printing multiple invalid version messages.
bool _hasShowInvalidVersionMsg = false; bool _hasShowInvalidVersionMsg = false;
@ -119,14 +119,14 @@ class FlutterManifest {
} }
bool get usesMaterialDesign { bool get usesMaterialDesign {
return _flutterDescriptor['uses-material-design'] ?? false; return _flutterDescriptor['uses-material-design'] as bool ?? false;
} }
/// True if this Flutter module should use AndroidX dependencies. /// True if this Flutter module should use AndroidX dependencies.
/// ///
/// If false the deprecated Android Support library will be used. /// If false the deprecated Android Support library will be used.
bool get usesAndroidX { bool get usesAndroidX {
return _flutterDescriptor['module']['androidX'] ?? false; return _flutterDescriptor['module']['androidX'] as bool ?? false;
} }
/// True if this manifest declares a Flutter module project. /// True if this manifest declares a Flutter module project.
@ -153,14 +153,14 @@ class FlutterManifest {
/// such declaration. /// such declaration.
String get androidPackage { String get androidPackage {
if (isModule) { if (isModule) {
return _flutterDescriptor['module']['androidPackage']; return _flutterDescriptor['module']['androidPackage'] as String;
} }
if (isPlugin) { if (isPlugin) {
final YamlMap plugin = _flutterDescriptor['plugin']; final YamlMap plugin = _flutterDescriptor['plugin'] as YamlMap;
if (plugin.containsKey('platforms')) { if (plugin.containsKey('platforms')) {
return plugin['platforms']['android']['package']; return plugin['platforms']['android']['package'] as String;
} else { } else {
return plugin['androidPackage']; return plugin['androidPackage'] as String;
} }
} }
return null; return null;
@ -170,7 +170,7 @@ class FlutterManifest {
/// module descriptor. Returns null if there is no such declaration. /// module descriptor. Returns null if there is no such declaration.
String get iosBundleIdentifier { String get iosBundleIdentifier {
if (isModule) { if (isModule) {
return _flutterDescriptor['module']['iosBundleIdentifier']; return _flutterDescriptor['module']['iosBundleIdentifier'] as String;
} }
return null; return null;
} }
@ -180,7 +180,7 @@ class FlutterManifest {
} }
List<Map<String, dynamic>> get _rawFontsDescriptor { List<Map<String, dynamic>> get _rawFontsDescriptor {
final List<dynamic> fontList = _flutterDescriptor['fonts']; final List<dynamic> fontList = _flutterDescriptor['fonts'] as List<dynamic>;
return fontList == null return fontList == null
? const <Map<String, dynamic>>[] ? const <Map<String, dynamic>>[]
: fontList.map<Map<String, dynamic>>(castStringKeyedMap).toList(); : fontList.map<Map<String, dynamic>>(castStringKeyedMap).toList();
@ -189,7 +189,7 @@ class FlutterManifest {
List<Uri> get assets => _assets ??= _computeAssets(); List<Uri> get assets => _assets ??= _computeAssets();
List<Uri> _assets; List<Uri> _assets;
List<Uri> _computeAssets() { List<Uri> _computeAssets() {
final List<dynamic> assets = _flutterDescriptor['assets']; final List<dynamic> assets = _flutterDescriptor['assets'] as List<dynamic>;
if (assets == null) { if (assets == null) {
return const <Uri>[]; return const <Uri>[];
} }
@ -199,7 +199,7 @@ class FlutterManifest {
printError('Asset manifest contains a null or empty uri.'); printError('Asset manifest contains a null or empty uri.');
continue; continue;
} }
final String stringAsset = asset; final String stringAsset = asset as String;
try { try {
results.add(Uri.parse(Uri.encodeFull(stringAsset))); results.add(Uri.parse(Uri.encodeFull(stringAsset)));
} on FormatException { } on FormatException {
@ -223,8 +223,8 @@ class FlutterManifest {
final List<Font> fonts = <Font>[]; final List<Font> fonts = <Font>[];
for (Map<String, dynamic> fontFamily in _rawFontsDescriptor) { for (Map<String, dynamic> fontFamily in _rawFontsDescriptor) {
final List<dynamic> fontFiles = fontFamily['fonts']; final YamlList fontFiles = fontFamily['fonts'] as YamlList;
final String familyName = fontFamily['family']; final String familyName = fontFamily['family'] as String;
if (familyName == null) { if (familyName == null) {
printError('Warning: Missing family name for font.', emphasis: true); printError('Warning: Missing family name for font.', emphasis: true);
continue; continue;
@ -235,8 +235,8 @@ class FlutterManifest {
} }
final List<FontAsset> fontAssets = <FontAsset>[]; final List<FontAsset> fontAssets = <FontAsset>[];
for (Map<dynamic, dynamic> fontFile in fontFiles) { for (Map<dynamic, dynamic> fontFile in fontFiles.cast<Map<dynamic, dynamic>>()) {
final String asset = fontFile['asset']; final String asset = fontFile['asset'] as String;
if (asset == null) { if (asset == null) {
printError('Warning: Missing asset in fonts for $familyName', emphasis: true); printError('Warning: Missing asset in fonts for $familyName', emphasis: true);
continue; continue;
@ -244,12 +244,12 @@ class FlutterManifest {
fontAssets.add(FontAsset( fontAssets.add(FontAsset(
Uri.parse(asset), Uri.parse(asset),
weight: fontFile['weight'], weight: fontFile['weight'] as int,
style: fontFile['style'], style: fontFile['style'] as String,
)); ));
} }
if (fontAssets.isNotEmpty) { if (fontAssets.isNotEmpty) {
fonts.add(Font(fontFamily['family'], fontAssets)); fonts.add(Font(fontFamily['family'] as String, fontAssets));
} }
} }
return fonts; return fonts;
@ -327,7 +327,7 @@ bool _validate(YamlMap manifest) {
errors.add('Expected YAML key to be a a string, but got ${kvp.key}.'); errors.add('Expected YAML key to be a a string, but got ${kvp.key}.');
continue; continue;
} }
switch (kvp.key) { switch (kvp.key as String) {
case 'name': case 'name':
if (kvp.value is! String) { if (kvp.value is! String) {
errors.add('Expected "${kvp.key}" to be a string, but got ${kvp.value}.'); errors.add('Expected "${kvp.key}" to be a string, but got ${kvp.value}.');
@ -340,7 +340,7 @@ bool _validate(YamlMap manifest) {
if (kvp.value is! YamlMap) { if (kvp.value is! YamlMap) {
errors.add('Expected "${kvp.key}" section to be an object or null, but got ${kvp.value}.'); errors.add('Expected "${kvp.key}" section to be an object or null, but got ${kvp.value}.');
} }
_validateFlutter(kvp.value, errors); _validateFlutter(kvp.value as YamlMap, errors);
break; break;
default: default:
// additionalProperties are allowed. // additionalProperties are allowed.
@ -366,7 +366,7 @@ void _validateFlutter(YamlMap yaml, List<String> errors) {
errors.add('Expected YAML key to be a a string, but got ${kvp.key} (${kvp.value.runtimeType}).'); errors.add('Expected YAML key to be a a string, but got ${kvp.key} (${kvp.value.runtimeType}).');
continue; continue;
} }
switch (kvp.key) { switch (kvp.key as String) {
case 'uses-material-design': case 'uses-material-design':
if (kvp.value is! bool) { if (kvp.value is! bool) {
errors.add('Expected "${kvp.key}" to be a bool, but got ${kvp.value} (${kvp.value.runtimeType}).'); errors.add('Expected "${kvp.key}" to be a bool, but got ${kvp.value} (${kvp.value.runtimeType}).');
@ -382,7 +382,7 @@ void _validateFlutter(YamlMap yaml, List<String> errors) {
if (kvp.value is! YamlList || kvp.value[0] is! YamlMap) { if (kvp.value is! YamlList || kvp.value[0] is! YamlMap) {
errors.add('Expected "${kvp.key}" to be a list, but got ${kvp.value} (${kvp.value.runtimeType}).'); errors.add('Expected "${kvp.key}" to be a list, but got ${kvp.value} (${kvp.value.runtimeType}).');
} else { } else {
_validateFonts(kvp.value, errors); _validateFonts(kvp.value as YamlList, errors);
} }
break; break;
case 'module': case 'module':
@ -405,7 +405,7 @@ void _validateFlutter(YamlMap yaml, List<String> errors) {
errors.add('Expected "${kvp.key}" to be an object, but got ${kvp.value} (${kvp.value.runtimeType}).'); errors.add('Expected "${kvp.key}" to be an object, but got ${kvp.value} (${kvp.value.runtimeType}).');
break; break;
} }
final List<String> pluginErrors = Plugin.validatePluginYaml(kvp.value); final List<String> pluginErrors = Plugin.validatePluginYaml(kvp.value as YamlMap);
errors.addAll(pluginErrors); errors.addAll(pluginErrors);
break; break;
default: default:
@ -427,7 +427,7 @@ void _validateFonts(YamlList fonts, List<String> errors) {
errors.add('Unexpected child "$fontListEntry" found under "fonts". Expected a map.'); errors.add('Unexpected child "$fontListEntry" found under "fonts". Expected a map.');
continue; continue;
} }
final YamlMap fontMap = fontListEntry; final YamlMap fontMap = fontListEntry as YamlMap;
for (dynamic key in fontMap.keys.where((dynamic key) => key != 'family' && key != 'fonts')) { for (dynamic key in fontMap.keys.where((dynamic key) => key != 'family' && key != 'fonts')) {
errors.add('Unexpected child "$key" found under "fonts".'); errors.add('Unexpected child "$key" found under "fonts".');
} }
@ -445,12 +445,12 @@ void _validateFonts(YamlList fonts, List<String> errors) {
errors.add('Expected "fonts" to be a list of maps.'); errors.add('Expected "fonts" to be a list of maps.');
continue; continue;
} }
final YamlMap fontMapList = fontListItem; final YamlMap fontMapList = fontListItem as YamlMap;
for (final MapEntry<dynamic, dynamic> kvp in fontMapList.entries) { for (final MapEntry<dynamic, dynamic> kvp in fontMapList.entries) {
if (kvp.key is! String) { if (kvp.key is! String) {
errors.add('Expected "${kvp.key}" under "fonts" to be a string.'); errors.add('Expected "${kvp.key}" under "fonts" to be a string.');
} }
switch(kvp.key) { switch(kvp.key as String) {
case 'asset': case 'asset':
if (kvp.value is! String) { if (kvp.value is! String) {
errors.add('Expected font asset ${kvp.value} ((${kvp.value.runtimeType})) to be a string.'); errors.add('Expected font asset ${kvp.value} ((${kvp.value.runtimeType})) to be a string.');

View File

@ -10,6 +10,7 @@ import '../asset.dart';
import '../base/common.dart'; import '../base/common.dart';
import '../base/file_system.dart'; import '../base/file_system.dart';
import '../base/io.dart'; import '../base/io.dart';
import '../base/utils.dart';
import '../build_info.dart'; import '../build_info.dart';
import '../bundle.dart'; import '../bundle.dart';
import '../convert.dart'; import '../convert.dart';
@ -87,7 +88,7 @@ Future<void> _buildAssets(
} }
void _rewriteCmx(BuildMode mode, String runnerPackageSource, File src, File dst) { void _rewriteCmx(BuildMode mode, String runnerPackageSource, File src, File dst) {
final Map<String, dynamic> cmx = json.decode(src.readAsStringSync()); final Map<String, dynamic> cmx = castStringKeyedMap(json.decode(src.readAsStringSync()));
// If the app author has already specified the runner in the cmx file, then // If the app author has already specified the runner in the cmx file, then
// do not override it with something else. // do not override it with something else.
if (cmx.containsKey('runner')) { if (cmx.containsKey('runner')) {

View File

@ -87,7 +87,7 @@ class _FuchsiaLogReader extends DeviceLogReader {
: RegExp('INFO: ${_app.name}(\.cmx)?\\(flutter\\): '); : RegExp('INFO: ${_app.name}(\.cmx)?\\(flutter\\): ');
return Stream<String>.eventTransformed( return Stream<String>.eventTransformed(
lines, lines,
(Sink<String> outout) => _FuchsiaLogSink(outout, matchRegExp, startTime), (EventSink<String> output) => _FuchsiaLogSink(output, matchRegExp, startTime),
); );
} }
@ -710,7 +710,7 @@ class _FuchsiaPortForwarder extends DevicePortForwarder {
]; ];
final ProcessResult result = await processManager.run(command); final ProcessResult result = await processManager.run(command);
if (result.exitCode != 0) { if (result.exitCode != 0) {
throwToolExit(result.stderr); throwToolExit('Unforward command failed: $result');
} }
} }
} }

View File

@ -62,7 +62,7 @@ class IntelliJPlugins {
final Archive archive = final Archive archive =
ZipDecoder().decodeBytes(fs.file(jarPath).readAsBytesSync()); ZipDecoder().decodeBytes(fs.file(jarPath).readAsBytesSync());
final ArchiveFile file = archive.findFile('META-INF/plugin.xml'); final ArchiveFile file = archive.findFile('META-INF/plugin.xml');
final String content = utf8.decode(file.content); final String content = utf8.decode(file.content as List<int>);
const String versionStartTag = '<version>'; const String versionStartTag = '<version>';
final int start = content.indexOf(versionStartTag); final int start = content.indexOf(versionStartTag);
final int end = content.indexOf('</version>', start); final int end = content.indexOf('</version>', start);

View File

@ -208,7 +208,7 @@ Future<String> _chooseSigningIdentity(List<String> validCodeSigningIdentities) a
} }
if (validCodeSigningIdentities.length > 1) { if (validCodeSigningIdentities.length > 1) {
final String savedCertChoice = config.getValue('ios-signing-cert'); final String savedCertChoice = config.getValue('ios-signing-cert') as String;
if (savedCertChoice != null) { if (savedCertChoice != null) {
if (validCodeSigningIdentities.contains(savedCertChoice)) { if (validCodeSigningIdentities.contains(savedCertChoice)) {

View File

@ -158,7 +158,7 @@ class IOSDevice extends Device {
@override @override
final String name; final String name;
Map<ApplicationPackage, DeviceLogReader> _logReaders; Map<IOSApp, DeviceLogReader> _logReaders;
DevicePortForwarder _portForwarder; DevicePortForwarder _portForwarder;
@ -202,7 +202,7 @@ class IOSDevice extends Device {
} }
@override @override
Future<bool> isAppInstalled(ApplicationPackage app) async { Future<bool> isAppInstalled(IOSApp app) async {
RunResult apps; RunResult apps;
try { try {
apps = await processUtils.run( apps = await processUtils.run(
@ -219,12 +219,11 @@ class IOSDevice extends Device {
} }
@override @override
Future<bool> isLatestBuildInstalled(ApplicationPackage app) async => false; Future<bool> isLatestBuildInstalled(IOSApp app) async => false;
@override @override
Future<bool> installApp(ApplicationPackage app) async { Future<bool> installApp(IOSApp app) async {
final IOSApp iosApp = app; final Directory bundle = fs.directory(app.deviceBundlePath);
final Directory bundle = fs.directory(iosApp.deviceBundlePath);
if (!bundle.existsSync()) { if (!bundle.existsSync()) {
printError('Could not find application bundle at ${bundle.path}; have you run "flutter build ios"?'); printError('Could not find application bundle at ${bundle.path}; have you run "flutter build ios"?');
return false; return false;
@ -232,7 +231,7 @@ class IOSDevice extends Device {
try { try {
await processUtils.run( await processUtils.run(
<String>[_installerPath, '-i', iosApp.deviceBundlePath], <String>[_installerPath, '-i', app.deviceBundlePath],
throwOnError: true, throwOnError: true,
environment: Map<String, String>.fromEntries( environment: Map<String, String>.fromEntries(
<MapEntry<String, String>>[cache.dyLdLibEntry], <MapEntry<String, String>>[cache.dyLdLibEntry],
@ -246,7 +245,7 @@ class IOSDevice extends Device {
} }
@override @override
Future<bool> uninstallApp(ApplicationPackage app) async { Future<bool> uninstallApp(IOSApp app) async {
try { try {
await processUtils.run( await processUtils.run(
<String>[_installerPath, '-U', app.id], <String>[_installerPath, '-U', app.id],
@ -267,7 +266,7 @@ class IOSDevice extends Device {
@override @override
Future<LaunchResult> startApp( Future<LaunchResult> startApp(
ApplicationPackage package, { IOSApp package, {
String mainPath, String mainPath,
String route, String route,
DebuggingOptions debuggingOptions, DebuggingOptions debuggingOptions,
@ -295,7 +294,7 @@ class IOSDevice extends Device {
// Step 1: Build the precompiled/DBC application if necessary. // Step 1: Build the precompiled/DBC application if necessary.
final XcodeBuildResult buildResult = await buildXcodeProject( final XcodeBuildResult buildResult = await buildXcodeProject(
app: package, app: package as BuildableIOSApp,
buildInfo: debuggingOptions.buildInfo, buildInfo: debuggingOptions.buildInfo,
targetOverride: mainPath, targetOverride: mainPath,
buildForDevice: true, buildForDevice: true,
@ -317,8 +316,7 @@ class IOSDevice extends Device {
packageId ??= package.id; packageId ??= package.id;
// Step 2: Check that the application exists at the specified path. // Step 2: Check that the application exists at the specified path.
final IOSApp iosApp = package; final Directory bundle = fs.directory(package.deviceBundlePath);
final Directory bundle = fs.directory(iosApp.deviceBundlePath);
if (!bundle.existsSync()) { if (!bundle.existsSync()) {
printError('Could not find the built application bundle at ${bundle.path}.'); printError('Could not find the built application bundle at ${bundle.path}.');
return LaunchResult.failed(); return LaunchResult.failed();
@ -347,7 +345,7 @@ class IOSDevice extends Device {
if (debuggingOptions.dumpSkpOnShaderCompilation) '--dump-skp-on-shader-compilation', if (debuggingOptions.dumpSkpOnShaderCompilation) '--dump-skp-on-shader-compilation',
if (debuggingOptions.verboseSystemLogs) '--verbose-logging', if (debuggingOptions.verboseSystemLogs) '--verbose-logging',
if (debuggingOptions.cacheSkSL) '--cache-sksl', if (debuggingOptions.cacheSkSL) '--cache-sksl',
if (platformArgs['trace-startup'] ?? false) '--trace-startup', if (platformArgs['trace-startup'] as bool ?? false) '--trace-startup',
]; ];
final Status installStatus = logger.startProgress( final Status installStatus = logger.startProgress(
@ -426,7 +424,7 @@ class IOSDevice extends Device {
} }
@override @override
Future<bool> stopApp(ApplicationPackage app) async { Future<bool> stopApp(IOSApp app) async {
// Currently we don't have a way to stop an app running on iOS. // Currently we don't have a way to stop an app running on iOS.
return false; return false;
} }
@ -438,14 +436,14 @@ class IOSDevice extends Device {
Future<String> get sdkNameAndVersion async => 'iOS $_sdkVersion'; Future<String> get sdkNameAndVersion async => 'iOS $_sdkVersion';
@override @override
DeviceLogReader getLogReader({ ApplicationPackage app }) { DeviceLogReader getLogReader({ IOSApp app }) {
_logReaders ??= <ApplicationPackage, DeviceLogReader>{}; _logReaders ??= <IOSApp, DeviceLogReader>{};
return _logReaders.putIfAbsent(app, () => IOSDeviceLogReader(this, app)); return _logReaders.putIfAbsent(app, () => IOSDeviceLogReader(this, app));
} }
@visibleForTesting @visibleForTesting
void setLogReader(ApplicationPackage app, DeviceLogReader logReader) { void setLogReader(IOSApp app, DeviceLogReader logReader) {
_logReaders ??= <ApplicationPackage, DeviceLogReader>{}; _logReaders ??= <IOSApp, DeviceLogReader>{};
_logReaders[app] = logReader; _logReaders[app] = logReader;
} }
@ -475,7 +473,7 @@ class IOSDevice extends Device {
@override @override
void dispose() { void dispose() {
_logReaders.forEach((ApplicationPackage application, DeviceLogReader logReader) { _logReaders.forEach((IOSApp application, DeviceLogReader logReader) {
logReader.dispose(); logReader.dispose();
}); });
_portForwarder?.dispose(); _portForwarder?.dispose();
@ -544,7 +542,7 @@ String decodeSyslog(String line) {
@visibleForTesting @visibleForTesting
class IOSDeviceLogReader extends DeviceLogReader { class IOSDeviceLogReader extends DeviceLogReader {
IOSDeviceLogReader(this.device, ApplicationPackage app) { IOSDeviceLogReader(this.device, IOSApp app) {
_linesController = StreamController<String>.broadcast( _linesController = StreamController<String>.broadcast(
onListen: _listenToSysLog, onListen: _listenToSysLog,
onCancel: dispose, onCancel: dispose,
@ -637,7 +635,7 @@ class IOSDeviceLogReader extends DeviceLogReader {
// any specific prefix. To properly capture those, we enter "printing" mode // any specific prefix. To properly capture those, we enter "printing" mode
// after matching a log line from the runner. When in printing mode, we print // after matching a log line from the runner. When in printing mode, we print
// all lines until we find the start of another log message (from any app). // all lines until we find the start of another log message (from any app).
Function _newSyslogLineHandler() { void Function(String line) _newSyslogLineHandler() {
bool printing = false; bool printing = false;
return (String line) { return (String line) {

View File

@ -143,7 +143,7 @@ class IMobileDevice {
], ],
environment: executionEnv, environment: executionEnv,
)).processResult; )).processResult;
if (ideviceResult.stdout.contains('Usage: ideviceinfo')) { if ((ideviceResult.stdout as String).contains('Usage: ideviceinfo')) {
_isWorking = false; _isWorking = false;
return _isWorking; return _isWorking;
} }
@ -156,7 +156,7 @@ class IMobileDevice {
], ],
environment: executionEnv, environment: executionEnv,
)).processResult; )).processResult;
if (result.exitCode == 0 && result.stdout.isEmpty) { if (result.exitCode == 0 && (result.stdout as String).isEmpty) {
_isWorking = true; _isWorking = true;
} else { } else {
// Check that we can look up the names of any attached devices. // Check that we can look up the names of any attached devices.
@ -183,7 +183,7 @@ class IMobileDevice {
if (result.exitCode != 0) { if (result.exitCode != 0) {
throw ToolExit('idevice_id returned an error:\n${result.stderr}'); throw ToolExit('idevice_id returned an error:\n${result.stderr}');
} }
return result.stdout; return result.stdout as String;
} on ProcessException { } on ProcessException {
throw ToolExit('Failed to invoke idevice_id. Run flutter doctor.'); throw ToolExit('Failed to invoke idevice_id. Run flutter doctor.');
} }
@ -203,17 +203,19 @@ class IMobileDevice {
<MapEntry<String, String>>[cache.dyLdLibEntry] <MapEntry<String, String>>[cache.dyLdLibEntry]
), ),
); );
if (result.exitCode == 255 && result.stdout != null && result.stdout.contains('No device found')) { final String stdout = result.stdout as String;
throw IOSDeviceNotFoundError('ideviceinfo could not find device:\n${result.stdout}. Try unlocking attached devices.'); final String stderr = result.stderr as String;
if (result.exitCode == 255 && stdout != null && stdout.contains('No device found')) {
throw IOSDeviceNotFoundError('ideviceinfo could not find device:\n$stdout. Try unlocking attached devices.');
} }
if (result.exitCode == 255 && result.stderr != null && result.stderr.contains('Could not connect to lockdownd')) { if (result.exitCode == 255 && stderr != null && stderr.contains('Could not connect to lockdownd')) {
if (result.stderr.contains('error code -${LockdownReturnCode.pairingDialogResponsePending.code}')) { if (stderr.contains('error code -${LockdownReturnCode.pairingDialogResponsePending.code}')) {
throw const IOSDeviceNotTrustedError( throw const IOSDeviceNotTrustedError(
'Device info unavailable. Is the device asking to "Trust This Computer?"', 'Device info unavailable. Is the device asking to "Trust This Computer?"',
LockdownReturnCode.pairingDialogResponsePending, LockdownReturnCode.pairingDialogResponsePending,
); );
} }
if (result.stderr.contains('error code -${LockdownReturnCode.invalidHostId.code}')) { if (stderr.contains('error code -${LockdownReturnCode.invalidHostId.code}')) {
throw const IOSDeviceNotTrustedError( throw const IOSDeviceNotTrustedError(
'Device info unavailable. Device pairing "trust" may have been revoked.', 'Device info unavailable. Device pairing "trust" may have been revoked.',
LockdownReturnCode.invalidHostId, LockdownReturnCode.invalidHostId,
@ -221,9 +223,9 @@ class IMobileDevice {
} }
} }
if (result.exitCode != 0) { if (result.exitCode != 0) {
throw ToolExit('ideviceinfo returned an error:\n${result.stderr}'); throw ToolExit('ideviceinfo returned an error:\n$stderr');
} }
return result.stdout.trim(); return stdout.trim();
} on ProcessException { } on ProcessException {
throw ToolExit('Failed to invoke ideviceinfo. Run flutter doctor.'); throw ToolExit('Failed to invoke ideviceinfo. Run flutter doctor.');
} }

View File

@ -6,6 +6,7 @@ import '../base/context.dart';
import '../base/file_system.dart'; import '../base/file_system.dart';
import '../base/io.dart'; import '../base/io.dart';
import '../base/process.dart'; import '../base/process.dart';
import '../base/utils.dart';
import '../convert.dart'; import '../convert.dart';
import '../globals.dart'; import '../globals.dart';
@ -45,7 +46,7 @@ class PlistParser {
args, args,
throwOnError: true, throwOnError: true,
).stdout.trim(); ).stdout.trim();
return json.decode(jsonContent); return castStringKeyedMap(json.decode(jsonContent));
} on ProcessException catch (error) { } on ProcessException catch (error) {
printTrace('$error'); printTrace('$error');
return const <String, dynamic>{}; return const <String, dynamic>{};
@ -64,6 +65,6 @@ class PlistParser {
String getValueFromFile(String plistFilePath, String key) { String getValueFromFile(String plistFilePath, String key) {
assert(key != null); assert(key != null);
final Map<String, dynamic> parsed = parseFile(plistFilePath); final Map<String, dynamic> parsed = parseFile(plistFilePath);
return parsed[key]; return parsed[key] as String;
} }
} }

View File

@ -192,7 +192,7 @@ List<String> _xcodeBuildSettingsLines({
xcodeBuildSettings.add('FLUTTER_BUILD_NUMBER=$buildNumber'); xcodeBuildSettings.add('FLUTTER_BUILD_NUMBER=$buildNumber');
if (artifacts is LocalEngineArtifacts) { if (artifacts is LocalEngineArtifacts) {
final LocalEngineArtifacts localEngineArtifacts = artifacts; final LocalEngineArtifacts localEngineArtifacts = artifacts as LocalEngineArtifacts;
final String engineOutPath = localEngineArtifacts.engineOutPath; final String engineOutPath = localEngineArtifacts.engineOutPath;
xcodeBuildSettings.add('FLUTTER_ENGINE=${fs.path.dirname(fs.path.dirname(engineOutPath))}'); xcodeBuildSettings.add('FLUTTER_ENGINE=${fs.path.dirname(fs.path.dirname(engineOutPath))}');
xcodeBuildSettings.add('LOCAL_ENGINE=${fs.path.basename(engineOutPath)}'); xcodeBuildSettings.add('LOCAL_ENGINE=${fs.path.basename(engineOutPath)}');

View File

@ -23,7 +23,7 @@ export FLUTTER_TARGET=$target
export PROJECT_DIR=${linuxProject.project.directory.path} export PROJECT_DIR=${linuxProject.project.directory.path}
'''); ''');
if (artifacts is LocalEngineArtifacts) { if (artifacts is LocalEngineArtifacts) {
final LocalEngineArtifacts localEngineArtifacts = artifacts; final LocalEngineArtifacts localEngineArtifacts = artifacts as LocalEngineArtifacts;
final String engineOutPath = localEngineArtifacts.engineOutPath; final String engineOutPath = localEngineArtifacts.engineOutPath;
buffer.writeln('export FLUTTER_ENGINE=${fs.path.dirname(fs.path.dirname(engineOutPath))}'); buffer.writeln('export FLUTTER_ENGINE=${fs.path.dirname(fs.path.dirname(engineOutPath))}');
buffer.writeln('export LOCAL_ENGINE=${fs.path.basename(engineOutPath)}'); buffer.writeln('export LOCAL_ENGINE=${fs.path.basename(engineOutPath)}');

View File

@ -32,7 +32,7 @@ class LinuxDoctorValidator extends DoctorValidator {
validationType = ValidationType.missing; validationType = ValidationType.missing;
messages.add(ValidationMessage.error('clang++ is not installed')); messages.add(ValidationMessage.error('clang++ is not installed'));
} else { } else {
final String firstLine = clangResult.stdout.split('\n').first.trim(); final String firstLine = (clangResult.stdout as String).split('\n').first.trim();
final String versionString = RegExp(r'[0-9]+\.[0-9]+\.[0-9]+').firstMatch(firstLine).group(0); final String versionString = RegExp(r'[0-9]+\.[0-9]+\.[0-9]+').firstMatch(firstLine).group(0);
final Version version = Version.parse(versionString); final Version version = Version.parse(versionString);
if (version >= minimumClangVersion) { if (version >= minimumClangVersion) {
@ -59,7 +59,7 @@ class LinuxDoctorValidator extends DoctorValidator {
validationType = ValidationType.missing; validationType = ValidationType.missing;
messages.add(ValidationMessage.error('make is not installed')); messages.add(ValidationMessage.error('make is not installed'));
} else { } else {
final String firstLine = makeResult.stdout.split('\n').first.trim(); final String firstLine = (makeResult.stdout as String).split('\n').first.trim();
messages.add(ValidationMessage(firstLine)); messages.add(ValidationMessage(firstLine));
} }

View File

@ -43,7 +43,7 @@ abstract class MacOSApp extends ApplicationPackage {
} }
/// Look up the executable name for a macOS application bundle. /// Look up the executable name for a macOS application bundle.
static _ExecutableAndId _executableFromBundle(Directory applicationBundle) { static _ExecutableAndId _executableFromBundle(FileSystemEntity applicationBundle) {
final FileSystemEntityType entityType = fs.typeSync(applicationBundle.path); final FileSystemEntityType entityType = fs.typeSync(applicationBundle.path);
if (entityType == FileSystemEntityType.notFound) { if (entityType == FileSystemEntityType.notFound) {
printError('File "${applicationBundle.path}" does not exist.'); printError('File "${applicationBundle.path}" does not exist.');
@ -67,8 +67,8 @@ abstract class MacOSApp extends ApplicationPackage {
return null; return null;
} }
final Map<String, dynamic> propertyValues = PlistParser.instance.parseFile(plistPath); final Map<String, dynamic> propertyValues = PlistParser.instance.parseFile(plistPath);
final String id = propertyValues[PlistParser.kCFBundleIdentifierKey]; final String id = propertyValues[PlistParser.kCFBundleIdentifierKey] as String;
final String executableName = propertyValues[PlistParser.kCFBundleExecutable]; final String executableName = propertyValues[PlistParser.kCFBundleExecutable] as String;
if (id == null) { if (id == null) {
printError('Invalid prebuilt macOS app. Info.plist does not contain bundle identifier'); printError('Invalid prebuilt macOS app. Info.plist does not contain bundle identifier');
return null; return null;

View File

@ -309,13 +309,15 @@ class CocoaPods {
); );
status.stop(); status.stop();
if (logger.isVerbose || result.exitCode != 0) { if (logger.isVerbose || result.exitCode != 0) {
if (result.stdout.isNotEmpty) { final String stdout = result.stdout as String;
if (stdout.isNotEmpty) {
printStatus('CocoaPods\' output:\n'); printStatus('CocoaPods\' output:\n');
printStatus(result.stdout, indent: 4); printStatus(stdout, indent: 4);
} }
if (result.stderr.isNotEmpty) { final String stderr = result.stderr as String;
if (stderr.isNotEmpty) {
printStatus('Error output from CocoaPods:\n'); printStatus('Error output from CocoaPods:\n');
printStatus(result.stderr, indent: 4); printStatus(stderr, indent: 4);
} }
} }
if (result.exitCode != 0) { if (result.exitCode != 0) {
@ -326,7 +328,8 @@ class CocoaPods {
} }
void _diagnosePodInstallFailure(ProcessResult result) { void _diagnosePodInstallFailure(ProcessResult result) {
if (result.stdout is String && result.stdout.contains('out-of-date source repos')) { final dynamic stdout = result.stdout;
if (stdout is String && stdout.contains('out-of-date source repos')) {
printError( printError(
"Error: CocoaPods's specs repository is too out-of-date to satisfy dependencies.\n" "Error: CocoaPods's specs repository is too out-of-date to satisfy dependencies.\n"
'To update the CocoaPods specs, run:\n' 'To update the CocoaPods specs, run:\n'

View File

@ -32,7 +32,7 @@ class _DefaultPersistentToolState implements PersistentToolState {
final Config _config; final Config _config;
@override @override
bool get redisplayWelcomeMessage => _config.getValue(_kRedisplayWelcomeMessage); bool get redisplayWelcomeMessage => _config.getValue(_kRedisplayWelcomeMessage) as bool;
@override @override
set redisplayWelcomeMessage(bool value) { set redisplayWelcomeMessage(bool value) {

View File

@ -31,8 +31,8 @@ class AndroidPlugin extends PluginPlatform {
assert(validate(yaml)); assert(validate(yaml));
return AndroidPlugin( return AndroidPlugin(
name: name, name: name,
package: yaml['package'], package: yaml['package'] as String,
pluginClass: yaml['pluginClass'], pluginClass: yaml['pluginClass'] as String,
pluginPath: pluginPath, pluginPath: pluginPath,
); );
} }
@ -144,7 +144,7 @@ class IOSPlugin extends PluginPlatform {
return IOSPlugin( return IOSPlugin(
name: name, name: name,
classPrefix: '', classPrefix: '',
pluginClass: yaml['pluginClass'], pluginClass: yaml['pluginClass'] as String,
); );
} }
@ -188,7 +188,7 @@ class MacOSPlugin extends PluginPlatform {
assert(validate(yaml)); assert(validate(yaml));
return MacOSPlugin( return MacOSPlugin(
name: name, name: name,
pluginClass: yaml['pluginClass'], pluginClass: yaml['pluginClass'] as String,
); );
} }
@ -227,7 +227,7 @@ class WindowsPlugin extends PluginPlatform {
assert(validate(yaml)); assert(validate(yaml));
return WindowsPlugin( return WindowsPlugin(
name: name, name: name,
pluginClass: yaml['pluginClass'], pluginClass: yaml['pluginClass'] as String,
); );
} }
@ -267,7 +267,7 @@ class LinuxPlugin extends PluginPlatform {
assert(validate(yaml)); assert(validate(yaml));
return LinuxPlugin( return LinuxPlugin(
name: name, name: name,
pluginClass: yaml['pluginClass'], pluginClass: yaml['pluginClass'] as String,
); );
} }
@ -309,8 +309,8 @@ class WebPlugin extends PluginPlatform {
assert(validate(yaml)); assert(validate(yaml));
return WebPlugin( return WebPlugin(
name: name, name: name,
pluginClass: yaml['pluginClass'], pluginClass: yaml['pluginClass'] as String,
fileName: yaml['fileName'], fileName: yaml['fileName'] as String,
); );
} }

View File

@ -60,7 +60,7 @@ class Plugin {
/// pluginClass: SamplePlugin /// pluginClass: SamplePlugin
/// windows: /// windows:
/// pluginClass: SamplePlugin /// pluginClass: SamplePlugin
factory Plugin.fromYaml(String name, String path, dynamic pluginYaml) { factory Plugin.fromYaml(String name, String path, YamlMap pluginYaml) {
final List<String> errors = validatePluginYaml(pluginYaml); final List<String> errors = validatePluginYaml(pluginYaml);
if (errors.isNotEmpty) { if (errors.isNotEmpty) {
throwToolExit('Invalid plugin specification.\n${errors.join('\n')}'); throwToolExit('Invalid plugin specification.\n${errors.join('\n')}');
@ -74,7 +74,7 @@ class Plugin {
factory Plugin._fromMultiPlatformYaml(String name, String path, dynamic pluginYaml) { factory Plugin._fromMultiPlatformYaml(String name, String path, dynamic pluginYaml) {
assert (pluginYaml != null && pluginYaml['platforms'] != null, assert (pluginYaml != null && pluginYaml['platforms'] != null,
'Invalid multi-platform plugin specification.'); 'Invalid multi-platform plugin specification.');
final dynamic platformsYaml = pluginYaml['platforms']; final YamlMap platformsYaml = pluginYaml['platforms'] as YamlMap;
assert (_validateMultiPlatformYaml(platformsYaml).isEmpty, assert (_validateMultiPlatformYaml(platformsYaml).isEmpty,
'Invalid multi-platform plugin specification.'); 'Invalid multi-platform plugin specification.');
@ -84,34 +84,34 @@ class Plugin {
if (platformsYaml[AndroidPlugin.kConfigKey] != null) { if (platformsYaml[AndroidPlugin.kConfigKey] != null) {
platforms[AndroidPlugin.kConfigKey] = AndroidPlugin.fromYaml( platforms[AndroidPlugin.kConfigKey] = AndroidPlugin.fromYaml(
name, name,
platformsYaml[AndroidPlugin.kConfigKey], platformsYaml[AndroidPlugin.kConfigKey] as YamlMap,
path, path,
); );
} }
if (platformsYaml[IOSPlugin.kConfigKey] != null) { if (platformsYaml[IOSPlugin.kConfigKey] != null) {
platforms[IOSPlugin.kConfigKey] = platforms[IOSPlugin.kConfigKey] =
IOSPlugin.fromYaml(name, platformsYaml[IOSPlugin.kConfigKey]); IOSPlugin.fromYaml(name, platformsYaml[IOSPlugin.kConfigKey] as YamlMap);
} }
if (platformsYaml[LinuxPlugin.kConfigKey] != null) { if (platformsYaml[LinuxPlugin.kConfigKey] != null) {
platforms[LinuxPlugin.kConfigKey] = platforms[LinuxPlugin.kConfigKey] =
LinuxPlugin.fromYaml(name, platformsYaml[LinuxPlugin.kConfigKey]); LinuxPlugin.fromYaml(name, platformsYaml[LinuxPlugin.kConfigKey] as YamlMap);
} }
if (platformsYaml[MacOSPlugin.kConfigKey] != null) { if (platformsYaml[MacOSPlugin.kConfigKey] != null) {
platforms[MacOSPlugin.kConfigKey] = platforms[MacOSPlugin.kConfigKey] =
MacOSPlugin.fromYaml(name, platformsYaml[MacOSPlugin.kConfigKey]); MacOSPlugin.fromYaml(name, platformsYaml[MacOSPlugin.kConfigKey] as YamlMap);
} }
if (platformsYaml[WebPlugin.kConfigKey] != null) { if (platformsYaml[WebPlugin.kConfigKey] != null) {
platforms[WebPlugin.kConfigKey] = platforms[WebPlugin.kConfigKey] =
WebPlugin.fromYaml(name, platformsYaml[WebPlugin.kConfigKey]); WebPlugin.fromYaml(name, platformsYaml[WebPlugin.kConfigKey] as YamlMap);
} }
if (platformsYaml[WindowsPlugin.kConfigKey] != null) { if (platformsYaml[WindowsPlugin.kConfigKey] != null) {
platforms[WindowsPlugin.kConfigKey] = platforms[WindowsPlugin.kConfigKey] =
WindowsPlugin.fromYaml(name, platformsYaml[WindowsPlugin.kConfigKey]); WindowsPlugin.fromYaml(name, platformsYaml[WindowsPlugin.kConfigKey] as YamlMap);
} }
return Plugin( return Plugin(
@ -123,19 +123,19 @@ class Plugin {
factory Plugin._fromLegacyYaml(String name, String path, dynamic pluginYaml) { factory Plugin._fromLegacyYaml(String name, String path, dynamic pluginYaml) {
final Map<String, PluginPlatform> platforms = <String, PluginPlatform>{}; final Map<String, PluginPlatform> platforms = <String, PluginPlatform>{};
final String pluginClass = pluginYaml['pluginClass']; final String pluginClass = pluginYaml['pluginClass'] as String;
if (pluginYaml != null && pluginClass != null) { if (pluginYaml != null && pluginClass != null) {
final String androidPackage = pluginYaml['androidPackage']; final String androidPackage = pluginYaml['androidPackage'] as String;
if (androidPackage != null) { if (androidPackage != null) {
platforms[AndroidPlugin.kConfigKey] = AndroidPlugin( platforms[AndroidPlugin.kConfigKey] = AndroidPlugin(
name: name, name: name,
package: pluginYaml['androidPackage'], package: pluginYaml['androidPackage'] as String,
pluginClass: pluginClass, pluginClass: pluginClass,
pluginPath: path, pluginPath: path,
); );
} }
final String iosPrefix = pluginYaml['iosPrefix'] ?? ''; final String iosPrefix = pluginYaml['iosPrefix'] as String ?? '';
platforms[IOSPlugin.kConfigKey] = platforms[IOSPlugin.kConfigKey] =
IOSPlugin( IOSPlugin(
name: name, name: name,
@ -158,7 +158,7 @@ class Plugin {
'Invalid plugin specification. There must be only one key: "platforms", found multiple: ${yaml.keys.join(',')}', 'Invalid plugin specification. There must be only one key: "platforms", found multiple: ${yaml.keys.join(',')}',
]; ];
} else { } else {
return _validateMultiPlatformYaml(yaml['platforms']); return _validateMultiPlatformYaml(yaml['platforms'] as YamlMap);
} }
} else { } else {
return _validateLegacyYaml(yaml); return _validateLegacyYaml(yaml);
@ -166,25 +166,24 @@ class Plugin {
} }
static List<String> _validateMultiPlatformYaml(YamlMap yaml) { static List<String> _validateMultiPlatformYaml(YamlMap yaml) {
bool isInvalid(String key, bool Function(YamlMap) validate) {
final dynamic value = yaml[key];
return value is YamlMap && !validate(value);
}
final List<String> errors = <String>[]; final List<String> errors = <String>[];
if (yaml.containsKey(AndroidPlugin.kConfigKey) && if (isInvalid(AndroidPlugin.kConfigKey, AndroidPlugin.validate)) {
!AndroidPlugin.validate(yaml[AndroidPlugin.kConfigKey])) {
errors.add('Invalid "android" plugin specification.'); errors.add('Invalid "android" plugin specification.');
} }
if (yaml.containsKey(IOSPlugin.kConfigKey) && if (isInvalid(IOSPlugin.kConfigKey, IOSPlugin.validate)) {
!IOSPlugin.validate(yaml[IOSPlugin.kConfigKey])) {
errors.add('Invalid "ios" plugin specification.'); errors.add('Invalid "ios" plugin specification.');
} }
if (yaml.containsKey(LinuxPlugin.kConfigKey) && if (isInvalid(LinuxPlugin.kConfigKey, LinuxPlugin.validate)) {
!LinuxPlugin.validate(yaml[LinuxPlugin.kConfigKey])) {
errors.add('Invalid "linux" plugin specification.'); errors.add('Invalid "linux" plugin specification.');
} }
if (yaml.containsKey(MacOSPlugin.kConfigKey) && if (isInvalid(MacOSPlugin.kConfigKey, MacOSPlugin.validate)) {
!MacOSPlugin.validate(yaml[MacOSPlugin.kConfigKey])) {
errors.add('Invalid "macos" plugin specification.'); errors.add('Invalid "macos" plugin specification.');
} }
if (yaml.containsKey(WindowsPlugin.kConfigKey) && if (isInvalid(WindowsPlugin.kConfigKey, WindowsPlugin.validate)) {
!WindowsPlugin.validate(yaml[WindowsPlugin.kConfigKey])) {
errors.add('Invalid "windows" plugin specification.'); errors.add('Invalid "windows" plugin specification.');
} }
return errors; return errors;
@ -221,7 +220,7 @@ Plugin _pluginFromPubspec(String name, Uri packageRoot) {
return null; return null;
} }
final dynamic flutterConfig = pubspec['flutter']; final dynamic flutterConfig = pubspec['flutter'];
if (flutterConfig == null || !flutterConfig.containsKey('plugin')) { if (flutterConfig == null || !(flutterConfig.containsKey('plugin') as bool)) {
return null; return null;
} }
final String packageRootPath = fs.path.fromUri(packageRoot); final String packageRootPath = fs.path.fromUri(packageRoot);
@ -229,7 +228,7 @@ Plugin _pluginFromPubspec(String name, Uri packageRoot) {
return Plugin.fromYaml( return Plugin.fromYaml(
name, name,
packageRootPath, packageRootPath,
flutterConfig['plugin'], flutterConfig['plugin'] as YamlMap,
); );
} }
@ -400,7 +399,7 @@ Future<void> _writeAndroidPluginRegistrant(FlutterProject project, List<Plugin>
// If a plugin is using an embedding version older than 2.0 and the app is using 2.0, // If a plugin is using an embedding version older than 2.0 and the app is using 2.0,
// then add shim for the old plugins. // then add shim for the old plugins.
for (Map<String, dynamic> plugin in androidPlugins) { for (Map<String, dynamic> plugin in androidPlugins) {
if (plugin['supportsEmbeddingV1'] && !plugin['supportsEmbeddingV2']) { if (plugin['supportsEmbeddingV1'] as bool && !(plugin['supportsEmbeddingV2'] as bool)) {
templateContext['needsShim'] = true; templateContext['needsShim'] = true;
if (project.isModule) { if (project.isModule) {
printStatus( printStatus(
@ -420,7 +419,7 @@ Future<void> _writeAndroidPluginRegistrant(FlutterProject project, List<Plugin>
case AndroidEmbeddingVersion.v1: case AndroidEmbeddingVersion.v1:
default: default:
for (Map<String, dynamic> plugin in androidPlugins) { for (Map<String, dynamic> plugin in androidPlugins) {
if (!plugin['supportsEmbeddingV1'] && plugin['supportsEmbeddingV2']) { if (!(plugin['supportsEmbeddingV1'] as bool) && plugin['supportsEmbeddingV2'] as bool) {
throwToolExit( throwToolExit(
'The plugin `${plugin['name']}` requires your app to be migrated to ' 'The plugin `${plugin['name']}` requires your app to be migrated to '
'the Android embedding v2. Follow the steps on https://flutter.dev/go/android-project-migration ' 'the Android embedding v2. Follow the steps on https://flutter.dev/go/android-project-migration '

View File

@ -231,12 +231,12 @@ class FlutterProject {
if (!pubspecFile.existsSync()) { if (!pubspecFile.existsSync()) {
return null; return null;
} }
final YamlMap pubspec = loadYaml(pubspecFile.readAsStringSync()); final YamlMap pubspec = loadYaml(pubspecFile.readAsStringSync()) as YamlMap;
// If the pubspec file is empty, this will be null. // If the pubspec file is empty, this will be null.
if (pubspec == null) { if (pubspec == null) {
return null; return null;
} }
return pubspec['builders']; return pubspec['builders'] as YamlMap;
} }
/// Whether there are any builders used by this package. /// Whether there are any builders used by this package.

View File

@ -112,7 +112,7 @@ class DoctorResultEvent extends UsageEvent {
flutterUsage.sendEvent(category, parameter, label: label); flutterUsage.sendEvent(category, parameter, label: label);
return; return;
} }
final GroupedValidator group = validator; final GroupedValidator group = validator as GroupedValidator;
for (int i = 0; i < group.subValidators.length; i++) { for (int i = 0; i < group.subValidators.length; i++) {
final DoctorValidator v = group.subValidators[i]; final DoctorValidator v = group.subValidators[i];
final ValidationResult r = group.subResults[i]; final ValidationResult r = group.subResults[i];

View File

@ -496,8 +496,8 @@ class HotRunner extends ResidentRunner {
(reloadReport['success'] == false && (reloadReport['success'] == false &&
(reloadReport['details'] is Map<String, dynamic> && (reloadReport['details'] is Map<String, dynamic> &&
reloadReport['details']['notices'] is List<dynamic> && reloadReport['details']['notices'] is List<dynamic> &&
reloadReport['details']['notices'].isNotEmpty && (reloadReport['details']['notices'] as List<dynamic>).isNotEmpty &&
reloadReport['details']['notices'].every( (reloadReport['details']['notices'] as List<dynamic>).every(
(dynamic item) => item is Map<String, dynamic> && item['message'] is String (dynamic item) => item is Map<String, dynamic> && item['message'] is String
) )
) )
@ -509,7 +509,7 @@ class HotRunner extends ResidentRunner {
} }
return false; return false;
} }
if (!reloadReport['success']) { if (!(reloadReport['success'] as bool)) {
if (printErrors) { if (printErrors) {
printError('Hot reload was rejected:'); printError('Hot reload was rejected:');
for (Map<String, dynamic> notice in reloadReport['details']['notices']) { for (Map<String, dynamic> notice in reloadReport['details']['notices']) {
@ -754,16 +754,16 @@ class HotRunner extends ResidentRunner {
// Collect stats only from the first device. If/when run -d all is // Collect stats only from the first device. If/when run -d all is
// refactored, we'll probably need to send one hot reload/restart event // refactored, we'll probably need to send one hot reload/restart event
// per device to analytics. // per device to analytics.
firstReloadDetails ??= reloadReport['details']; firstReloadDetails ??= castStringKeyedMap(reloadReport['details']);
final int loadedLibraryCount = reloadReport['details']['loadedLibraryCount']; final int loadedLibraryCount = reloadReport['details']['loadedLibraryCount'] as int;
final int finalLibraryCount = reloadReport['details']['finalLibraryCount']; final int finalLibraryCount = reloadReport['details']['finalLibraryCount'] as int;
printTrace('reloaded $loadedLibraryCount of $finalLibraryCount libraries'); printTrace('reloaded $loadedLibraryCount of $finalLibraryCount libraries');
reloadMessage = 'Reloaded $loadedLibraryCount of $finalLibraryCount libraries'; reloadMessage = 'Reloaded $loadedLibraryCount of $finalLibraryCount libraries';
} }
} on Map<String, dynamic> catch (error, stackTrace) { } on Map<String, dynamic> catch (error, stackTrace) {
printTrace('Hot reload failed: $error\n$stackTrace'); printTrace('Hot reload failed: $error\n$stackTrace');
final int errorCode = error['code']; final int errorCode = error['code'] as int;
String errorMessage = error['message']; String errorMessage = error['message'] as String;
if (errorCode == Isolate.kIsolateReloadBarred) { if (errorCode == Isolate.kIsolateReloadBarred) {
errorMessage = 'Unable to hot reload application due to an unrecoverable error in ' errorMessage = 'Unable to hot reload application due to an unrecoverable error in '
'the source code. Please address the error and then use "R" to ' 'the source code. Please address the error and then use "R" to '
@ -905,10 +905,10 @@ class HotRunner extends ResidentRunner {
fullRestart: false, fullRestart: false,
reason: reason, reason: reason,
overallTimeInMs: reloadInMs, overallTimeInMs: reloadInMs,
finalLibraryCount: firstReloadDetails['finalLibraryCount'], finalLibraryCount: firstReloadDetails['finalLibraryCount'] as int,
syncedLibraryCount: firstReloadDetails['receivedLibraryCount'], syncedLibraryCount: firstReloadDetails['receivedLibraryCount'] as int,
syncedClassesCount: firstReloadDetails['receivedClassesCount'], syncedClassesCount: firstReloadDetails['receivedClassesCount'] as int,
syncedProceduresCount: firstReloadDetails['receivedProceduresCount'], syncedProceduresCount: firstReloadDetails['receivedProceduresCount'] as int,
syncedBytes: updatedDevFS.syncedBytes, syncedBytes: updatedDevFS.syncedBytes,
invalidatedSourcesCount: updatedDevFS.invalidatedSourcesCount, invalidatedSourcesCount: updatedDevFS.invalidatedSourcesCount,
transferTimeInMs: devFSTimer.elapsed.inMilliseconds, transferTimeInMs: devFSTimer.elapsed.inMilliseconds,

View File

@ -113,7 +113,7 @@ abstract class FlutterCommand extends Command<void> {
); );
@override @override
FlutterCommandRunner get runner => super.runner; FlutterCommandRunner get runner => super.runner as FlutterCommandRunner;
bool _requiresPubspecYaml = false; bool _requiresPubspecYaml = false;
@ -126,7 +126,7 @@ abstract class FlutterCommand extends Command<void> {
bool _usesIpv6Flag = false; bool _usesIpv6Flag = false;
bool get shouldRunPub => _usesPubOption && argResults['pub']; bool get shouldRunPub => _usesPubOption && boolArg('pub');
bool get shouldUpdateCache => true; bool get shouldUpdateCache => true;
@ -173,7 +173,7 @@ abstract class FlutterCommand extends Command<void> {
String get targetFile { String get targetFile {
if (argResults.wasParsed('target')) { if (argResults.wasParsed('target')) {
return argResults['target']; return stringArg('target');
} }
if (argResults.rest.isNotEmpty) { if (argResults.rest.isNotEmpty) {
return argResults.rest.first; return argResults.rest.first;
@ -252,7 +252,7 @@ abstract class FlutterCommand extends Command<void> {
'"--host-vmservice-port" may be specified.'); '"--host-vmservice-port" may be specified.');
} }
try { try {
return int.parse(argResults['observatory-port'] ?? argResults['host-vmservice-port']); return int.parse(stringArg('observatory-port') ?? stringArg('host-vmservice-port'));
} on FormatException catch (error) { } on FormatException catch (error) {
throwToolExit('Invalid port for `--observatory-port/--host-vmservice-port`: $error'); throwToolExit('Invalid port for `--observatory-port/--host-vmservice-port`: $error');
} }
@ -267,7 +267,7 @@ abstract class FlutterCommand extends Command<void> {
return null; return null;
} }
try { try {
return int.parse(argResults['device-vmservice-port']); return int.parse(stringArg('device-vmservice-port'));
} on FormatException catch (error) { } on FormatException catch (error) {
throwToolExit('Invalid port for `--device-vmservice-port`: $error'); throwToolExit('Invalid port for `--device-vmservice-port`: $error');
} }
@ -285,7 +285,7 @@ abstract class FlutterCommand extends Command<void> {
_usesIpv6Flag = true; _usesIpv6Flag = true;
} }
bool get ipv6 => _usesIpv6Flag ? argResults['ipv6'] : null; bool get ipv6 => _usesIpv6Flag ? boolArg('ipv6') : null;
void usesBuildNumberOption() { void usesBuildNumberOption() {
argParser.addOption('build-number', argParser.addOption('build-number',
@ -318,7 +318,7 @@ abstract class FlutterCommand extends Command<void> {
} }
/// The values passed via the `--dart-define` option. /// The values passed via the `--dart-define` option.
List<String> get dartDefines => argResults['dart-define']; List<String> get dartDefines => stringsArg('dart-define');
void usesIsolateFilterOption({ @required bool hide }) { void usesIsolateFilterOption({ @required bool hide }) {
argParser.addOption('isolate-filter', argParser.addOption('isolate-filter',
@ -382,18 +382,18 @@ abstract class FlutterCommand extends Command<void> {
} }
BuildMode getBuildMode() { BuildMode getBuildMode() {
final bool debugResult = _excludeDebug ? false : argResults['debug']; final bool debugResult = !_excludeDebug && boolArg('debug');
final List<bool> modeFlags = <bool>[debugResult, argResults['profile'], argResults['release']]; final List<bool> modeFlags = <bool>[debugResult, boolArg('profile'), boolArg('release')];
if (modeFlags.where((bool flag) => flag).length > 1) { if (modeFlags.where((bool flag) => flag).length > 1) {
throw UsageException('Only one of --debug, --profile, or --release can be specified.', null); throw UsageException('Only one of --debug, --profile, or --release can be specified.', null);
} }
if (debugResult) { if (debugResult) {
return BuildMode.debug; return BuildMode.debug;
} }
if (argResults['profile']) { if (boolArg('profile')) {
return BuildMode.profile; return BuildMode.profile;
} }
if (argResults['release']) { if (boolArg('release')) {
return BuildMode.release; return BuildMode.release;
} }
return _defaultBuildMode; return _defaultBuildMode;
@ -419,21 +419,20 @@ abstract class FlutterCommand extends Command<void> {
} }
BuildInfo getBuildInfo() { BuildInfo getBuildInfo() {
final bool trackWidgetCreation = argParser.options.containsKey('track-widget-creation') final bool trackWidgetCreation = argParser.options.containsKey('track-widget-creation') &&
? argResults['track-widget-creation'] boolArg('track-widget-creation');
: false;
final String buildNumber = argParser.options.containsKey('build-number') && argResults['build-number'] != null final String buildNumber = argParser.options.containsKey('build-number')
? argResults['build-number'] ? stringArg('build-number')
: null; : null;
String extraFrontEndOptions = String extraFrontEndOptions =
argParser.options.containsKey(FlutterOptions.kExtraFrontEndOptions) argParser.options.containsKey(FlutterOptions.kExtraFrontEndOptions)
? argResults[FlutterOptions.kExtraFrontEndOptions] ? stringArg(FlutterOptions.kExtraFrontEndOptions)
: null; : null;
if (argParser.options.containsKey(FlutterOptions.kEnableExperiment) && if (argParser.options.containsKey(FlutterOptions.kEnableExperiment) &&
argResults[FlutterOptions.kEnableExperiment] != null) { argResults[FlutterOptions.kEnableExperiment] != null) {
for (String expFlag in argResults[FlutterOptions.kEnableExperiment]) { for (String expFlag in stringsArg(FlutterOptions.kEnableExperiment)) {
final String flag = '--enable-experiment=' + expFlag; final String flag = '--enable-experiment=' + expFlag;
if (extraFrontEndOptions != null) { if (extraFrontEndOptions != null) {
extraFrontEndOptions += ',' + flag; extraFrontEndOptions += ',' + flag;
@ -445,20 +444,22 @@ abstract class FlutterCommand extends Command<void> {
return BuildInfo(getBuildMode(), return BuildInfo(getBuildMode(),
argParser.options.containsKey('flavor') argParser.options.containsKey('flavor')
? argResults['flavor'] ? stringArg('flavor')
: null, : null,
trackWidgetCreation: trackWidgetCreation, trackWidgetCreation: trackWidgetCreation,
extraFrontEndOptions: extraFrontEndOptions, extraFrontEndOptions: extraFrontEndOptions,
extraGenSnapshotOptions: argParser.options.containsKey(FlutterOptions.kExtraGenSnapshotOptions) extraGenSnapshotOptions: argParser.options.containsKey(FlutterOptions.kExtraGenSnapshotOptions)
? argResults[FlutterOptions.kExtraGenSnapshotOptions] ? stringArg(FlutterOptions.kExtraGenSnapshotOptions)
: null, : null,
fileSystemRoots: argParser.options.containsKey(FlutterOptions.kFileSystemRoot) fileSystemRoots: argParser.options.containsKey(FlutterOptions.kFileSystemRoot)
? argResults[FlutterOptions.kFileSystemRoot] : null, ? stringsArg(FlutterOptions.kFileSystemRoot)
: null,
fileSystemScheme: argParser.options.containsKey(FlutterOptions.kFileSystemScheme) fileSystemScheme: argParser.options.containsKey(FlutterOptions.kFileSystemScheme)
? argResults[FlutterOptions.kFileSystemScheme] : null, ? stringArg(FlutterOptions.kFileSystemScheme)
: null,
buildNumber: buildNumber, buildNumber: buildNumber,
buildName: argParser.options.containsKey('build-name') buildName: argParser.options.containsKey('build-name')
? argResults['build-name'] ? stringArg('build-name')
: null, : null,
); );
} }
@ -471,7 +472,7 @@ abstract class FlutterCommand extends Command<void> {
/// tracking of the command. /// tracking of the command.
Future<String> get usagePath async { Future<String> get usagePath async {
if (parent is FlutterCommand) { if (parent is FlutterCommand) {
final FlutterCommand commandParent = parent; final FlutterCommand commandParent = parent as FlutterCommand;
final String path = await commandParent.usagePath; final String path = await commandParent.usagePath;
// Don't report for parents that return null for usagePath. // Don't report for parents that return null for usagePath.
return path == null ? null : '$path/$name'; return path == null ? null : '$path/$name';
@ -683,7 +684,7 @@ abstract class FlutterCommand extends Command<void> {
} }
// Validate the current package map only if we will not be running "pub get" later. // Validate the current package map only if we will not be running "pub get" later.
if (parent?.name != 'pub' && !(_usesPubOption && argResults['pub'])) { if (parent?.name != 'pub' && !(_usesPubOption && boolArg('pub'))) {
final String error = PackageMap(PackageMap.globalPackagesPath).checkValid(); final String error = PackageMap(PackageMap.globalPackagesPath).checkValid();
if (error != null) { if (error != null) {
throw ToolExit(error); throw ToolExit(error);
@ -700,6 +701,15 @@ abstract class FlutterCommand extends Command<void> {
} }
ApplicationPackageStore applicationPackages; ApplicationPackageStore applicationPackages;
/// Gets the parsed command-line option named [name] as `bool`.
bool boolArg(String name) => argResults[name] as bool;
/// Gets the parsed command-line option named [name] as `String`.
String stringArg(String name) => argResults[name] as String;
/// Gets the parsed command-line option named [name] as `List<String>`.
List<String> stringsArg(String name) => argResults[name] as List<String>;
} }
/// A mixin which applies an implementation of [requiredArtifacts] that only /// A mixin which applies an implementation of [requiredArtifacts] that only
@ -735,7 +745,7 @@ mixin TargetPlatformBasedDevelopmentArtifacts on FlutterCommand {
Future<Set<DevelopmentArtifact>> get requiredArtifacts async { Future<Set<DevelopmentArtifact>> get requiredArtifacts async {
// If there is no specified target device, fallback to the default // If there is no specified target device, fallback to the default
// confiugration. // confiugration.
final String rawTargetPlatform = argResults['target-platform']; final String rawTargetPlatform = stringArg('target-platform');
final TargetPlatform targetPlatform = getTargetPlatformForName(rawTargetPlatform); final TargetPlatform targetPlatform = getTargetPlatformForName(rawTargetPlatform);
if (targetPlatform == null) { if (targetPlatform == null) {
return super.requiredArtifacts; return super.requiredArtifacts;

View File

@ -212,7 +212,7 @@ class FlutterCommandRunner extends CommandRunner<void> {
} catch (error) { } catch (error) {
// we don't have a logger at the time this is run // we don't have a logger at the time this is run
// (which is why we don't use printTrace here) // (which is why we don't use printTrace here)
print(userMessages.runnerNoRoot(error)); print(userMessages.runnerNoRoot('$error'));
} }
return '.'; return '.';
} }
@ -224,7 +224,7 @@ class FlutterCommandRunner extends CommandRunner<void> {
// override this function so we can call tryArgsCompletion instead, so the // override this function so we can call tryArgsCompletion instead, so the
// completion package can interrogate the argParser, and as part of that, // completion package can interrogate the argParser, and as part of that,
// it calls argParser.parse(args) itself and returns the result. // it calls argParser.parse(args) itself and returns the result.
return tryArgsCompletion(args, argParser); return tryArgsCompletion(args.toList(), argParser);
} on ArgParserException catch (error) { } on ArgParserException catch (error) {
if (error.commands.isEmpty) { if (error.commands.isEmpty) {
usageException(error.message); usageException(error.message);
@ -258,7 +258,7 @@ class FlutterCommandRunner extends CommandRunner<void> {
}; };
// Check for verbose. // Check for verbose.
if (topLevelResults['verbose']) { if (topLevelResults['verbose'] as bool) {
// Override the logger. // Override the logger.
contextOverrides[Logger] = VerboseLogger(logger); contextOverrides[Logger] = VerboseLogger(logger);
} }
@ -269,7 +269,7 @@ class FlutterCommandRunner extends CommandRunner<void> {
int wrapColumn; int wrapColumn;
if (topLevelResults.wasParsed('wrap-column')) { if (topLevelResults.wasParsed('wrap-column')) {
try { try {
wrapColumn = int.parse(topLevelResults['wrap-column']); wrapColumn = int.parse(topLevelResults['wrap-column'] as String);
if (wrapColumn < 0) { if (wrapColumn < 0) {
throwToolExit(userMessages.runnerWrapColumnInvalid(topLevelResults['wrap-column'])); throwToolExit(userMessages.runnerWrapColumnInvalid(topLevelResults['wrap-column']));
} }
@ -281,23 +281,23 @@ class FlutterCommandRunner extends CommandRunner<void> {
// If we're not writing to a terminal with a defined width, then don't wrap // If we're not writing to a terminal with a defined width, then don't wrap
// anything, unless the user explicitly said to. // anything, unless the user explicitly said to.
final bool useWrapping = topLevelResults.wasParsed('wrap') final bool useWrapping = topLevelResults.wasParsed('wrap')
? topLevelResults['wrap'] ? topLevelResults['wrap'] as bool
: io.stdio.terminalColumns == null ? false : topLevelResults['wrap']; : io.stdio.terminalColumns != null && topLevelResults['wrap'] as bool;
contextOverrides[OutputPreferences] = OutputPreferences( contextOverrides[OutputPreferences] = OutputPreferences(
wrapText: useWrapping, wrapText: useWrapping,
showColor: topLevelResults['color'], showColor: topLevelResults['color'] as bool,
wrapColumn: wrapColumn, wrapColumn: wrapColumn,
); );
if (topLevelResults['show-test-device'] || if (topLevelResults['show-test-device'] as bool ||
topLevelResults['device-id'] == FlutterTesterDevices.kTesterDeviceId) { topLevelResults['device-id'] == FlutterTesterDevices.kTesterDeviceId) {
FlutterTesterDevices.showFlutterTesterDevice = true; FlutterTesterDevices.showFlutterTesterDevice = true;
} }
String recordTo = topLevelResults['record-to']; String recordTo = topLevelResults['record-to'] as String;
String replayFrom = topLevelResults['replay-from']; String replayFrom = topLevelResults['replay-from'] as String;
if (topLevelResults['bug-report']) { if (topLevelResults['bug-report'] as bool) {
// --bug-report implies --record-to=<tmp_path> // --bug-report implies --record-to=<tmp_path>
final Directory tempDir = const LocalFileSystem() final Directory tempDir = const LocalFileSystem()
.systemTempDirectory .systemTempDirectory
@ -353,7 +353,7 @@ class FlutterCommandRunner extends CommandRunner<void> {
// We must set Cache.flutterRoot early because other features use it (e.g. // We must set Cache.flutterRoot early because other features use it (e.g.
// enginePath's initializer uses it). // enginePath's initializer uses it).
final String flutterRoot = topLevelResults['flutter-root'] ?? defaultFlutterRoot; final String flutterRoot = topLevelResults['flutter-root'] as String ?? defaultFlutterRoot;
Cache.flutterRoot = fs.path.normalize(fs.path.absolute(flutterRoot)); Cache.flutterRoot = fs.path.normalize(fs.path.absolute(flutterRoot));
// Set up the tooling configuration. // Set up the tooling configuration.
@ -369,13 +369,13 @@ class FlutterCommandRunner extends CommandRunner<void> {
return MapEntry<Type, Generator>(type, () => value); return MapEntry<Type, Generator>(type, () => value);
}), }),
body: () async { body: () async {
logger.quiet = topLevelResults['quiet']; logger.quiet = topLevelResults['quiet'] as bool;
if (platform.environment['FLUTTER_ALREADY_LOCKED'] != 'true') { if (platform.environment['FLUTTER_ALREADY_LOCKED'] != 'true') {
await Cache.lock(); await Cache.lock();
} }
if (topLevelResults['suppress-analytics']) { if (topLevelResults['suppress-analytics'] as bool) {
flutterUsage.suppressAnalytics = true; flutterUsage.suppressAnalytics = true;
} }
@ -387,21 +387,21 @@ class FlutterCommandRunner extends CommandRunner<void> {
printError('Please ensure you have permissions in the artifact cache directory.'); printError('Please ensure you have permissions in the artifact cache directory.');
throwToolExit('Failed to write the version file'); throwToolExit('Failed to write the version file');
} }
if (topLevelResults.command?.name != 'upgrade' && topLevelResults['version-check']) { if (topLevelResults.command?.name != 'upgrade' && topLevelResults['version-check'] as bool) {
await FlutterVersion.instance.checkFlutterVersionFreshness(); await FlutterVersion.instance.checkFlutterVersionFreshness();
} }
if (topLevelResults.wasParsed('packages')) { if (topLevelResults.wasParsed('packages')) {
PackageMap.globalPackagesPath = fs.path.normalize(fs.path.absolute(topLevelResults['packages'])); PackageMap.globalPackagesPath = fs.path.normalize(fs.path.absolute(topLevelResults['packages'] as String));
} }
// See if the user specified a specific device. // See if the user specified a specific device.
deviceManager.specifiedDeviceId = topLevelResults['device-id']; deviceManager.specifiedDeviceId = topLevelResults['device-id'] as String;
if (topLevelResults['version']) { if (topLevelResults['version'] as bool) {
flutterUsage.sendCommand('version'); flutterUsage.sendCommand('version');
String status; String status;
if (topLevelResults['machine']) { if (topLevelResults['machine'] as bool) {
status = const JsonEncoder.withIndent(' ').convert(FlutterVersion.instance.toJson()); status = const JsonEncoder.withIndent(' ').convert(FlutterVersion.instance.toJson());
} else { } else {
status = FlutterVersion.instance.toString(); status = FlutterVersion.instance.toString();
@ -410,7 +410,7 @@ class FlutterCommandRunner extends CommandRunner<void> {
return; return;
} }
if (topLevelResults['machine']) { if (topLevelResults['machine'] as bool) {
throwToolExit('The --machine flag is only valid with the --version flag.', exitCode: 2); throwToolExit('The --machine flag is only valid with the --version flag.', exitCode: 2);
} }
await super.runCommand(topLevelResults); await super.runCommand(topLevelResults);
@ -426,7 +426,7 @@ class FlutterCommandRunner extends CommandRunner<void> {
} }
String _findEnginePath(ArgResults globalResults) { String _findEnginePath(ArgResults globalResults) {
String engineSourcePath = globalResults['local-engine-src-path'] ?? platform.environment[kFlutterEngineEnvironmentVariableName]; String engineSourcePath = globalResults['local-engine-src-path'] as String ?? platform.environment[kFlutterEngineEnvironmentVariableName];
if (engineSourcePath == null && globalResults['local-engine'] != null) { if (engineSourcePath == null && globalResults['local-engine'] != null) {
try { try {
@ -478,7 +478,7 @@ class FlutterCommandRunner extends CommandRunner<void> {
EngineBuildPaths _findEngineBuildPath(ArgResults globalResults, String enginePath) { EngineBuildPaths _findEngineBuildPath(ArgResults globalResults, String enginePath) {
String localEngine; String localEngine;
if (globalResults['local-engine'] != null) { if (globalResults['local-engine'] != null) {
localEngine = globalResults['local-engine']; localEngine = globalResults['local-engine'] as String;
} else { } else {
throwToolExit(userMessages.runnerLocalEngineRequired, exitCode: 2); throwToolExit(userMessages.runnerLocalEngineRequired, exitCode: 2);
} }

View File

@ -90,25 +90,25 @@ class Template {
final Match match = _kTemplateLanguageVariant.matchAsPrefix(relativeDestinationPath); final Match match = _kTemplateLanguageVariant.matchAsPrefix(relativeDestinationPath);
if (match != null) { if (match != null) {
final String platform = match.group(1); final String platform = match.group(1);
final String language = context['${platform}Language']; final String language = context['${platform}Language'] as String;
if (language != match.group(2)) { if (language != match.group(2)) {
return null; return null;
} }
relativeDestinationPath = relativeDestinationPath.replaceAll('$platform-$language.tmpl', platform); relativeDestinationPath = relativeDestinationPath.replaceAll('$platform-$language.tmpl', platform);
} }
// Only build a web project if explicitly asked. // Only build a web project if explicitly asked.
final bool web = context['web']; final bool web = context['web'] as bool;
if (relativeDestinationPath.contains('web') && !web) { if (relativeDestinationPath.contains('web') && !web) {
return null; return null;
} }
// Only build a macOS project if explicitly asked. // Only build a macOS project if explicitly asked.
final bool macOS = context['macos']; final bool macOS = context['macos'] as bool;
if (relativeDestinationPath.startsWith('macos.tmpl') && !macOS) { if (relativeDestinationPath.startsWith('macos.tmpl') && !macOS) {
return null; return null;
} }
final String projectName = context['projectName']; final String projectName = context['projectName'] as String;
final String androidIdentifier = context['androidIdentifier']; final String androidIdentifier = context['androidIdentifier'] as String;
final String pluginClass = context['pluginClass']; final String pluginClass = context['pluginClass'] as String;
final String destinationDirPath = destination.absolute.path; final String destinationDirPath = destination.absolute.path;
final String pathSeparator = fs.path.separator; final String pathSeparator = fs.path.separator;
String finalDestinationPath = fs.path String finalDestinationPath = fs.path
@ -130,7 +130,7 @@ class Template {
} }
_templateFilePaths.forEach((String relativeDestinationPath, String absoluteSourcePath) { _templateFilePaths.forEach((String relativeDestinationPath, String absoluteSourcePath) {
final bool withRootModule = context['withRootModule'] ?? false; final bool withRootModule = context['withRootModule'] as bool ?? false;
if (!withRootModule && absoluteSourcePath.contains('flutter_root')) { if (!withRootModule && absoluteSourcePath.contains('flutter_root')) {
return; return;
} }

View File

@ -12,6 +12,7 @@ import '../base/logger.dart';
import '../base/os.dart'; import '../base/os.dart';
import '../base/platform.dart'; import '../base/platform.dart';
import '../base/process.dart'; import '../base/process.dart';
import '../base/utils.dart';
import '../dart/package_map.dart'; import '../dart/package_map.dart';
import '../globals.dart'; import '../globals.dart';
import '../vmservice.dart'; import '../vmservice.dart';
@ -22,7 +23,7 @@ import 'watcher.dart';
class CoverageCollector extends TestWatcher { class CoverageCollector extends TestWatcher {
CoverageCollector({this.libraryPredicate}); CoverageCollector({this.libraryPredicate});
Map<String, dynamic> _globalHitmap; Map<String, Map<int, int>> _globalHitmap;
bool Function(String) libraryPredicate; bool Function(String) libraryPredicate;
@override @override
@ -31,7 +32,7 @@ class CoverageCollector extends TestWatcher {
await collectCoverage(event.process, event.observatoryUri); await collectCoverage(event.process, event.observatoryUri);
} }
void _addHitmap(Map<String, dynamic> hitmap) { void _addHitmap(Map<String, Map<int, int>> hitmap) {
if (_globalHitmap == null) { if (_globalHitmap == null) {
_globalHitmap = hitmap; _globalHitmap = hitmap;
} else { } else {
@ -55,7 +56,7 @@ class CoverageCollector extends TestWatcher {
assert(data != null); assert(data != null);
print('($observatoryUri): collected coverage data; merging...'); print('($observatoryUri): collected coverage data; merging...');
_addHitmap(coverage.createHitmap(data['coverage'])); _addHitmap(coverage.createHitmap(data['coverage'] as List<dynamic>));
print('($observatoryUri): done merging coverage data into global coverage map.'); print('($observatoryUri): done merging coverage data into global coverage map.');
} }
@ -87,7 +88,7 @@ class CoverageCollector extends TestWatcher {
assert(data != null); assert(data != null);
printTrace('pid $pid ($observatoryUri): collected coverage data; merging...'); printTrace('pid $pid ($observatoryUri): collected coverage data; merging...');
_addHitmap(coverage.createHitmap(data['coverage'])); _addHitmap(coverage.createHitmap(data['coverage'] as List<dynamic>));
printTrace('pid $pid ($observatoryUri): done merging coverage data into global coverage map.'); printTrace('pid $pid ($observatoryUri): done merging coverage data into global coverage map.');
} }
@ -205,10 +206,10 @@ Future<Map<String, dynamic>> _getAllCoverage(VMService service, bool Function(St
continue; continue;
} }
for (Map<String, dynamic> script in scriptList['scripts']) { for (Map<String, dynamic> script in scriptList['scripts']) {
if (!libraryPredicate(script['uri'])) { if (!libraryPredicate(script['uri'] as String)) {
continue; continue;
} }
final String scriptId = script['id']; final String scriptId = script['id'] as String;
futures.add( futures.add(
isolateRef.invokeRpcRaw('getSourceReport', params: <String, dynamic>{ isolateRef.invokeRpcRaw('getSourceReport', params: <String, dynamic>{
'forceCompile': true, 'forceCompile': true,
@ -246,19 +247,19 @@ void _buildCoverageMap(
for (String scriptId in scripts.keys) { for (String scriptId in scripts.keys) {
final Map<String, dynamic> sourceReport = sourceReports[scriptId]; final Map<String, dynamic> sourceReport = sourceReports[scriptId];
for (Map<String, dynamic> range in sourceReport['ranges']) { for (Map<String, dynamic> range in sourceReport['ranges']) {
final Map<String, dynamic> coverage = range['coverage']; final Map<String, dynamic> coverage = castStringKeyedMap(range['coverage']);
// Coverage reports may sometimes be null for a Script. // Coverage reports may sometimes be null for a Script.
if (coverage == null) { if (coverage == null) {
continue; continue;
} }
final Map<String, dynamic> scriptRef = sourceReport['scripts'][range['scriptIndex']]; final Map<String, dynamic> scriptRef = castStringKeyedMap(sourceReport['scripts'][range['scriptIndex']]);
final String uri = scriptRef['uri']; final String uri = scriptRef['uri'] as String;
hitMaps[uri] ??= <int, int>{}; hitMaps[uri] ??= <int, int>{};
final Map<int, int> hitMap = hitMaps[uri]; final Map<int, int> hitMap = hitMaps[uri];
final List<dynamic> hits = coverage['hits']; final List<int> hits = (coverage['hits'] as List<dynamic>).cast<int>();
final List<dynamic> misses = coverage['misses']; final List<int> misses = (coverage['misses'] as List<dynamic>).cast<int>();
final List<dynamic> tokenPositions = scripts[scriptRef['id']]['tokenPosTable']; final List<dynamic> tokenPositions = scripts[scriptRef['id']]['tokenPosTable'] as List<dynamic>;
// The token positions can be null if the script has no coverable lines. // The token positions can be null if the script has no coverable lines.
if (tokenPositions == null) { if (tokenPositions == null) {
continue; continue;
@ -291,7 +292,7 @@ List<int> _lineAndColumn(int position, List<dynamic> tokenPositions) {
int max = tokenPositions.length; int max = tokenPositions.length;
while (min < max) { while (min < max) {
final int mid = min + ((max - min) >> 1); final int mid = min + ((max - min) >> 1);
final List<dynamic> row = tokenPositions[mid]; final List<int> row = (tokenPositions[mid] as List<dynamic>).cast<int>();
if (row[1] > position) { if (row[1] > position) {
max = mid; max = mid;
} else { } else {

View File

@ -428,7 +428,7 @@ class FlutterPlatform extends PlatformPlugin {
webSocket.complete(WebSocketTransformer.upgrade(request)); webSocket.complete(WebSocketTransformer.upgrade(request));
} }
}, },
onError: (dynamic error, dynamic stack) { onError: (dynamic error, StackTrace stack) {
// If you reach here, it's unlikely we're going to be able to really handle this well. // If you reach here, it's unlikely we're going to be able to really handle this well.
printTrace('test $ourTestCount: test harness socket server experienced an unexpected error: $error'); printTrace('test $ourTestCount: test harness socket server experienced an unexpected error: $error');
if (!controllerSinkClosed) { if (!controllerSinkClosed) {
@ -595,7 +595,7 @@ class FlutterPlatform extends PlatformPlugin {
testSocket.add(json.encode(event)); testSocket.add(json.encode(event));
}, },
onDone: harnessDone.complete, onDone: harnessDone.complete,
onError: (dynamic error, dynamic stack) { onError: (dynamic error, StackTrace stack) {
// If you reach here, it's unlikely we're going to be able to really handle this well. // If you reach here, it's unlikely we're going to be able to really handle this well.
printError('test harness controller stream experienced an unexpected error\ntest: $testPath\nerror: $error'); printError('test harness controller stream experienced an unexpected error\ntest: $testPath\nerror: $error');
if (!controllerSinkClosed) { if (!controllerSinkClosed) {
@ -611,12 +611,11 @@ class FlutterPlatform extends PlatformPlugin {
final Completer<void> testDone = Completer<void>(); final Completer<void> testDone = Completer<void>();
final StreamSubscription<dynamic> testToHarness = testSocket.listen( final StreamSubscription<dynamic> testToHarness = testSocket.listen(
(dynamic encodedEvent) { (dynamic encodedEvent) {
assert(encodedEvent assert(encodedEvent is String); // we shouldn't ever get binary messages
is String); // we shouldn't ever get binary messages controller.sink.add(json.decode(encodedEvent as String));
controller.sink.add(json.decode(encodedEvent));
}, },
onDone: testDone.complete, onDone: testDone.complete,
onError: (dynamic error, dynamic stack) { onError: (dynamic error, StackTrace stack) {
// If you reach here, it's unlikely we're going to be able to really handle this well. // If you reach here, it's unlikely we're going to be able to really handle this well.
printError('test socket stream experienced an unexpected error\ntest: $testPath\nerror: $error'); printError('test socket stream experienced an unexpected error\ntest: $testPath\nerror: $error');
if (!controllerSinkClosed) { if (!controllerSinkClosed) {
@ -970,10 +969,11 @@ class _FlutterPlatformStreamSinkWrapper<S> implements StreamSink<S> {
(List<dynamic> futureResults) { (List<dynamic> futureResults) {
assert(futureResults.length == 2); assert(futureResults.length == 2);
assert(futureResults.first == null); assert(futureResults.first == null);
if (futureResults.last is _AsyncError) { final dynamic lastResult = futureResults.last;
_done.completeError(futureResults.last.error, futureResults.last.stack); if (lastResult is _AsyncError) {
_done.completeError(lastResult.error, lastResult.stack);
} else { } else {
assert(futureResults.last == null); assert(lastResult == null);
_done.complete(); _done.complete();
} }
}, },

View File

@ -96,11 +96,11 @@ Future<void> downloadStartupTrace(VMService observatory, { bool awaitFirstFrame
int extractInstantEventTimestamp(String eventName) { int extractInstantEventTimestamp(String eventName) {
final List<Map<String, dynamic>> events = final List<Map<String, dynamic>> events =
List<Map<String, dynamic>>.from(timeline['traceEvents']); List<Map<String, dynamic>>.from(timeline['traceEvents'] as List<Map<String, dynamic>>);
final Map<String, dynamic> event = events.firstWhere( final Map<String, dynamic> event = events.firstWhere(
(Map<String, dynamic> event) => event['name'] == eventName, orElse: () => null, (Map<String, dynamic> event) => event['name'] == eventName, orElse: () => null,
); );
return event == null ? null : event['ts']; return event == null ? null : (event['ts'] as int);
} }
String message = 'No useful metrics were gathered.'; String message = 'No useful metrics were gathered.';

View File

@ -434,7 +434,7 @@ class VersionCheckStamp {
// Attempt to parse stamp JSON. // Attempt to parse stamp JSON.
try { try {
final dynamic jsonObject = json.decode(versionCheckStamp); final dynamic jsonObject = json.decode(versionCheckStamp);
if (jsonObject is Map) { if (jsonObject is Map<String, dynamic>) {
return fromJson(jsonObject); return fromJson(jsonObject);
} else { } else {
printTrace('Warning: expected version stamp to be a Map but found: $jsonObject'); printTrace('Warning: expected version stamp to be a Map but found: $jsonObject');
@ -452,7 +452,7 @@ class VersionCheckStamp {
static VersionCheckStamp fromJson(Map<String, dynamic> jsonObject) { static VersionCheckStamp fromJson(Map<String, dynamic> jsonObject) {
DateTime readDateTime(String property) { DateTime readDateTime(String property) {
return jsonObject.containsKey(property) return jsonObject.containsKey(property)
? DateTime.parse(jsonObject[property]) ? DateTime.parse(jsonObject[property] as String)
: null; : null;
} }
@ -536,7 +536,7 @@ String _runSync(List<String> command, { bool lenient = true }) {
final ProcessResult results = processManager.runSync(command, workingDirectory: Cache.flutterRoot); final ProcessResult results = processManager.runSync(command, workingDirectory: Cache.flutterRoot);
if (results.exitCode == 0) { if (results.exitCode == 0) {
return results.stdout.trim(); return (results.stdout as String).trim();
} }
if (!lenient) { if (!lenient) {
@ -564,7 +564,7 @@ Future<String> _run(List<String> command) async {
final ProcessResult results = await processManager.run(command, workingDirectory: Cache.flutterRoot); final ProcessResult results = await processManager.run(command, workingDirectory: Cache.flutterRoot);
if (results.exitCode == 0) { if (results.exitCode == 0) {
return results.stdout.trim(); return (results.stdout as String).trim();
} }
throw VersionCheckError( throw VersionCheckError(

Some files were not shown because too many files have changed in this diff Show More