Fix late variable non-assignment when WASM is enabled (#167954)

Closes https://github.com/flutter/flutter/issues/167887.

Appears to be a regression as of
https://github.com/flutter/flutter/issues/165006. Might be worth CPing?
This commit is contained in:
Matan Lurey 2025-04-28 17:34:26 -07:00 committed by GitHub
parent f94a82d2e4
commit f7d7633f54
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 123 additions and 31 deletions

View File

@ -435,7 +435,8 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
final String targetPlatform = getNameForTargetPlatform(TargetPlatform.web_javascript);
final String sdkName = await device!.device!.sdkNameAndVersion;
late UpdateFSReport report;
// Will be null if there is no report.
final UpdateFSReport? report;
if (debuggingOptions.buildInfo.isDebug && !debuggingOptions.webUseWasm) {
await runSourceGenerators();
// Don't reset the resident compiler for web, since the extra recompile is
@ -469,6 +470,7 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
return OperationResult(1, 'Failed to recompile application.');
}
} else {
report = null;
try {
final WebBuilder webBuilder = WebBuilder(
logger: _logger,
@ -490,8 +492,9 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
}
}
late Duration reloadDuration;
late Duration reassembleDuration;
// Both will be null when not assigned.
Duration? reloadDuration;
Duration? reassembleDuration;
try {
if (!deviceIsDebuggable) {
_logger.printStatus('Recompile complete. Page requires refresh.');
@ -578,12 +581,12 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
fullRestart: true,
reason: reason,
overallTimeInMs: elapsed.inMilliseconds,
syncedBytes: report.syncedBytes,
invalidatedSourcesCount: report.invalidatedSourcesCount,
transferTimeInMs: report.transferDuration.inMilliseconds,
compileTimeInMs: report.compileDuration.inMilliseconds,
findInvalidatedTimeInMs: report.findInvalidatedDuration.inMilliseconds,
scannedSourcesCount: report.scannedSourcesCount,
syncedBytes: report?.syncedBytes,
invalidatedSourcesCount: report?.invalidatedSourcesCount,
transferTimeInMs: report?.transferDuration.inMilliseconds,
compileTimeInMs: report?.compileDuration.inMilliseconds,
findInvalidatedTimeInMs: report?.findInvalidatedDuration.inMilliseconds,
scannedSourcesCount: report?.scannedSourcesCount,
).send();
_analytics.send(
Event.hotRunnerInfo(
@ -594,12 +597,12 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
fullRestart: true,
reason: reason,
overallTimeInMs: elapsed.inMilliseconds,
syncedBytes: report.syncedBytes,
invalidatedSourcesCount: report.invalidatedSourcesCount,
transferTimeInMs: report.transferDuration.inMilliseconds,
compileTimeInMs: report.compileDuration.inMilliseconds,
findInvalidatedTimeInMs: report.findInvalidatedDuration.inMilliseconds,
scannedSourcesCount: report.scannedSourcesCount,
syncedBytes: report?.syncedBytes,
invalidatedSourcesCount: report?.invalidatedSourcesCount,
transferTimeInMs: report?.transferDuration.inMilliseconds,
compileTimeInMs: report?.compileDuration.inMilliseconds,
findInvalidatedTimeInMs: report?.findInvalidatedDuration.inMilliseconds,
scannedSourcesCount: report?.scannedSourcesCount,
),
);
} else {
@ -618,14 +621,14 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
fullRestart: false,
reason: reason,
overallTimeInMs: elapsed.inMilliseconds,
syncedBytes: report.syncedBytes,
invalidatedSourcesCount: report.invalidatedSourcesCount,
transferTimeInMs: report.transferDuration.inMilliseconds,
compileTimeInMs: report.compileDuration.inMilliseconds,
findInvalidatedTimeInMs: report.findInvalidatedDuration.inMilliseconds,
scannedSourcesCount: report.scannedSourcesCount,
reassembleTimeInMs: reassembleDuration.inMilliseconds,
reloadVMTimeInMs: reloadDuration.inMilliseconds,
syncedBytes: report?.syncedBytes,
invalidatedSourcesCount: report?.invalidatedSourcesCount,
transferTimeInMs: report?.transferDuration.inMilliseconds,
compileTimeInMs: report?.compileDuration.inMilliseconds,
findInvalidatedTimeInMs: report?.findInvalidatedDuration.inMilliseconds,
scannedSourcesCount: report?.scannedSourcesCount,
reassembleTimeInMs: reassembleDuration?.inMilliseconds,
reloadVMTimeInMs: reloadDuration?.inMilliseconds,
).send();
_analytics.send(
Event.hotRunnerInfo(
@ -636,14 +639,14 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
fullRestart: false,
reason: reason,
overallTimeInMs: elapsed.inMilliseconds,
syncedBytes: report.syncedBytes,
invalidatedSourcesCount: report.invalidatedSourcesCount,
transferTimeInMs: report.transferDuration.inMilliseconds,
compileTimeInMs: report.compileDuration.inMilliseconds,
findInvalidatedTimeInMs: report.findInvalidatedDuration.inMilliseconds,
scannedSourcesCount: report.scannedSourcesCount,
reassembleTimeInMs: reassembleDuration.inMilliseconds,
reloadVMTimeInMs: reloadDuration.inMilliseconds,
syncedBytes: report?.syncedBytes,
invalidatedSourcesCount: report?.invalidatedSourcesCount,
transferTimeInMs: report?.transferDuration.inMilliseconds,
compileTimeInMs: report?.compileDuration.inMilliseconds,
findInvalidatedTimeInMs: report?.findInvalidatedDuration.inMilliseconds,
scannedSourcesCount: report?.scannedSourcesCount,
reassembleTimeInMs: reassembleDuration?.inMilliseconds,
reloadVMTimeInMs: reloadDuration?.inMilliseconds,
),
);
}

