Index: pkg/front_end/lib/src/incremental/file_state.dart |
diff --git a/pkg/front_end/lib/src/incremental/file_state.dart b/pkg/front_end/lib/src/incremental/file_state.dart |
index 77f4d147e9e0bef8a2fc845c5f2eae8eff67cb6f..27519429b9cdec9baac03341800fad37ca8b796d 100644 |
--- a/pkg/front_end/lib/src/incremental/file_state.dart |
+++ b/pkg/front_end/lib/src/incremental/file_state.dart |
@@ -49,6 +49,7 @@ class FileState { |
Set<FileState> _directReferencedFiles = new Set<FileState>(); |
List<FileState> _directReferencedLibraries = <FileState>[]; |
+ Set<FileState> _transitiveFiles; |
/// This flag is set to `true` during the mark phase of garbage collection |
/// and set back to `false` for survived instances. |
@@ -106,17 +107,18 @@ class FileState { |
/// Return the set of transitive files - the file itself and all of the |
/// directly or indirectly referenced files. |
Set<FileState> get transitiveFiles { |
- // TODO(scheglov) add caching. |
- var transitiveFiles = new Set<FileState>(); |
+ if (_transitiveFiles == null) { |
+ _transitiveFiles = new Set<FileState>(); |
- void appendReferenced(FileState file) { |
- if (transitiveFiles.add(file)) { |
- file._directReferencedFiles.forEach(appendReferenced); |
+ void appendReferenced(FileState file) { |
+ if (_transitiveFiles.add(file)) { |
+ file._directReferencedFiles.forEach(appendReferenced); |
+ } |
} |
- } |
- appendReferenced(this); |
- return transitiveFiles; |
+ appendReferenced(this); |
+ } |
+ return _transitiveFiles; |
} |
@override |
@@ -191,6 +193,7 @@ class FileState { |
} |
// Compute referenced files. |
+ var oldDirectReferencedFiles = _directReferencedFiles; |
_directReferencedFiles = new Set<FileState>() |
..addAll(_importedLibraries) |
..addAll(_exportedLibraries) |
@@ -199,6 +202,19 @@ class FileState { |
..addAll(_importedLibraries) |
..addAll(_exportedLibraries)) |
.toList(); |
+ |
+ // If the set of directly referenced files of this file is changed, |
+ // then the transitive sets of files that include this file are also |
+ // changed. Reset these transitive sets. |
+ if (_directReferencedFiles.length != oldDirectReferencedFiles.length || |
+ !_directReferencedFiles.containsAll(oldDirectReferencedFiles)) { |
+ for (var file in _fsState._uriToFile.values) { |
+ if (file._transitiveFiles != null && |
+ file._transitiveFiles.contains(this)) { |
+ file._transitiveFiles = null; |
+ } |
+ } |
+ } |
} |
@override |