Skip to content

Commit f07a4bd

Browse files
committed
Mark target preparation out-of-date when it has changed in the build server
When the target changes in the build server, it’s build settings might have changed, which means that we can no longer assume that it’s up-to-date.
1 parent bafd8ba commit f07a4bd

File tree

3 files changed

+96
-14
lines changed

3 files changed

+96
-14
lines changed

Sources/SemanticIndex/SemanticIndexManager.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,38 @@ package final actor SemanticIndexManager {
413413
)
414414
}
415415

416+
package func buildTargetsChanged(_ changes: [BuildTargetEvent]?) async {
417+
let targets = changes?.map(\.target)
418+
419+
if let targets {
420+
var targetsAndDependencies = targets
421+
targetsAndDependencies += await buildSystemManager.targets(dependingOn: Set(targets))
422+
if !targetsAndDependencies.isEmpty {
423+
logger.info(
424+
"""
425+
Marking dependent targets as out-of-date: \
426+
\(String(targetsAndDependencies.map(\.uri.stringValue).joined(separator: ", ")))
427+
"""
428+
)
429+
await preparationUpToDateTracker.markOutOfDate(targetsAndDependencies)
430+
}
431+
} else {
432+
await preparationUpToDateTracker.markAllKnownOutOfDate()
433+
}
434+
435+
await orLog("Scheduling re-indexing of changed targets") {
436+
var sourceFiles = try await self.buildSystemManager.sourceFiles(includeNonBuildableFiles: false)
437+
if let targets {
438+
sourceFiles = sourceFiles.filter { !$0.value.targets.isDisjoint(with: targets) }
439+
}
440+
_ = await scheduleIndexing(
441+
of: sourceFiles.keys,
442+
indexFilesWithUpToDateUnit: false,
443+
priority: .low
444+
)
445+
}
446+
}
447+
416448
/// Returns the files that should be indexed to get up-to-date index information for the given files.
417449
///
418450
/// If `files` contains a header file, this will return a `FileToIndex` that re-indexes a main file which includes the

Sources/SourceKitLSP/Workspace.swift

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -435,20 +435,7 @@ package final class Workspace: Sendable, BuildSystemManagerDelegate {
435435

436436
package func buildTargetsChanged(_ changes: [BuildTargetEvent]?) async {
437437
await sourceKitLSPServer?.fileHandlingCapabilityChanged()
438-
await orLog("Scheduling re-indexing of changed targets") {
439-
var sourceFiles = try await self.buildSystemManager.sourceFiles(includeNonBuildableFiles: false)
440-
if let changes {
441-
let changedTargets = changes.map(\.target)
442-
sourceFiles = sourceFiles.filter {
443-
!$0.value.targets.isDisjoint(with: changedTargets)
444-
}
445-
}
446-
_ = await semanticIndexManager?.scheduleIndexing(
447-
of: sourceFiles.keys,
448-
indexFilesWithUpToDateUnit: false,
449-
priority: .low
450-
)
451-
}
438+
await semanticIndexManager?.buildTargetsChanged(changes)
452439
await orLog("Scheduling syntactic test re-indexing") {
453440
let testFiles = try await buildSystemManager.testFiles()
454441
await syntacticTestIndex.listOfTestFilesDidChange(testFiles)

Tests/SourceKitLSPTests/BackgroundIndexingTests.swift

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1977,6 +1977,69 @@ final class BackgroundIndexingTests: XCTestCase {
19771977
return true
19781978
}
19791979
}
1980+
1981+
func testRePrepareTargetsWhenBuildServerChanges() async throws {
1982+
let project = try await SwiftPMTestProject(
1983+
files: [
1984+
"LibA/LibA.swift": """
1985+
#if ENABLE_FOO
1986+
public func foo() {}
1987+
#endif
1988+
""",
1989+
"LibB/LibB.swift": """
1990+
import LibA
1991+
1992+
func test() {
1993+
1️⃣foo()
1994+
}
1995+
""",
1996+
],
1997+
manifest: """
1998+
// swift-tools-version: 5.7
1999+
2000+
import PackageDescription
2001+
2002+
let package = Package(
2003+
name: "MyLibrary",
2004+
targets: [
2005+
.target(name: "LibA"),
2006+
.target(name: "LibB", dependencies: ["LibA"]),
2007+
]
2008+
)
2009+
""",
2010+
enableBackgroundIndexing: true
2011+
)
2012+
2013+
let (uri, positions) = try project.openDocument("LibB.swift")
2014+
let hoverWithMissingDependencyDeclaration = try await project.testClient.send(
2015+
HoverRequest(textDocument: TextDocumentIdentifier(uri), position: positions["1️⃣"])
2016+
)
2017+
XCTAssertNil(hoverWithMissingDependencyDeclaration)
2018+
2019+
let manifestUri = try project.uri(for: "Package.swift")
2020+
try """
2021+
// swift-tools-version: 5.7
2022+
2023+
import PackageDescription
2024+
2025+
let package = Package(
2026+
name: "MyLibrary",
2027+
targets: [
2028+
.target(name: "LibA", swiftSettings: [.define("ENABLE_FOO")]),
2029+
.target(name: "LibB", dependencies: ["LibA"]),
2030+
]
2031+
)
2032+
""".write(to: XCTUnwrap(project.uri(for: "Package.swift").fileURL), atomically: true, encoding: .utf8)
2033+
2034+
project.testClient.send(DidChangeWatchedFilesNotification(changes: [FileEvent(uri: manifestUri, type: .changed)]))
2035+
2036+
try await repeatUntilExpectedResult {
2037+
let hoverAfterAddingDependencyDeclaration = try await project.testClient.send(
2038+
HoverRequest(textDocument: TextDocumentIdentifier(uri), position: positions["1️⃣"])
2039+
)
2040+
return hoverAfterAddingDependencyDeclaration != nil
2041+
}
2042+
}
19802043
}
19812044

19822045
extension HoverResponseContents {

0 commit comments

Comments
 (0)