diff --git a/packages/flutter_tools/lib/src/run_hot.dart b/packages/flutter_tools/lib/src/run_hot.dart index 7b868dfdcc..b2ea6dd681 100644 --- a/packages/flutter_tools/lib/src/run_hot.dart +++ b/packages/flutter_tools/lib/src/run_hot.dart @@ -1241,9 +1241,11 @@ class ProjectFileInvalidator { final List> waitList = >[]; for (final Uri uri in urisToScan) { waitList.add(pool.withResource( - () => _fileSystem - .file(uri) - .stat() + // Calling fs.stat() is more performant than fs.file().stat(), but + // uri.toFilePath() does not work with MultiRootFileSystem. + () => (uri.hasScheme && uri.scheme != 'file' + ? _fileSystem.file(uri).stat() + : _fileSystem.stat(uri.toFilePath(windows: _platform.isWindows))) .then((FileStat stat) { final DateTime updatedAt = stat.modified; if (updatedAt != null && updatedAt.isAfter(lastCompiled)) { @@ -1255,7 +1257,11 @@ class ProjectFileInvalidator { await Future.wait(waitList); } else { for (final Uri uri in urisToScan) { - final DateTime updatedAt = _fileSystem.file(uri).statSync().modified; + // Calling fs.statSync() is more performant than fs.file().statSync(), but + // uri.toFilePath() does not work with MultiRootFileSystem. + final DateTime updatedAt = uri.hasScheme && uri.scheme != 'file' + ? _fileSystem.file(uri).statSync().modified + : _fileSystem.statSync(uri.toFilePath(windows: _platform.isWindows)).modified; if (updatedAt != null && updatedAt.isAfter(lastCompiled)) { invalidatedFiles.add(uri); } diff --git a/packages/flutter_tools/test/general.shard/project_file_invalidator_test.dart b/packages/flutter_tools/test/general.shard/project_file_invalidator_test.dart index 4f6f9bcf94..ca9544b8a8 100644 --- a/packages/flutter_tools/test/general.shard/project_file_invalidator_test.dart +++ b/packages/flutter_tools/test/general.shard/project_file_invalidator_test.dart @@ -7,6 +7,7 @@ import 'package:file/memory.dart'; import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/logger.dart'; +import 'package:flutter_tools/src/base/multi_root_file_system.dart'; import 'package:flutter_tools/src/base/platform.dart'; import 'package:flutter_tools/src/convert.dart'; import 'package:flutter_tools/src/run_hot.dart'; @@ -164,5 +165,36 @@ void main() { expect(nextInvalidationResult.packageConfig, isNot(invalidationResult.packageConfig)); }); + + testWithoutContext('Works with MultiRootFileSystem uris, asyncScanning: $asyncScanning', () async { + final FileSystem fileSystem = MemoryFileSystem.test(); + final FileSystem multiRootFileSystem = MultiRootFileSystem( + delegate: fileSystem, + scheme: 'scheme', + roots: [ + '/root', + ], + ); + final ProjectFileInvalidator projectFileInvalidator = ProjectFileInvalidator( + fileSystem: multiRootFileSystem, + platform: FakePlatform(), + logger: BufferLogger.test(), + ); + + expect( + (await projectFileInvalidator.findInvalidated( + lastCompiled: inFuture, + urisToMonitor: [ + Uri.parse('file1'), + Uri.parse('file:///file2'), + Uri.parse('scheme:///file3'), + ], + packagesPath: '.packages', + asyncScanning: asyncScanning, + packageConfig: PackageConfig.empty, + )).uris, + isEmpty, + ); + }); } }