diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart index 9c86abbcd8..a424873a9b 100644 --- a/packages/flutter_tools/lib/src/resident_runner.dart +++ b/packages/flutter_tools/lib/src/resident_runner.dart @@ -23,6 +23,7 @@ import 'base/utils.dart'; import 'build_info.dart'; import 'build_system/build_system.dart'; import 'build_system/targets/localizations.dart'; +import 'bundle.dart'; import 'cache.dart'; import 'codegen.dart'; import 'compile.dart'; @@ -83,6 +84,12 @@ class FlutterDevice { if (device.platformType == PlatformType.fuchsia) { targetModel = TargetModel.flutterRunner; } + // For both web and non-web platforms we initialize dill to/from + // a shared location for faster bootstrapping. If the compiler fails + // due to a kernel target or version mismatch, no error is reported + // and the compiler starts up as normal. Unexpected errors will print + // a warning message and dump some debug information which can be + // used to file a bug, but the compiler will still start up correctly. if (targetPlatform == TargetPlatform.web_javascript) { generator = ResidentCompiler( globals.artifacts.getArtifactPath(Artifact.flutterWebSdk, mode: buildInfo.mode), @@ -95,6 +102,9 @@ class FlutterDevice { compilerMessageConsumer: (String message, {bool emphasis, TerminalColor color, }) => globals.printTrace(message), + initializeFromDill: getDefaultCachedKernelPath( + trackWidgetCreation: buildInfo.trackWidgetCreation, + ), targetModel: TargetModel.dartdevc, experimentalFlags: experimentalFlags, platformDill: globals.fs.file(globals.artifacts @@ -119,6 +129,9 @@ class FlutterDevice { targetModel: targetModel, experimentalFlags: experimentalFlags, dartDefines: buildInfo.dartDefines, + initializeFromDill: getDefaultCachedKernelPath( + trackWidgetCreation: buildInfo.trackWidgetCreation, + ), packagesPath: globalPackagesPath, ); } @@ -691,7 +704,6 @@ abstract class ResidentRunner { final bool ipv6; final String _dillOutputPath; /// The parent location of the incremental artifacts. - @visibleForTesting final Directory artifactDirectory; final String packagesFilePath; final String projectRootPath; @@ -1196,6 +1208,12 @@ abstract class ResidentRunner { Future preExit() async { // If _dillOutputPath is null, we created a temporary directory for the dill. if (_dillOutputPath == null && artifactDirectory.existsSync()) { + final File outputDill = globals.fs.file(dillOutputPath); + if (outputDill.existsSync()) { + outputDill.copySync(getDefaultCachedKernelPath( + trackWidgetCreation: trackWidgetCreation, + )); + } artifactDirectory.deleteSync(recursive: true); } } diff --git a/packages/flutter_tools/test/general.shard/resident_runner_test.dart b/packages/flutter_tools/test/general.shard/resident_runner_test.dart index 30c9e1e258..319df1a121 100644 --- a/packages/flutter_tools/test/general.shard/resident_runner_test.dart +++ b/packages/flutter_tools/test/general.shard/resident_runner_test.dart @@ -4,10 +4,10 @@ import 'dart:async'; -import 'package:file_testing/file_testing.dart'; import 'package:flutter_tools/src/cache.dart'; import 'package:vm_service/vm_service.dart' as vm_service; import 'package:file/memory.dart'; +import 'package:file_testing/file_testing.dart'; import 'package:flutter_tools/src/artifacts.dart'; import 'package:flutter_tools/src/base/command_help.dart'; import 'package:flutter_tools/src/base/common.dart'; @@ -521,6 +521,24 @@ void main() { expect(otherRunner.artifactDirectory.path, contains('foobar')); })); + test('ResidentRunner copies output dill to cache location during preExit', () => testbed.run(() async { + fakeVmServiceHost = FakeVmServiceHost(requests: []); + residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('hello'); + await residentRunner.preExit(); + final File cacheDill = globals.fs.file(globals.fs.path.join(getBuildDirectory(), 'cache.dill')); + + expect(cacheDill, exists); + expect(cacheDill.readAsStringSync(), 'hello'); + })); + + test('ResidentRunner handles output dill missing during preExit', () => testbed.run(() async { + fakeVmServiceHost = FakeVmServiceHost(requests: []); + await residentRunner.preExit(); + final File cacheDill = globals.fs.file(globals.fs.path.join(getBuildDirectory(), 'cache.dill')); + + expect(cacheDill, isNot(exists)); + })); + test('ResidentRunner can run source generation', () => testbed.run(() async { final FakeProcessManager processManager = globals.processManager as FakeProcessManager; final Directory dependencies = globals.fs.directory( @@ -1140,6 +1158,8 @@ void main() { target: null, )).generator as DefaultResidentCompiler; + expect(residentCompiler.initializeFromDill, + globals.fs.path.join(getBuildDirectory(), 'cache.dill')); expect(residentCompiler.librariesSpec, globals.fs.file(globals.artifacts.getArtifactPath(Artifact.flutterWebLibrariesJson)) .uri.toString());