Skip to content

Commit 54ac721

Browse files
authored
Merge pull request #2072 from ahoppen/update-index-store-db-during-indexing
Ensure that unit file generated by background indexing are immediately loaded into indextore-db
2 parents 4220b7f + 8b2727f commit 54ac721

File tree

3 files changed

+58
-0
lines changed

3 files changed

+58
-0
lines changed

Sources/SemanticIndex/CheckedIndex.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,11 @@ package final actor UncheckedIndex: Sendable {
336336
package nonisolated func pollForUnitChangesAndWait() {
337337
self.underlyingIndexStoreDB.pollForUnitChangesAndWait()
338338
}
339+
340+
/// Import the units for the given output paths into indexstore-db. Returns after the import has finished.
341+
package nonisolated func processUnitsForOutputPathsAndWait(_ outputPaths: some Collection<String>) {
342+
self.underlyingIndexStoreDB.processUnitsForOutputPathsAndWait(outputPaths)
343+
}
339344
}
340345

341346
/// Helper class to check if symbols from the index are up-to-date or if the source file has been modified after it was

Sources/SemanticIndex/UpdateIndexStoreTaskDescription.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,17 @@ package struct UpdateIndexStoreTaskDescription: IndexTaskDescription {
188188
outputPath: fileIndexInfo.outputPath
189189
)
190190
}
191+
// If we know the output paths, make sure that we load their units into indexstore-db. We would eventually also
192+
// pick the units up through file watching but that would leave a short time period in which we think that
193+
// indexing has finished (because the index process has terminated) but when the new symbols aren't present in
194+
// indexstore-db.
195+
let outputPaths = filesToIndex.compactMap { fileToIndex in
196+
switch fileToIndex.outputPath {
197+
case .path(let string): return string
198+
case .notSupported: return nil
199+
}
200+
}
201+
index.processUnitsForOutputPathsAndWait(outputPaths)
191202
await hooks.updateIndexStoreTaskDidFinish?(self)
192203
logger.log(
193204
"Finished updating index store in \(Date().timeIntervalSince(startDate) * 1000, privacy: .public)ms: \(filesToIndexDescription)"

Tests/SourceKitLSPTests/BackgroundIndexingTests.swift

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2585,6 +2585,48 @@ final class BackgroundIndexingTests: XCTestCase {
25852585
let symbols = try await project.testClient.send(WorkspaceSymbolsRequest(query: "myTestFu"))
25862586
XCTAssertEqual(symbols?.compactMap(\.symbolInformation?.name), ["myTestFunc()"])
25872587
}
2588+
2589+
func testEnsureSymbolsLoadedIntoIndexstoreDbWhenIndexingHasFinished() async throws {
2590+
let testSetupComplete = AtomicBool(initialValue: false)
2591+
let updateIndexStoreStarted = self.expectation(description: "Update index store started")
2592+
let project = try await SwiftPMTestProject(
2593+
files: [
2594+
"Test.swift": ""
2595+
],
2596+
options: .testDefault(experimentalFeatures: [.isIndexingRequest]),
2597+
hooks: Hooks(
2598+
indexHooks: IndexHooks(updateIndexStoreTaskDidStart: { _ in
2599+
guard testSetupComplete.value else {
2600+
return
2601+
}
2602+
updateIndexStoreStarted.fulfill()
2603+
})
2604+
),
2605+
enableBackgroundIndexing: true,
2606+
pollIndex: false
2607+
)
2608+
2609+
try await project.changeFileOnDisk("Test.swift", newMarkedContents: "")
2610+
try await project.testClient.send(SynchronizeRequest(index: true))
2611+
let symbolsBeforeUpdate = try await project.testClient.send(WorkspaceSymbolsRequest(query: "myTestFu"))
2612+
XCTAssertEqual(symbolsBeforeUpdate, [])
2613+
2614+
testSetupComplete.value = true
2615+
try await project.changeFileOnDisk(
2616+
"Test.swift",
2617+
newMarkedContents: """
2618+
func myTestFunc() {}
2619+
"""
2620+
)
2621+
try await fulfillmentOfOrThrow([updateIndexStoreStarted])
2622+
try await repeatUntilExpectedResult(sleepInterval: .milliseconds(2)) {
2623+
try await !project.testClient.send(IsIndexingRequest()).indexing
2624+
}
2625+
// Check that the newly added function has been registered in indexstore-db once indexing is done and that there is
2626+
// no time gap in which indexing has finished but the new unit has not been loaded into indexstore-db yet.
2627+
let symbols = try await project.testClient.send(WorkspaceSymbolsRequest(query: "myTestFu"))
2628+
XCTAssertEqual(symbols?.count, 1)
2629+
}
25882630
}
25892631

25902632
extension HoverResponseContents {

0 commit comments

Comments
 (0)