Chromium Code Reviews| Index: pkg/analyzer/lib/file_system/physical_file_system.dart |
| diff --git a/pkg/analyzer/lib/file_system/physical_file_system.dart b/pkg/analyzer/lib/file_system/physical_file_system.dart |
| index 9cd62b6b89ed269e9d1ad5b181643e29bbcb3d3a..cbd2b0566fd21fe3a4e84efbb7b9beda3f7fe503 100644 |
| --- a/pkg/analyzer/lib/file_system/physical_file_system.dart |
| +++ b/pkg/analyzer/lib/file_system/physical_file_system.dart |
| @@ -12,10 +12,34 @@ import 'package:analyzer/file_system/file_system.dart'; |
| import 'package:analyzer/src/generated/java_io.dart'; |
| import 'package:analyzer/src/generated/source_io.dart'; |
| import 'package:analyzer/src/util/absolute_path.dart'; |
| +import 'package:isolate/isolate_runner.dart'; |
| import 'package:path/path.dart'; |
| import 'package:watcher/watcher.dart'; |
| /** |
| + * Return modification times for every file path in [paths]. |
| + * |
| + * If a path is `null`, the modification time is also `null`. |
| + * |
| + * If any exception happens, the file is considered as a not existing and |
| + * `-1` is its modification time. |
| + */ |
| +List<int> _pathsToTimes(List<String> paths) { |
| + return paths.map((path) { |
| + if (path != null) { |
| + try { |
| + io.File file = new io.File(path); |
| + return file.lastModifiedSync().millisecondsSinceEpoch; |
| + } catch (_) { |
| + return -1; |
| + } |
| + } else { |
| + return null; |
| + } |
| + }).toList(); |
| +} |
| + |
| +/** |
| * A `dart:io` based implementation of [ResourceProvider]. |
| */ |
| class PhysicalResourceProvider implements ResourceProvider { |
| @@ -31,6 +55,9 @@ class PhysicalResourceProvider implements ResourceProvider { |
| */ |
| static final String SERVER_DIR = ".dartServer"; |
| + static _SingleIsolateRunnerProvider pathsToTimesIsolateProvider = |
| + new _SingleIsolateRunnerProvider(); |
| + |
| @override |
| final AbsolutePathContext absolutePathContext = |
| new AbsolutePathContext(io.Platform.isWindows); |
| @@ -51,6 +78,15 @@ class PhysicalResourceProvider implements ResourceProvider { |
| Folder getFolder(String path) => new _PhysicalFolder(new io.Directory(path)); |
| @override |
| + Future<List<int>> getModificationTimes(List<Source> sources) async { |
| + List<String> paths = sources |
| + .map((source) => source is FileBasedSource ? source.fullName : null) |
| + .toList(); |
| + IsolateRunner runner = await pathsToTimesIsolateProvider.get(); |
| + return runner.run(_pathsToTimes, paths); |
| + } |
| + |
| + @override |
| Resource getResource(String path) { |
| if (io.FileSystemEntity.isDirectorySync(path)) { |
| return getFolder(path); |
| @@ -274,3 +310,33 @@ abstract class _PhysicalResource implements Resource { |
| @override |
| String toString() => path; |
| } |
| + |
| +/** |
| + * This class encapsulates logic for creating a single [IsolateRunner]. |
| + */ |
| +class _SingleIsolateRunnerProvider { |
| + bool _isBeenCreated = false; |
|
Brian Wilkerson
2016/07/08 21:25:09
"_is" --> "_has" || "_isBeenCreated" --> "_created
|
| + IsolateRunner _runner; |
| + |
| + /** |
| + * Complete with the only [IsolateRunner] instance. |
| + */ |
| + Future<IsolateRunner> get() async { |
| + if (_runner != null) { |
| + return _runner; |
| + } |
| + if (_isBeenCreated) { |
| + Completer<IsolateRunner> completer = new Completer<IsolateRunner>(); |
| + new Timer.periodic(new Duration(milliseconds: 20), (Timer timer) { |
| + if (_runner != null) { |
| + completer.complete(_runner); |
| + timer.cancel(); |
| + } |
| + }); |
| + return completer.future; |
| + } |
| + _isBeenCreated = true; |
| + _runner = await IsolateRunner.spawn(); |
| + return _runner; |
| + } |
| +} |