@@ -39,10 +39,10 @@ fileprivate enum TaskMetadata: DependencyTracker, Equatable {
39
39
// Adding the dependency also elevates the index task's priorities.
40
40
return true
41
41
case ( . index( let lhsUris) , . index( let rhsUris) ) :
42
- // Technically, we should be able to allow simultaneous indexing of the same file. When a file gets re-scheduled
43
- // for indexing, all previous index invocations should get cancelled. But conceptually the code becomes simpler
44
- // if we don't need to think racing indexing tasks for the same file and it shouldn't make a performance impact
45
- // in practice because of the cancellation described before .
42
+ // Technically, we should be able to allow simultaneous indexing of the same file. But conceptually the code
43
+ // becomes simpler if we don't need to think racing indexing tasks for the same file and it shouldn't make a
44
+ // performance impact in practice because if a first task indexes a file, a subsequent index task for the same
45
+ // file will realize that the index is already up-to-date based on the file's mtime and early exit .
46
46
return !lhsUris. intersection ( rhsUris) . isEmpty
47
47
}
48
48
}
@@ -82,14 +82,18 @@ fileprivate func testItems(in url: URL) async -> [TestItem] {
82
82
return await swiftTestingTests + xcTests
83
83
}
84
84
85
+ /// An in-memory syntactic index of test items within a workspace.
86
+ ///
87
+ /// The index does not get persisted to disk but instead gets rebuilt every time a workspace is opened (ie. usually when
88
+ /// sourcekit-lsp is launched). Building it takes only a few seconds, even for large projects.
85
89
actor SyntacticTestIndex {
86
90
/// The tests discovered by the index.
87
91
private var indexedTests : [ DocumentURI : IndexedTests ] = [ : ]
88
92
89
93
/// Files that have been removed using `removeFileForIndex`.
90
94
///
91
95
/// We need to keep track of these files because when the files get removed, there might be an in-progress indexing
92
- /// operation running for that file. We need to ensure that this indexing operation doesn't write add the removed file
96
+ /// operation running for that file. We need to ensure that this indexing operation doesn't add the removed file
93
97
/// back to `indexTests`.
94
98
private var removedFiles : Set < DocumentURI > = [ ]
95
99
@@ -138,6 +142,10 @@ actor SyntacticTestIndex {
138
142
139
143
/// Called when a list of files was updated. Re-scans those files
140
144
private func rescanFiles( _ uris: [ DocumentURI ] ) {
145
+ // If we scan a file again, it might have been added after being removed before. Remove it from the list of removed
146
+ // files.
147
+ removedFiles. subtract ( uris)
148
+
141
149
// Divide the files into multiple batches. This is more efficient than spawning a new task for every file, mostly
142
150
// because it keeps the number of pending items in `indexingQueue` low and adding a new task to `indexingQueue` is
143
151
// in O(number of pending tasks), since we need to scan for dependency edges to add, which would make scanning files
0 commit comments