[flutter_tools] support sound null-safety mode for the web (#60570)
In web debug mode, infer sound null safety by default. When sound null safety is enabled, provide a separate dill and precompiled Dart SDK. Release builds do not need this setting since we run dart2js from source.
Fixes #59873
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 d998796..765c47e 100644
--- a/packages/flutter_tools/test/general.shard/resident_runner_test.dart
+++ b/packages/flutter_tools/test/general.shard/resident_runner_test.dart
@@ -1540,7 +1540,7 @@
expect(fakeVmServiceHost.hasRemainingExpectations, false);
}));
- testUsingContext('FlutterDevice uses dartdevc configuration when targeting web', () => testbed.run(() async {
+ testUsingContext('FlutterDevice uses dartdevc configuration when targeting web', () async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
final MockDevice mockDevice = MockDevice();
when(mockDevice.targetPlatform).thenAnswer((Invocation invocation) async {
@@ -1549,7 +1549,12 @@
final DefaultResidentCompiler residentCompiler = (await FlutterDevice.create(
mockDevice,
- buildInfo: BuildInfo.debug,
+ buildInfo: const BuildInfo(
+ BuildMode.debug,
+ '',
+ treeShakeIcons: false,
+ nullSafetyMode: NullSafetyMode.unsound,
+ ),
flutterProject: FlutterProject.current(),
target: null,
)).generator as DefaultResidentCompiler;
@@ -1562,12 +1567,46 @@
expect(residentCompiler.targetModel, TargetModel.dartdevc);
expect(residentCompiler.sdkRoot,
globals.artifacts.getArtifactPath(Artifact.flutterWebSdk, mode: BuildMode.debug) + '/');
- expect(
- residentCompiler.platformDill,
- globals.fs.file(globals.artifacts.getArtifactPath(Artifact.webPlatformKernelDill, mode: BuildMode.debug))
- .absolute.uri.toString(),
- );
- }));
+ expect(residentCompiler.platformDill, 'file:///Artifact.webPlatformKernelDill.debug');
+ }, overrides: <Type, Generator>{
+ Artifacts: () => Artifacts.test(),
+ FileSystem: () => MemoryFileSystem.test(),
+ ProcessManager: () => FakeProcessManager.any(),
+ });
+
+ testUsingContext('FlutterDevice uses dartdevc configuration when targeting web with null-safety autodetected', () async {
+ fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
+ final MockDevice mockDevice = MockDevice();
+ when(mockDevice.targetPlatform).thenAnswer((Invocation invocation) async {
+ return TargetPlatform.web_javascript;
+ });
+
+ final DefaultResidentCompiler residentCompiler = (await FlutterDevice.create(
+ mockDevice,
+ buildInfo: const BuildInfo(
+ BuildMode.debug,
+ '',
+ treeShakeIcons: false,
+ extraFrontEndOptions: <String>['--enable-experiment=non-nullable'],
+ ),
+ flutterProject: FlutterProject.current(),
+ 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());
+ expect(residentCompiler.targetModel, TargetModel.dartdevc);
+ expect(residentCompiler.sdkRoot,
+ globals.artifacts.getArtifactPath(Artifact.flutterWebSdk, mode: BuildMode.debug) + '/');
+ expect(residentCompiler.platformDill, 'file:///Artifact.webPlatformSoundKernelDill.debug');
+ }, overrides: <Type, Generator>{
+ Artifacts: () => Artifacts.test(),
+ FileSystem: () => MemoryFileSystem.test(),
+ ProcessManager: () => FakeProcessManager.any(),
+ });
testUsingContext('connect sets up log reader', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);