Unverified Commit 6e950672 authored by Christopher Fujino's avatar Christopher Fujino Committed by GitHub

[flutter_tools] Fix _CastError in HotRunner._resetDirtyAssets (#108771)

parent 965912d8
...@@ -12,6 +12,7 @@ import 'context.dart'; ...@@ -12,6 +12,7 @@ import 'context.dart';
import 'io.dart' as io; import 'io.dart' as io;
import 'logger.dart'; import 'logger.dart';
// TODO(fujino): This should be direct injected, rather than mutable global state.
@visibleForTesting @visibleForTesting
Future<dds.DartDevelopmentService> Function( Future<dds.DartDevelopmentService> Function(
Uri remoteVmServiceUri, { Uri remoteVmServiceUri, {
......
...@@ -81,14 +81,14 @@ const String kExitMessage = 'Failed to establish connection with the application ...@@ -81,14 +81,14 @@ const String kExitMessage = 'Failed to establish connection with the application
class ResidentWebRunner extends ResidentRunner { class ResidentWebRunner extends ResidentRunner {
ResidentWebRunner( ResidentWebRunner(
FlutterDevice? device, { FlutterDevice device, {
String? target, String? target,
bool stayResident = true, bool stayResident = true,
bool machine = false, bool machine = false,
required this.flutterProject, required this.flutterProject,
required bool? ipv6, required bool? ipv6,
required DebuggingOptions debuggingOptions, required DebuggingOptions debuggingOptions,
required FileSystem? fileSystem, required FileSystem fileSystem,
required Logger? logger, required Logger? logger,
required SystemClock systemClock, required SystemClock systemClock,
required Usage usage, required Usage usage,
...@@ -100,8 +100,8 @@ class ResidentWebRunner extends ResidentRunner { ...@@ -100,8 +100,8 @@ class ResidentWebRunner extends ResidentRunner {
_usage = usage, _usage = usage,
_urlTunneller = urlTunneller, _urlTunneller = urlTunneller,
super( super(
<FlutterDevice?>[device], <FlutterDevice>[device],
target: target ?? fileSystem!.path.join('lib', 'main.dart'), target: target ?? fileSystem.path.join('lib', 'main.dart'),
debuggingOptions: debuggingOptions, debuggingOptions: debuggingOptions,
ipv6: ipv6, ipv6: ipv6,
stayResident: stayResident, stayResident: stayResident,
...@@ -109,7 +109,7 @@ class ResidentWebRunner extends ResidentRunner { ...@@ -109,7 +109,7 @@ class ResidentWebRunner extends ResidentRunner {
devtoolsHandler: devtoolsHandler, devtoolsHandler: devtoolsHandler,
); );
final FileSystem? _fileSystem; final FileSystem _fileSystem;
final Logger? _logger; final Logger? _logger;
final SystemClock _systemClock; final SystemClock _systemClock;
final Usage _usage; final Usage _usage;
...@@ -119,7 +119,7 @@ class ResidentWebRunner extends ResidentRunner { ...@@ -119,7 +119,7 @@ class ResidentWebRunner extends ResidentRunner {
Logger? get logger => _logger; Logger? get logger => _logger;
@override @override
FileSystem? get fileSystem => _fileSystem; FileSystem get fileSystem => _fileSystem;
FlutterDevice? get device => flutterDevices.first; FlutterDevice? get device => flutterDevices.first;
final FlutterProject flutterProject; final FlutterProject flutterProject;
...@@ -245,7 +245,7 @@ class ResidentWebRunner extends ResidentRunner { ...@@ -245,7 +245,7 @@ class ResidentWebRunner extends ResidentRunner {
} }
final String modeName = debuggingOptions.buildInfo.friendlyModeName; final String modeName = debuggingOptions.buildInfo.friendlyModeName;
_logger!.printStatus( _logger!.printStatus(
'Launching ${getDisplayPath(target, _fileSystem!)} ' 'Launching ${getDisplayPath(target, _fileSystem)} '
'on ${device!.device!.name} in $modeName mode...', 'on ${device!.device!.name} in $modeName mode...',
); );
if (device!.device is ChromiumDevice) { if (device!.device is ChromiumDevice) {
...@@ -271,7 +271,7 @@ class ResidentWebRunner extends ResidentRunner { ...@@ -271,7 +271,7 @@ class ResidentWebRunner extends ResidentRunner {
buildInfo: debuggingOptions.buildInfo, buildInfo: debuggingOptions.buildInfo,
enableDwds: _enableDwds, enableDwds: _enableDwds,
enableDds: debuggingOptions.enableDds, enableDds: debuggingOptions.enableDds,
entrypoint: _fileSystem!.file(target).uri, entrypoint: _fileSystem.file(target).uri,
expressionCompiler: expressionCompiler, expressionCompiler: expressionCompiler,
chromiumLauncher: _chromiumLauncher, chromiumLauncher: _chromiumLauncher,
nullAssertions: debuggingOptions.nullAssertions, nullAssertions: debuggingOptions.nullAssertions,
...@@ -425,7 +425,7 @@ class ResidentWebRunner extends ResidentRunner { ...@@ -425,7 +425,7 @@ class ResidentWebRunner extends ResidentRunner {
Future<Uri> _generateEntrypoint(Uri mainUri, PackageConfig? packageConfig) async { Future<Uri> _generateEntrypoint(Uri mainUri, PackageConfig? packageConfig) async {
File? result = _generatedEntrypointDirectory?.childFile('web_entrypoint.dart'); File? result = _generatedEntrypointDirectory?.childFile('web_entrypoint.dart');
if (_generatedEntrypointDirectory == null) { if (_generatedEntrypointDirectory == null) {
_generatedEntrypointDirectory ??= _fileSystem!.systemTempDirectory.createTempSync('flutter_tools.') _generatedEntrypointDirectory ??= _fileSystem.systemTempDirectory.createTempSync('flutter_tools.')
..createSync(); ..createSync();
result = _generatedEntrypointDirectory!.childFile('web_entrypoint.dart'); result = _generatedEntrypointDirectory!.childFile('web_entrypoint.dart');
...@@ -438,16 +438,17 @@ class ResidentWebRunner extends ResidentRunner { ...@@ -438,16 +438,17 @@ class ResidentWebRunner extends ResidentRunner {
Uri? importedEntrypoint = packageConfig!.toPackageUri(mainUri); Uri? importedEntrypoint = packageConfig!.toPackageUri(mainUri);
// Special handling for entrypoints that are not under lib, such as test scripts. // Special handling for entrypoints that are not under lib, such as test scripts.
if (importedEntrypoint == null) { if (importedEntrypoint == null) {
final String parent = _fileSystem!.file(mainUri).parent.path; final String parent = _fileSystem.file(mainUri).parent.path;
flutterDevices.first!.generator!.addFileSystemRoot(parent); flutterDevices.first.generator!
flutterDevices.first!.generator!.addFileSystemRoot(_fileSystem!.directory('test').absolute.path); ..addFileSystemRoot(parent)
..addFileSystemRoot(_fileSystem.directory('test').absolute.path);
importedEntrypoint = Uri( importedEntrypoint = Uri(
scheme: 'org-dartlang-app', scheme: 'org-dartlang-app',
path: '/${mainUri.pathSegments.last}', path: '/${mainUri.pathSegments.last}',
); );
} }
final LanguageVersion languageVersion = determineLanguageVersion( final LanguageVersion languageVersion = determineLanguageVersion(
_fileSystem!.file(mainUri), _fileSystem.file(mainUri),
packageConfig[flutterProject.manifest.appName], packageConfig[flutterProject.manifest.appName],
Cache.flutterRoot!, Cache.flutterRoot!,
); );
...@@ -487,7 +488,7 @@ class ResidentWebRunner extends ResidentRunner { ...@@ -487,7 +488,7 @@ class ResidentWebRunner extends ResidentRunner {
); );
final UpdateFSReport report = await device!.devFS!.update( final UpdateFSReport report = await device!.devFS!.update(
mainUri: await _generateEntrypoint( mainUri: await _generateEntrypoint(
_fileSystem!.file(mainPath).absolute.uri, _fileSystem.file(mainPath).absolute.uri,
invalidationResult.packageConfig, invalidationResult.packageConfig,
), ),
target: target, target: target,
...@@ -603,7 +604,7 @@ class ResidentWebRunner extends ResidentRunner { ...@@ -603,7 +604,7 @@ class ResidentWebRunner extends ResidentRunner {
} }
if (websocketUri != null) { if (websocketUri != null) {
if (debuggingOptions.vmserviceOutFile != null) { if (debuggingOptions.vmserviceOutFile != null) {
_fileSystem!.file(debuggingOptions.vmserviceOutFile) _fileSystem.file(debuggingOptions.vmserviceOutFile)
..createSync(recursive: true) ..createSync(recursive: true)
..writeAsStringSync(websocketUri.toString()); ..writeAsStringSync(websocketUri.toString());
} }
......
...@@ -240,7 +240,7 @@ class FlutterDevice { ...@@ -240,7 +240,7 @@ class FlutterDevice {
bool cacheStartupProfile = false, bool cacheStartupProfile = false,
bool enableDds = true, bool enableDds = true,
required bool allowExistingDdsInstance, required bool allowExistingDdsInstance,
bool? ipv6 = false, bool ipv6 = false,
}) { }) {
final Completer<void> completer = Completer<void>(); final Completer<void> completer = Completer<void>();
late StreamSubscription<void> subscription; late StreamSubscription<void> subscription;
...@@ -927,14 +927,14 @@ abstract class ResidentHandlers { ...@@ -927,14 +927,14 @@ abstract class ResidentHandlers {
if (!supportsWriteSkSL) { if (!supportsWriteSkSL) {
throw Exception('writeSkSL is not supported by this runner.'); throw Exception('writeSkSL is not supported by this runner.');
} }
final List<FlutterView> views = await flutterDevices final FlutterDevice flutterDevice = flutterDevices.first!;
.first! final FlutterVmService vmService = flutterDevice.vmService!;
.vmService!.getFlutterViews(); final List<FlutterView> views = await vmService.getFlutterViews();
final Map<String, Object> data = await (flutterDevices.first!.vmService!.getSkSLs( final Map<String, Object?>? data = await vmService.getSkSLs(
viewId: views.first.id, viewId: views.first.id,
) as FutureOr<Map<String, Object>>); );
final Device device = flutterDevices.first!.device!; final Device device = flutterDevice.device!;
return sharedSkSlWriter(device, data); return sharedSkSlWriter(device, data!);
} }
/// Take a screenshot on the provided [device]. /// Take a screenshot on the provided [device].
...@@ -1091,10 +1091,10 @@ abstract class ResidentRunner extends ResidentHandlers { ...@@ -1091,10 +1091,10 @@ abstract class ResidentRunner extends ResidentHandlers {
Logger? get logger => globals.logger; Logger? get logger => globals.logger;
@override @override
FileSystem? get fileSystem => globals.fs; FileSystem get fileSystem => globals.fs;
@override @override
final List<FlutterDevice?> flutterDevices; final List<FlutterDevice> flutterDevices;
final String target; final String target;
final DebuggingOptions debuggingOptions; final DebuggingOptions debuggingOptions;
...@@ -1171,7 +1171,7 @@ abstract class ResidentRunner extends ResidentHandlers { ...@@ -1171,7 +1171,7 @@ abstract class ResidentRunner extends ResidentHandlers {
// //
// Would be null if there is no device connected or // Would be null if there is no device connected or
// there is no devFS associated with the first device. // there is no devFS associated with the first device.
Uri? get uri => flutterDevices.first?.devFS?.baseUri; Uri? get uri => flutterDevices.first.devFS?.baseUri;
/// Returns [true] if the resident runner exited after invoking [exit()]. /// Returns [true] if the resident runner exited after invoking [exit()].
bool get exited => _exited; bool get exited => _exited;
...@@ -1257,7 +1257,7 @@ abstract class ResidentRunner extends ResidentHandlers { ...@@ -1257,7 +1257,7 @@ abstract class ResidentRunner extends ResidentHandlers {
void writeVmServiceFile() { void writeVmServiceFile() {
if (debuggingOptions.vmserviceOutFile != null) { if (debuggingOptions.vmserviceOutFile != null) {
try { try {
final String address = flutterDevices.first!.vmService!.wsAddress.toString(); final String address = flutterDevices.first.vmService!.wsAddress.toString();
final File vmserviceOutFile = globals.fs.file(debuggingOptions.vmserviceOutFile); final File vmserviceOutFile = globals.fs.file(debuggingOptions.vmserviceOutFile);
vmserviceOutFile.createSync(recursive: true); vmserviceOutFile.createSync(recursive: true);
vmserviceOutFile.writeAsStringSync(address); vmserviceOutFile.writeAsStringSync(address);
...@@ -1359,7 +1359,7 @@ abstract class ResidentRunner extends ResidentHandlers { ...@@ -1359,7 +1359,7 @@ abstract class ResidentRunner extends ResidentHandlers {
hostVmServicePort: debuggingOptions.hostVmServicePort, hostVmServicePort: debuggingOptions.hostVmServicePort,
getSkSLMethod: getSkSLMethod, getSkSLMethod: getSkSLMethod,
printStructuredErrorLogMethod: printStructuredErrorLog, printStructuredErrorLogMethod: printStructuredErrorLog,
ipv6: ipv6, ipv6: ipv6 ?? false,
disableServiceAuthCodes: debuggingOptions.disableServiceAuthCodes, disableServiceAuthCodes: debuggingOptions.disableServiceAuthCodes,
cacheStartupProfile: debuggingOptions.cacheStartupProfile, cacheStartupProfile: debuggingOptions.cacheStartupProfile,
); );
......
...@@ -88,11 +88,11 @@ class ColdRunner extends ResidentRunner { ...@@ -88,11 +88,11 @@ class ColdRunner extends ResidentRunner {
)); ));
} }
if (flutterDevices.first!.observatoryUris != null) { if (flutterDevices.first.observatoryUris != null) {
// For now, only support one debugger connection. // For now, only support one debugger connection.
connectionInfoCompleter?.complete(DebugConnectionInfo( connectionInfoCompleter?.complete(DebugConnectionInfo(
httpUri: flutterDevices.first!.vmService!.httpAddress, httpUri: flutterDevices.first.vmService!.httpAddress,
wsUri: flutterDevices.first!.vmService!.wsAddress, wsUri: flutterDevices.first.vmService!.wsAddress,
)); ));
} }
...@@ -108,7 +108,7 @@ class ColdRunner extends ResidentRunner { ...@@ -108,7 +108,7 @@ class ColdRunner extends ResidentRunner {
if (traceStartup) { if (traceStartup) {
// Only trace startup for the first device. // Only trace startup for the first device.
final FlutterDevice device = flutterDevices.first!; final FlutterDevice device = flutterDevices.first;
if (device.vmService != null) { if (device.vmService != null) {
globals.printStatus('Tracing startup on ${device.device!.name}.'); globals.printStatus('Tracing startup on ${device.device!.name}.');
final String outputPath = globals.platform.environment[kFlutterTestOutputsDirEnvName] ?? getBuildDirectory(); final String outputPath = globals.platform.environment[kFlutterTestOutputsDirEnvName] ?? getBuildDirectory();
......
...@@ -141,7 +141,7 @@ class HotRunner extends ResidentRunner { ...@@ -141,7 +141,7 @@ class HotRunner extends ResidentRunner {
} }
if (flutterDevices.length == 1) { if (flutterDevices.length == 1) {
final Device device = flutterDevices.first!.device!; final Device device = flutterDevices.first.device!;
_targetPlatform = getNameForTargetPlatform(await device.targetPlatform); _targetPlatform = getNameForTargetPlatform(await device.targetPlatform);
_sdkName = await device.sdkNameAndVersion; _sdkName = await device.sdkNameAndVersion;
_emulator = await device.isLocalEmulator; _emulator = await device.isLocalEmulator;
...@@ -257,8 +257,8 @@ class HotRunner extends ResidentRunner { ...@@ -257,8 +257,8 @@ class HotRunner extends ResidentRunner {
// Only handle one debugger connection. // Only handle one debugger connection.
connectionInfoCompleter.complete( connectionInfoCompleter.complete(
DebugConnectionInfo( DebugConnectionInfo(
httpUri: flutterDevices.first!.vmService!.httpAddress, httpUri: flutterDevices.first.vmService!.httpAddress,
wsUri: flutterDevices.first!.vmService!.wsAddress, wsUri: flutterDevices.first.vmService!.wsAddress,
baseUri: baseUris.first.toString(), baseUri: baseUris.first.toString(),
), ),
); );
...@@ -454,12 +454,13 @@ class HotRunner extends ResidentRunner { ...@@ -454,12 +454,13 @@ class HotRunner extends ResidentRunner {
} }
final Stopwatch findInvalidationTimer = _stopwatchFactory.createStopwatch('updateDevFS')..start(); final Stopwatch findInvalidationTimer = _stopwatchFactory.createStopwatch('updateDevFS')..start();
final DevFS devFS = flutterDevices[0].devFS!;
final InvalidationResult invalidationResult = await projectFileInvalidator.findInvalidated( final InvalidationResult invalidationResult = await projectFileInvalidator.findInvalidated(
lastCompiled: flutterDevices[0]!.devFS!.lastCompiled, lastCompiled: devFS.lastCompiled,
urisToMonitor: flutterDevices[0]!.devFS!.sources, urisToMonitor: devFS.sources,
packagesPath: packagesFilePath, packagesPath: packagesFilePath,
asyncScanning: hotRunnerConfig!.asyncScanning, asyncScanning: hotRunnerConfig!.asyncScanning,
packageConfig: flutterDevices[0]!.devFS!.lastPackageConfig packageConfig: devFS.lastPackageConfig
?? debuggingOptions.buildInfo.packageConfig, ?? debuggingOptions.buildInfo.packageConfig,
); );
findInvalidationTimer.stop(); findInvalidationTimer.stop();
...@@ -474,7 +475,7 @@ class HotRunner extends ResidentRunner { ...@@ -474,7 +475,7 @@ class HotRunner extends ResidentRunner {
} }
final UpdateFSReport results = UpdateFSReport( final UpdateFSReport results = UpdateFSReport(
success: true, success: true,
scannedSourcesCount: flutterDevices[0]!.devFS!.sources.length, scannedSourcesCount: devFS.sources.length,
findInvalidatedDuration: findInvalidationTimer.elapsed, findInvalidatedDuration: findInvalidationTimer.elapsed,
); );
for (final FlutterDevice? device in flutterDevices) { for (final FlutterDevice? device in flutterDevices) {
...@@ -497,21 +498,27 @@ class HotRunner extends ResidentRunner { ...@@ -497,21 +498,27 @@ class HotRunner extends ResidentRunner {
} }
void _resetDirtyAssets() { void _resetDirtyAssets() {
for (final FlutterDevice? device in flutterDevices) { for (final FlutterDevice device in flutterDevices) {
device!.devFS!.assetPathsToEvict.clear(); final DevFS? devFS = device.devFS;
device.devFS!.shaderPathsToEvict.clear(); if (devFS == null) {
// This is sometimes null, however we don't know why and have not been
// able to reproduce, https://github.com/flutter/flutter/issues/108653
continue;
}
devFS.assetPathsToEvict.clear();
devFS.shaderPathsToEvict.clear();
} }
} }
Future<void> _cleanupDevFS() async { Future<void> _cleanupDevFS() async {
final List<Future<void>> futures = <Future<void>>[]; final List<Future<void>> futures = <Future<void>>[];
for (final FlutterDevice? device in flutterDevices) { for (final FlutterDevice device in flutterDevices) {
if (device!.devFS != null) { if (device.devFS != null) {
// Cleanup the devFS, but don't wait indefinitely. // Cleanup the devFS, but don't wait indefinitely.
// We ignore any errors, because it's not clear what we would do anyway. // We ignore any errors, because it's not clear what we would do anyway.
futures.add(device.devFS!.destroy() futures.add(device.devFS!.destroy()
.timeout(const Duration(milliseconds: 250)) .timeout(const Duration(milliseconds: 250))
.catchError((dynamic error) { .catchError((Object? error) {
globals.printTrace('Ignored error while cleaning up DevFS: $error'); globals.printTrace('Ignored error while cleaning up DevFS: $error');
})); }));
} }
...@@ -756,7 +763,7 @@ class HotRunner extends ResidentRunner { ...@@ -756,7 +763,7 @@ class HotRunner extends ResidentRunner {
String? restartEvent; String? restartEvent;
try { try {
final Stopwatch restartTimer = _stopwatchFactory.createStopwatch('fullRestartHelper')..start(); final Stopwatch restartTimer = _stopwatchFactory.createStopwatch('fullRestartHelper')..start();
if (!(await (hotRunnerConfig!.setupHotRestart() as FutureOr<bool>))) { if ((await hotRunnerConfig!.setupHotRestart()) != true) {
return OperationResult(1, 'setupHotRestart failed'); return OperationResult(1, 'setupHotRestart failed');
} }
result = await _restartFromSources(reason: reason); result = await _restartFromSources(reason: reason);
...@@ -885,7 +892,7 @@ class HotRunner extends ResidentRunner { ...@@ -885,7 +892,7 @@ class HotRunner extends ResidentRunner {
} }
final Stopwatch reloadTimer = _stopwatchFactory.createStopwatch('reloadSources:reload')..start(); final Stopwatch reloadTimer = _stopwatchFactory.createStopwatch('reloadSources:reload')..start();
if (!(await (hotRunnerConfig!.setupHotReload() as FutureOr<bool>))) { if ((await hotRunnerConfig!.setupHotReload()) != true) {
return OperationResult(1, 'setupHotReload failed'); return OperationResult(1, 'setupHotReload failed');
} }
final Stopwatch devFSTimer = Stopwatch()..start(); final Stopwatch devFSTimer = Stopwatch()..start();
......
...@@ -13,7 +13,7 @@ import 'convert.dart'; ...@@ -13,7 +13,7 @@ import 'convert.dart';
import 'device.dart'; import 'device.dart';
import 'globals.dart' as globals; import 'globals.dart' as globals;
Future<String?> sharedSkSlWriter(Device device, Map<String, Object> data, { Future<String?> sharedSkSlWriter(Device device, Map<String, Object?> data, {
File? outputFile, File? outputFile,
Logger? logger, Logger? logger,
}) async { }) async {
......
...@@ -493,7 +493,7 @@ class FlutterVmService { ...@@ -493,7 +493,7 @@ class FlutterVmService {
/// ///
/// This method will only return data if `--cache-sksl` was provided as a /// This method will only return data if `--cache-sksl` was provided as a
/// flutter run argument, and only then on physical devices. /// flutter run argument, and only then on physical devices.
Future<Map<String, Object>?> getSkSLs({ Future<Map<String, Object?>?> getSkSLs({
required String viewId, required String viewId,
}) async { }) async {
final vm_service.Response? response = await callMethodWrapper( final vm_service.Response? response = await callMethodWrapper(
...@@ -505,7 +505,7 @@ class FlutterVmService { ...@@ -505,7 +505,7 @@ class FlutterVmService {
if (response == null) { if (response == null) {
return null; return null;
} }
return response.json?['SkSLs'] as Map<String, Object>?; return response.json?['SkSLs'] as Map<String, Object?>?;
} }
/// Flush all tasks on the UI thread for an attached Flutter view. /// Flush all tasks on the UI thread for an attached Flutter view.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment