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; |
+ } |
+} |