Skip to content

Commit e1c84fe

Browse files
committed
When the build system sends an update for build targets, update the index for the files in those targets
For each file in the changed targets, we still check whether it has an up-to-date unit based on timestamps. The important thing for this change is that we start indexing files for which we only receive build settings after an update from the build server.
1 parent 6ae6927 commit e1c84fe

File tree

6 files changed

+109
-19
lines changed

6 files changed

+109
-19
lines changed

Sources/BuildServerProtocol/Messages/InitializeBuildRequest.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -283,11 +283,11 @@ public struct SourceKitInitializeBuildResponseData: LSPAnyCodable, Codable, Send
283283
public var sourceKitOptionsProvider: Bool?
284284

285285
public init(
286-
indexDatabasePath: String?,
287-
indexStorePath: String?,
288-
watchers: [FileSystemWatcher]?,
289-
prepareProvider: Bool?,
290-
sourceKitOptionsProvider: Bool?
286+
indexDatabasePath: String? = nil,
287+
indexStorePath: String? = nil,
288+
watchers: [FileSystemWatcher]? = nil,
289+
prepareProvider: Bool? = nil,
290+
sourceKitOptionsProvider: Bool? = nil
291291
) {
292292
self.indexDatabasePath = indexDatabasePath
293293
self.indexStorePath = indexStorePath

Sources/BuildSystemIntegration/TestBuildSystem.swift

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,15 @@ package actor TestBuildSystem: MessageHandler {
3737
connectionToSourceKitLSP.send(OnBuildTargetDidChangeNotification(changes: nil))
3838
}
3939

40-
package nonisolated var supportsPreparation: Bool { false }
40+
private let initializeData: SourceKitInitializeBuildResponseData
4141

42-
package init(connectionToSourceKitLSP: any Connection) {
42+
package init(
43+
initializeData: SourceKitInitializeBuildResponseData = SourceKitInitializeBuildResponseData(
44+
sourceKitOptionsProvider: true
45+
),
46+
connectionToSourceKitLSP: any Connection
47+
) {
48+
self.initializeData = initializeData
4349
self.connectionToSourceKitLSP = connectionToSourceKitLSP
4450
}
4551

@@ -90,6 +96,8 @@ package actor TestBuildSystem: MessageHandler {
9096
handle(request, using: self.workspaceBuildTargetsRequest)
9197
case let request as WorkspaceWaitForBuildSystemUpdatesRequest:
9298
handle(request, using: self.workspaceWaitForBuildSystemUpdatesRequest)
99+
case let request as BuildTargetPrepareRequest:
100+
handle(request, using: self.prepareTarget)
93101
default:
94102
reply(.failure(ResponseError.methodNotFound(type(of: request).method)))
95103
}
@@ -101,7 +109,8 @@ package actor TestBuildSystem: MessageHandler {
101109
version: "",
102110
bspVersion: "2.2.0",
103111
capabilities: BuildServerCapabilities(),
104-
data: nil
112+
dataKind: .sourceKit,
113+
data: initializeData.encodeToLSPAny()
105114
)
106115
}
107116

@@ -148,6 +157,10 @@ package actor TestBuildSystem: MessageHandler {
148157
return buildSettingsByFile[request.textDocument.uri]
149158
}
150159

160+
func prepareTarget(_ request: BuildTargetPrepareRequest) async throws -> VoidResponse {
161+
return VoidResponse()
162+
}
163+
151164
package func waitForBuildSystemUpdates(request: WorkspaceWaitForBuildSystemUpdatesRequest) async -> VoidResponse {
152165
return VoidResponse()
153166
}

Sources/SemanticIndex/SemanticIndexManager.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,7 @@ package final actor SemanticIndexManager {
672672
/// `indexFilesWithUpToDateUnit` is `true`.
673673
///
674674
/// The returned task finishes when all files are indexed.
675-
private func scheduleIndexing(
675+
package func scheduleIndexing(
676676
of files: some Collection<DocumentURI> & Sendable,
677677
indexFilesWithUpToDateUnit: Bool,
678678
priority: TaskPriority?

Sources/SourceKitLSP/Workspace.swift

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -428,8 +428,24 @@ package final class Workspace: Sendable, BuildSystemManagerDelegate {
428428

429429
package func buildTargetsChanged(_ changes: [BuildTargetEvent]?) async {
430430
await sourceKitLSPServer?.fileHandlingCapabilityChanged()
431-
let testFiles = await orLog("Getting test files") { try await buildSystemManager.testFiles() } ?? []
432-
await syntacticTestIndex.listOfTestFilesDidChange(testFiles)
431+
await orLog("Scheduling re-indexing of changed targets") {
432+
var sourceFiles = try await self.buildSystemManager.sourceFiles(includeNonBuildableFiles: false)
433+
if let changes {
434+
let changedTargets = changes.map(\.target)
435+
sourceFiles = sourceFiles.filter {
436+
!$0.value.targets.intersection(changedTargets).isEmpty
437+
}
438+
}
439+
_ = await semanticIndexManager?.scheduleIndexing(
440+
of: sourceFiles.keys,
441+
indexFilesWithUpToDateUnit: false,
442+
priority: .low
443+
)
444+
}
445+
await orLog("Scheduling syntactic test re-indexing") {
446+
let testFiles = try await buildSystemManager.testFiles()
447+
await syntacticTestIndex.listOfTestFilesDidChange(testFiles)
448+
}
433449
}
434450

435451
package var clientSupportsWorkDoneProgress: Bool {

Tests/SourceKitLSPTests/BackgroundIndexingTests.swift

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
import BuildServerProtocol
1314
import BuildSystemIntegration
1415
import LanguageServerProtocol
1516
import LanguageServerProtocolExtensions
@@ -1883,6 +1884,72 @@ final class BackgroundIndexingTests: XCTestCase {
18831884
) != nil
18841885
}
18851886
}
1887+
1888+
func testIndexFileIfBuildTargetsChange() async throws {
1889+
let testBuildSystem = ThreadSafeBox<TestBuildSystem?>(initialValue: nil)
1890+
let project = try await MultiFileTestProject(
1891+
files: [
1892+
"Test.swift": """
1893+
func 1️⃣myTestFunc() {}
1894+
"""
1895+
],
1896+
hooks: Hooks(
1897+
buildSystemHooks: BuildSystemHooks(injectBuildServer: { projectRoot, connectionToSourceKitLSP in
1898+
assert(testBuildSystem.value == nil, "Build system injector hook can only create a single TestBuildSystem")
1899+
let buildSystem = TestBuildSystem(
1900+
initializeData: SourceKitInitializeBuildResponseData(
1901+
indexDatabasePath: projectRoot.appendingPathComponent("index-db").path,
1902+
indexStorePath: projectRoot.appendingPathComponent("index-store").path,
1903+
prepareProvider: true,
1904+
sourceKitOptionsProvider: true
1905+
),
1906+
connectionToSourceKitLSP: connectionToSourceKitLSP
1907+
)
1908+
testBuildSystem.value = buildSystem
1909+
let connection = LocalConnection(receiverName: "TestBuildSystem")
1910+
connection.start(handler: buildSystem)
1911+
return connection
1912+
})
1913+
),
1914+
enableBackgroundIndexing: true
1915+
)
1916+
let fileUrl = try XCTUnwrap(project.uri(for: "Test.swift").fileURL)
1917+
1918+
var compilerArguments = [fileUrl.path]
1919+
if let defaultSDKPath {
1920+
compilerArguments += ["-sdk", defaultSDKPath]
1921+
}
1922+
1923+
// We don't initially index Test.swift because we don't have build settings for it.
1924+
1925+
try await XCTUnwrap(testBuildSystem.value).setBuildSettings(
1926+
for: DocumentURI(fileUrl),
1927+
to: TextDocumentSourceKitOptionsResponse(compilerArguments: compilerArguments)
1928+
)
1929+
1930+
// But once we get build settings for it, we should index the file.
1931+
1932+
try await repeatUntilExpectedResult {
1933+
let workspaceSymbols = try await project.testClient.send(WorkspaceSymbolsRequest(query: "myTestFunc"))
1934+
guard let workspaceSymbols, !workspaceSymbols.isEmpty else {
1935+
// No results yet, indexing of the file might not have finished.
1936+
return false
1937+
}
1938+
XCTAssertEqual(
1939+
workspaceSymbols,
1940+
[
1941+
.symbolInformation(
1942+
SymbolInformation(
1943+
name: "myTestFunc()",
1944+
kind: .function,
1945+
location: try project.location(from: "1️⃣", to: "1️⃣", in: "Test.swift")
1946+
)
1947+
)
1948+
]
1949+
)
1950+
return true
1951+
}
1952+
}
18861953
}
18871954

18881955
extension HoverResponseContents {

Tests/SourceKitLSPTests/WorkspaceSymbolsTests.swift

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,20 +76,14 @@ class WorkspaceSymbolsTests: XCTestCase {
7676
SymbolInformation(
7777
name: "afuncFromA()",
7878
kind: .function,
79-
location: Location(
80-
uri: try project.uri(for: "PackageALib.swift"),
81-
range: Range(try project.position(of: "1️⃣", in: "PackageALib.swift"))
82-
)
79+
location: try project.location(from: "1️⃣", to: "1️⃣", in: "PackageALib.swift")
8380
)
8481
),
8582
.symbolInformation(
8683
SymbolInformation(
8784
name: "funcFromB()",
8885
kind: .function,
89-
location: Location(
90-
uri: try project.uri(for: "PackageBLib.swift"),
91-
range: Range(try project.position(of: "2️⃣", in: "PackageBLib.swift"))
92-
)
86+
location: try project.location(from: "2️⃣", to: "2️⃣", in: "PackageBLib.swift")
9387
)
9488
),
9589
]

0 commit comments

Comments
 (0)