View File

@ -17,6 +17,7 @@ import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/terminal.dart';
import 'package:flutter_tools/src/base/time.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/build_system/build_system.dart';
import 'package:flutter_tools/src/build_system/tools/shader_compiler.dart';
import 'package:flutter_tools/src/compile.dart';
import 'package:flutter_tools/src/dart/pub.dart';
@ -46,6 +47,7 @@ import '../src/fake_pub_deps.dart';
import '../src/fake_vm_services.dart';
import '../src/fakes.dart' as test_fakes;
import '../src/package_config.dart';
import '../src/test_build_system.dart';
const List<VmServiceExpectation> kAttachLogExpectations = <VmServiceExpectation>[
FakeVmServiceRequest(method: 'streamListen', args: <String, Object>{'streamId': 'Stdout'}),
@ -914,6 +916,88 @@ name: my_app
},
);
// Regression test for https://github.com/flutter/flutter/issues/167887.
testUsingContext(
'WASM builds report analysis without crashing',
() async {
final BufferLogger logger = BufferLogger.test();
final ResidentRunner residentWebRunner = setUpResidentRunner(
flutterDevice,
logger: logger,
systemClock: SystemClock.fixed(DateTime(2001)),
debuggingOptions: DebuggingOptions.enabled(
const BuildInfo(
BuildMode.debug,
null,
trackWidgetCreation: true,
treeShakeIcons: false,
packageConfigPath: '.dart_tool/package_config.json',
// Hot reload only supported with these flags for now.
extraFrontEndOptions: kDdcLibraryBundleFlags,
),
webUseWasm: true,
),
);
fakeVmServiceHost = FakeVmServiceHost(
requests: <VmServiceExpectation>[
...kAttachExpectations,
const FakeVmServiceRequest(
method: kReloadSourcesServiceName,
args: <String, Object>{'isolateId': ''},
jsonResponse: <String, Object>{'type': 'ReloadReport', 'success': true},
),
const FakeVmServiceRequest(
method: 'ext.flutter.reassemble',
jsonResponse: <String, Object>{'type': 'ReloadReport', 'success': true},
),
const FakeVmServiceRequest(
method: 'streamListen',
args: <String, Object>{'streamId': 'Isolate'},
),
],
);
setupMocks();
final TestChromiumLauncher chromiumLauncher = TestChromiumLauncher();
final FakeProcess process = FakeProcess();
final Chromium chrome = Chromium(
1,
chromeConnection,
chromiumLauncher: chromiumLauncher,
process: process,
logger: logger,
);
chromiumLauncher.setInstance(chrome);
flutterDevice.device = GoogleChromeDevice(
fileSystem: fileSystem,
chromiumLauncher: chromiumLauncher,
logger: BufferLogger.test(),
platform: FakePlatform(),
processManager: FakeProcessManager.any(),
);
webDevFS.report = UpdateFSReport(success: true);
final Completer<DebugConnectionInfo> connectionInfoCompleter =
Completer<DebugConnectionInfo>();
unawaited(residentWebRunner.run(connectionInfoCompleter: connectionInfoCompleter));
final DebugConnectionInfo debugConnectionInfo = await connectionInfoCompleter.future;
expect(debugConnectionInfo, isNotNull);
final OperationResult result = await residentWebRunner.restart();
expect(logger.statusText, contains('Reloaded application in'));
expect(result.code, 0);
},
overrides: <Type, Generator>{
Analytics: () => fakeAnalytics,
BuildSystem: () => TestBuildSystem.all(BuildResult(success: true)),
FileSystem: () => fileSystem,
ProcessManager: () => processManager,
FeatureFlags: enableExplicitPackageDependencies,
Pub: FakePubWithPrimedDeps.new,
},
);
// Hot restart is available with and without the DDC library bundle format.
// Test one extra config where `fullRestart` is false without the DDC library
// bundle format - we should do a hot restart in this case because hot reload
@ -1995,6 +2079,11 @@ class FakeChromeTab extends Fake implements ChromeTab {
class FakeWipConnection extends Fake implements WipConnection {
@override
final WipDebugger debugger = FakeWipDebugger();
@override
Future<WipResponse> sendCommand(String method, [Map<String, dynamic>? params]) async {
return WipResponse(<String, dynamic>{'id': 0, 'result': <String, dynamic>{}});
}
}
/// A test implementation of the [ChromiumLauncher] that launches a fixed instance.