diff --git a/packages/flutter_tools/gradle/flutter.gradle b/packages/flutter_tools/gradle/flutter.gradle index 3cbd6fa985..98748d67c6 100644 --- a/packages/flutter_tools/gradle/flutter.gradle +++ b/packages/flutter_tools/gradle/flutter.gradle @@ -255,6 +255,11 @@ class FlutterPlugin implements Plugin { if (project.hasProperty('preview-dart-2')) { previewDart2Value = project.property('preview-dart-2') } + + Boolean strongModeValue = false + if (project.hasProperty('strong')) { + strongModeValue = project.property('strong') + } String extraFrontEndOptionsValue = null if (project.hasProperty('extra-front-end-options')) { @@ -290,6 +295,7 @@ class FlutterPlugin implements Plugin { localEngineSrcPath this.localEngineSrcPath targetPath target previewDart2 previewDart2Value + strongMode strongModeValue preferSharedLibrary preferSharedLibraryValue sourceDir project.file(project.flutter.source) intermediateDir project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}") @@ -304,6 +310,7 @@ class FlutterPlugin implements Plugin { localEngineSrcPath this.localEngineSrcPath targetPath target previewDart2 previewDart2Value + strongMode strongModeValue preferSharedLibrary preferSharedLibraryValue sourceDir project.file(project.flutter.source) intermediateDir project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}") @@ -338,6 +345,8 @@ abstract class BaseFlutterTask extends DefaultTask { @Optional @Input Boolean previewDart2 @Optional @Input + Boolean strongMode + @Optional @Input Boolean preferSharedLibrary File sourceDir File intermediateDir @@ -378,6 +387,9 @@ abstract class BaseFlutterTask extends DefaultTask { if (previewDart2) { args "--preview-dart-2" } + if (strongMode) { + args "--strong" + } if (extraFrontEndOptions != null) { args "--extra-front-end-options", "${extraFrontEndOptions}" } @@ -404,6 +416,10 @@ abstract class BaseFlutterTask extends DefaultTask { if (previewDart2) { args "--preview-dart-2" } + if (strongMode) { + args "--strong" + } + args "--output-file", "${intermediateDir}/app.flx" if (buildMode != "debug") { args "--precompiled" diff --git a/packages/flutter_tools/lib/src/android/android_device.dart b/packages/flutter_tools/lib/src/android/android_device.dart index b6e58904fa..a0a19c0040 100644 --- a/packages/flutter_tools/lib/src/android/android_device.dart +++ b/packages/flutter_tools/lib/src/android/android_device.dart @@ -378,6 +378,7 @@ class AndroidDevice extends Device { return new LaunchResult.failed(); final bool traceStartup = platformArgs['trace-startup'] ?? false; + final bool strongMode = platformArgs['strong'] ?? false; final AndroidApk apk = package; printTrace('$this startApp'); @@ -406,6 +407,9 @@ class AndroidDevice extends Device { if (traceStartup) cmd.addAll(['--ez', 'trace-startup', 'true']); + if (strongMode) { + cmd.addAll(['--ez', 'strong', 'true']); + } if (route != null) cmd.addAll(['--es', 'route', route]); if (debuggingOptions.enableSoftwareRendering) diff --git a/packages/flutter_tools/lib/src/android/gradle.dart b/packages/flutter_tools/lib/src/android/gradle.dart index 0a7083edb0..8d8957a443 100644 --- a/packages/flutter_tools/lib/src/android/gradle.dart +++ b/packages/flutter_tools/lib/src/android/gradle.dart @@ -291,6 +291,8 @@ Future _buildGradleProjectV2(String gradle, BuildInfo buildInfo, String ta } if (buildInfo.previewDart2) { command.add('-Ppreview-dart-2=true'); + if (buildInfo.strongMode) + command.add('-Pstrong=true'); if (buildInfo.extraFrontEndOptions != null) command.add('-Pextra-front-end-options=${buildInfo.extraFrontEndOptions}'); if (buildInfo.extraGenSnapshotOptions != null) diff --git a/packages/flutter_tools/lib/src/artifacts.dart b/packages/flutter_tools/lib/src/artifacts.dart index e3d12c3af8..3c4bfa3b38 100644 --- a/packages/flutter_tools/lib/src/artifacts.dart +++ b/packages/flutter_tools/lib/src/artifacts.dart @@ -21,6 +21,7 @@ enum Artifact { vmSnapshotData, isolateSnapshotData, platformKernelDill, + platformKernelStrongDill, platformLibrariesJson, flutterPatchedSdkPath, frontendServerSnapshotForEngineDartSdk, @@ -47,6 +48,8 @@ String _artifactToFileName(Artifact artifact) { return 'isolate_snapshot.bin'; case Artifact.platformKernelDill: return 'platform.dill'; + case Artifact.platformKernelStrongDill: + return 'platform_strong.dill'; case Artifact.platformLibrariesJson: return 'libraries.json'; case Artifact.flutterPatchedSdkPath: @@ -168,6 +171,7 @@ class CachedArtifacts extends Artifacts { final String platformDirName = getNameForTargetPlatform(platform); return fs.path.join(engineArtifactsPath, platformDirName, _artifactToFileName(artifact)); case Artifact.platformKernelDill: + case Artifact.platformKernelStrongDill: return fs.path.join(_getFlutterPatchedSdkPath(), _artifactToFileName(artifact)); case Artifact.platformLibrariesJson: return fs.path.join(_getFlutterPatchedSdkPath(), 'lib', _artifactToFileName(artifact)); @@ -237,6 +241,7 @@ class LocalEngineArtifacts extends Artifacts { case Artifact.vmSnapshotData: return fs.path.join(engineOutPath, 'gen', 'flutter', 'lib', 'snapshot', _artifactToFileName(artifact)); case Artifact.platformKernelDill: + case Artifact.platformKernelStrongDill: return fs.path.join(_getFlutterPatchedSdkPath(), _artifactToFileName(artifact)); case Artifact.platformLibrariesJson: return fs.path.join(_getFlutterPatchedSdkPath(), 'lib', _artifactToFileName(artifact)); diff --git a/packages/flutter_tools/lib/src/build_info.dart b/packages/flutter_tools/lib/src/build_info.dart index 5f3aef2a3e..63bf145a3d 100644 --- a/packages/flutter_tools/lib/src/build_info.dart +++ b/packages/flutter_tools/lib/src/build_info.dart @@ -12,6 +12,7 @@ import 'globals.dart'; class BuildInfo { const BuildInfo(this.mode, this.flavor, {this.previewDart2, + this.strongMode, this.extraFrontEndOptions, this.extraGenSnapshotOptions, this.preferSharedLibrary}); @@ -27,6 +28,9 @@ class BuildInfo { // Whether build should be done using Dart2 Frontend parser. final bool previewDart2; + + // Whether build should use strong mode semantics. + final bool strongMode; /// Extra command-line options for front-end. final String extraFrontEndOptions; diff --git a/packages/flutter_tools/lib/src/commands/build_aot.dart b/packages/flutter_tools/lib/src/commands/build_aot.dart index af455f75b3..f132f0c5aa 100644 --- a/packages/flutter_tools/lib/src/commands/build_aot.dart +++ b/packages/flutter_tools/lib/src/commands/build_aot.dart @@ -40,6 +40,7 @@ class BuildAotCommand extends BuildSubCommand { ..addFlag('interpreter') ..addFlag('quiet', defaultsTo: false) ..addFlag('preview-dart-2', negatable: false, hide: !verboseHelp) + ..addFlag('strong', negatable: false, hide: !verboseHelp) ..addOption(FlutterOptions.kExtraFrontEndOptions, allowMultiple: true, splitCommas: true, @@ -81,6 +82,7 @@ class BuildAotCommand extends BuildSubCommand { outputPath: argResults['output-dir'], interpreter: argResults['interpreter'], previewDart2: argResults['preview-dart-2'], + strongMode: argResults['strong'], extraFrontEndOptions: argResults[FlutterOptions.kExtraFrontEndOptions], extraGenSnapshotOptions: argResults[FlutterOptions.kExtraGenSnapshotOptions], preferSharedLibrary: argResults['prefer-shared-library'], @@ -112,6 +114,7 @@ Future buildAotSnapshot( String outputPath, bool interpreter: false, bool previewDart2: false, + bool strongMode: false, List extraFrontEndOptions, List extraGenSnapshotOptions, bool preferSharedLibrary: false, @@ -125,6 +128,7 @@ Future buildAotSnapshot( outputPath: outputPath, interpreter: interpreter, previewDart2: previewDart2, + strongMode: strongMode, extraFrontEndOptions: extraFrontEndOptions, extraGenSnapshotOptions: extraGenSnapshotOptions, preferSharedLibrary: preferSharedLibrary, @@ -144,6 +148,7 @@ Future _buildAotSnapshot( String outputPath, bool interpreter: false, bool previewDart2: false, + bool strongMode: false, List extraFrontEndOptions, List extraGenSnapshotOptions, bool preferSharedLibrary: false, @@ -335,6 +340,7 @@ Future _buildAotSnapshot( extraFrontEndOptions: extraFrontEndOptions, linkPlatformKernelIn : true, aot : true, + strongMode: strongMode, ); } diff --git a/packages/flutter_tools/lib/src/commands/build_apk.dart b/packages/flutter_tools/lib/src/commands/build_apk.dart index 0c1811dceb..4636e4859e 100644 --- a/packages/flutter_tools/lib/src/commands/build_apk.dart +++ b/packages/flutter_tools/lib/src/commands/build_apk.dart @@ -16,6 +16,7 @@ class BuildApkCommand extends BuildSubCommand { argParser ..addFlag('preview-dart-2', negatable: false, hide: !verboseHelp) + ..addFlag('strong', negatable: false, hide: !verboseHelp) ..addFlag('prefer-shared-library', negatable: false, help: 'Whether to prefer compiling to a *.so file (android only).'); } diff --git a/packages/flutter_tools/lib/src/commands/build_flx.dart b/packages/flutter_tools/lib/src/commands/build_flx.dart index be66079245..73c1a088a2 100644 --- a/packages/flutter_tools/lib/src/commands/build_flx.dart +++ b/packages/flutter_tools/lib/src/commands/build_flx.dart @@ -21,6 +21,7 @@ class BuildFlxCommand extends BuildSubCommand { argParser.addOption('snapshot', defaultsTo: defaultSnapshotPath); argParser.addOption('depfile', defaultsTo: defaultDepfilePath); argParser.addFlag('preview-dart-2', negatable: false, hide: !verboseHelp); + argParser.addFlag('strong', negatable: false, hide: !verboseHelp); argParser.addOption('working-dir', defaultsTo: getAssetBuildDirectory()); argParser.addFlag('report-licensed-packages', help: 'Whether to report the names of all the packages that are included in the application\'s LICENSE file.', defaultsTo: false); usesPubOption(); @@ -50,6 +51,7 @@ class BuildFlxCommand extends BuildSubCommand { privateKeyPath: argResults['private-key'], workingDirPath: argResults['working-dir'], previewDart2: argResults['preview-dart-2'], + strongMode: argResults['strong'], precompiledSnapshot: argResults['precompiled'], reportLicensedPackages: argResults['report-licensed-packages'] ); diff --git a/packages/flutter_tools/lib/src/commands/build_ios.dart b/packages/flutter_tools/lib/src/commands/build_ios.dart index ee0c312339..d1d7580e42 100644 --- a/packages/flutter_tools/lib/src/commands/build_ios.dart +++ b/packages/flutter_tools/lib/src/commands/build_ios.dart @@ -31,6 +31,8 @@ class BuildIOSCommand extends BuildSubCommand { help: 'Codesign the application bundle (only available on device builds).'); argParser.addFlag('preview-dart-2', negatable: false, hide: !verboseHelp); + argParser.addFlag('strong', negatable: false, + hide: !verboseHelp); } @override diff --git a/packages/flutter_tools/lib/src/commands/create.dart b/packages/flutter_tools/lib/src/commands/create.dart index 2247079796..056d0b513b 100644 --- a/packages/flutter_tools/lib/src/commands/create.dart +++ b/packages/flutter_tools/lib/src/commands/create.dart @@ -229,6 +229,7 @@ class CreateCommand extends FlutterCommand { target: flx.defaultMainPath, hasPlugins: generatePlugin, previewDart2: false, + strongMode: false, ); if (argResults['pub']) { diff --git a/packages/flutter_tools/lib/src/commands/run.dart b/packages/flutter_tools/lib/src/commands/run.dart index 52e27bd484..beb0c61560 100644 --- a/packages/flutter_tools/lib/src/commands/run.dart +++ b/packages/flutter_tools/lib/src/commands/run.dart @@ -105,6 +105,10 @@ class RunCommand extends RunCommandBase { argParser.addFlag('preview-dart-2', hide: !verboseHelp, help: 'Preview Dart 2.0 functionality.'); + argParser.addFlag('strong', + hide: !verboseHelp, + help: 'Turn on strong mode semantics.\n' + 'Valid only when --preview-dart-2 is also specified'); argParser.addOption('packages', hide: !verboseHelp, valueHelp: 'path', @@ -290,7 +294,9 @@ class RunCommand extends RunCommandBase { } final List flutterDevices = devices.map((Device device) { - return new FlutterDevice(device, previewDart2: argResults['preview-dart-2']); + return new FlutterDevice(device, + previewDart2: argResults['preview-dart-2'], + strongMode : argResults['strong']); }).toList(); ResidentRunner runner; @@ -302,6 +308,7 @@ class RunCommand extends RunCommandBase { benchmarkMode: argResults['benchmark'], applicationBinary: argResults['use-application-binary'], previewDart2: argResults['preview-dart-2'], + strongMode: argResults['strong'], projectRootPath: argResults['project-root'], packagesFilePath: argResults['packages'], projectAssets: argResults['project-assets'], @@ -316,6 +323,7 @@ class RunCommand extends RunCommandBase { traceStartup: traceStartup, applicationBinary: argResults['use-application-binary'], previewDart2: argResults['preview-dart-2'], + strongMode: argResults['strong'], stayResident: stayResident, ipv6: ipv6, ); diff --git a/packages/flutter_tools/lib/src/compile.dart b/packages/flutter_tools/lib/src/compile.dart index 998ff67e6d..be352170d3 100644 --- a/packages/flutter_tools/lib/src/compile.dart +++ b/packages/flutter_tools/lib/src/compile.dart @@ -61,6 +61,7 @@ Future compile( String mainPath, bool linkPlatformKernelIn : false, bool aot : false, + bool strongMode : false, List extraFrontEndOptions, String incrementalCompilerByteStorePath}) async { final String frontendServer = artifacts.getArtifactPath( @@ -81,6 +82,9 @@ Future compile( if (aot) { command.add('--aot'); } + if (strongMode) { + command.add('--strong'); + } if (incrementalCompilerByteStorePath != null) { command.addAll([ '--incremental', diff --git a/packages/flutter_tools/lib/src/flx.dart b/packages/flutter_tools/lib/src/flx.dart index ff4c501953..d54ac1b535 100644 --- a/packages/flutter_tools/lib/src/flx.dart +++ b/packages/flutter_tools/lib/src/flx.dart @@ -39,6 +39,7 @@ Future build({ String workingDirPath, String packagesPath, bool previewDart2 : false, + bool strongMode : false, bool precompiledSnapshot: false, bool reportLicensedPackages: false }) async { @@ -72,7 +73,8 @@ Future build({ final String kernelBinaryFilename = await compile( sdkRoot: artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath), incrementalCompilerByteStorePath: fs.path.absolute(getIncrementalCompilerByteStoreDirectory()), - mainPath: fs.file(mainPath).absolute.path + mainPath: fs.file(mainPath).absolute.path, + strongMode: strongMode ); kernelContent = new DevFSFileContent(fs.file(kernelBinaryFilename)); } @@ -85,6 +87,7 @@ Future build({ privateKeyPath: privateKeyPath, workingDirPath: workingDirPath, packagesPath: packagesPath, + strongMode: strongMode, reportLicensedPackages: reportLicensedPackages ).then((_) => null); } @@ -98,6 +101,7 @@ Future> assemble({ String privateKeyPath: defaultPrivateKeyPath, String workingDirPath, String packagesPath, + bool strongMode : false, bool includeDefaultFonts: true, bool reportLicensedPackages: false }) async { @@ -128,7 +132,9 @@ Future> assemble({ .toList(); if (kernelContent != null) { - final String platformKernelDill = artifacts.getArtifactPath(Artifact.platformKernelDill); + final String platformKernelDill = strongMode ? + artifacts.getArtifactPath(Artifact.platformKernelStrongDill) : + artifacts.getArtifactPath(Artifact.platformKernelDill); zipBuilder.entries[_kKernelKey] = kernelContent; zipBuilder.entries[_kPlatformKernelKey] = new DevFSFileContent(fs.file(platformKernelDill)); } diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart index 2ca81092fd..14fa5a34cf 100644 --- a/packages/flutter_tools/lib/src/ios/mac.dart +++ b/packages/flutter_tools/lib/src/ios/mac.dart @@ -264,6 +264,7 @@ Future buildXcodeProject({ target: target, hasPlugins: hasFlutterPlugins, previewDart2: buildInfo.previewDart2, + strongMode: buildInfo.strongMode, ); if (hasFlutterPlugins) { diff --git a/packages/flutter_tools/lib/src/ios/xcodeproj.dart b/packages/flutter_tools/lib/src/ios/xcodeproj.dart index 7dbeca7edd..c70c997359 100644 --- a/packages/flutter_tools/lib/src/ios/xcodeproj.dart +++ b/packages/flutter_tools/lib/src/ios/xcodeproj.dart @@ -25,6 +25,7 @@ void updateXcodeGeneratedProperties({ @required String target, @required bool hasPlugins, @required bool previewDart2, + @required bool strongMode, }) { final StringBuffer localsBuffer = new StringBuffer(); @@ -57,6 +58,9 @@ void updateXcodeGeneratedProperties({ if (previewDart2) { localsBuffer.writeln('PREVIEW_DART_2=true'); } + if (strongMode) { + localsBuffer.writeln('STRONG=true'); + } // Add dependency to CocoaPods' generated project only if plugins are used. if (hasPlugins) diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart index c284dcedd8..22a62fd3a9 100644 --- a/packages/flutter_tools/lib/src/resident_runner.dart +++ b/packages/flutter_tools/lib/src/resident_runner.dart @@ -38,7 +38,8 @@ class FlutterDevice { StreamSubscription _loggingSubscription; - FlutterDevice(this.device, { bool previewDart2 : false }) { + FlutterDevice(this.device, + { bool previewDart2 : false, bool strongMode : false }) { if (previewDart2) generator = new ResidentCompiler( artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath)); @@ -259,6 +260,8 @@ class FlutterDevice { } final Map platformArgs = {}; + if (hotRunner.strongMode != null) + platformArgs['strong'] = hotRunner.strongMode; startEchoingDeviceLog(); @@ -320,6 +323,8 @@ class FlutterDevice { final Map platformArgs = {}; if (coldRunner.traceStartup != null) platformArgs['trace-startup'] = coldRunner.traceStartup; + if (coldRunner.strongMode != null) + platformArgs['strong'] = coldRunner.strongMode; startEchoingDeviceLog(); diff --git a/packages/flutter_tools/lib/src/run_cold.dart b/packages/flutter_tools/lib/src/run_cold.dart index 7a004f24f3..9d41ce8022 100644 --- a/packages/flutter_tools/lib/src/run_cold.dart +++ b/packages/flutter_tools/lib/src/run_cold.dart @@ -21,6 +21,7 @@ class ColdRunner extends ResidentRunner { this.traceStartup: false, this.applicationBinary, this.previewDart2 : false, + this.strongMode : false, bool stayResident: true, bool ipv6: false, }) : super(devices, @@ -33,6 +34,7 @@ class ColdRunner extends ResidentRunner { final bool traceStartup; final String applicationBinary; final bool previewDart2; + final bool strongMode; @override Future run({ diff --git a/packages/flutter_tools/lib/src/run_hot.dart b/packages/flutter_tools/lib/src/run_hot.dart index b7a6f3852f..4a20f91543 100644 --- a/packages/flutter_tools/lib/src/run_hot.dart +++ b/packages/flutter_tools/lib/src/run_hot.dart @@ -40,6 +40,7 @@ class HotRunner extends ResidentRunner { this.benchmarkMode: false, this.applicationBinary, this.previewDart2: false, + this.strongMode: false, this.hostIsIde: false, String projectRootPath, String packagesFilePath, @@ -65,6 +66,7 @@ class HotRunner extends ResidentRunner { // The initial launch is from a snapshot. bool _runningFromSnapshot = true; bool previewDart2 = false; + bool strongMode = false; void _addBenchmarkData(String name, int value) { benchmarkData[name] ??= []; diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart index 5d673b61c4..33d3e54cff 100644 --- a/packages/flutter_tools/lib/src/runner/flutter_command.dart +++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart @@ -149,13 +149,23 @@ abstract class FlutterCommand extends Command { } BuildInfo getBuildInfo() { + final bool previewDart2 = argParser.options.containsKey('preview-dart-2') + ? argResults['preview-dart-2'] + : false; + final bool strongMode = argParser.options.containsKey('strong') + ? argResults['strong'] + : false; + if (strongMode == true && previewDart2 == false) { + throw new UsageException( + '--strong is valid only when --preview-dart-2 is specified.', null); + } + return new BuildInfo(getBuildMode(), argParser.options.containsKey('flavor') ? argResults['flavor'] : null, - previewDart2: argParser.options.containsKey('preview-dart-2') - ? argResults['preview-dart-2'] - : false, + previewDart2: previewDart2, + strongMode: strongMode, extraFrontEndOptions: argParser.options.containsKey(FlutterOptions.kExtraFrontEndOptions) ? argResults[FlutterOptions.kExtraFrontEndOptions] : null, @@ -374,6 +384,16 @@ abstract class FlutterCommand extends Command { if (!fs.isFileSync(targetPath)) throw new ToolExit('Target file "$targetPath" not found.'); } + + final bool previewDart2 = argParser.options.containsKey('preview-dart-2') + ? argResults['preview-dart-2'] + : false; + final bool strongMode = argParser.options.containsKey('strong') + ? argResults['strong'] + : false; + if (strongMode == true && previewDart2 == false) { + throw new ToolExit('--strong is valid only with --preview-dart-2 option.'); + } } ApplicationPackageStore applicationPackages;