Skip to content

Commit b691da0

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 d090fb0 commit b691da0

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
@@ -425,6 +425,38 @@ package final actor SemanticIndexManager {
425425
)
426426
}
427427

428+
package func buildTargetsChanged(_ changes: [BuildTargetEvent]?) async {
429+
let targets = changes?.map(\.target)
430+
431+
if let targets {
432+
var targetsAndDependencies = targets
433+
targetsAndDependencies += await buildSystemManager.targets(dependingOn: Set(targets))
434+
if !targetsAndDependencies.isEmpty {
435+
logger.info(
436+
"""
437+
Marking dependent targets as out-of-date: \
438+
\(String(targetsAndDependencies.map(\.uri.stringValue).joined(separator: ", ")))
439+
"""
440+
)
441+
await preparationUpToDateTracker.markOutOfDate(targetsAndDependencies)
442+
}
443+
} else {
444+
await preparationUpToDateTracker.markAllKnownOutOfDate()
445+
}
446+
447+
await orLog("Scheduling re-indexing of changed targets") {
448+
var sourceFiles = try await self.buildSystemManager.sourceFiles(includeNonBuildableFiles: false)
449+
if let targets {
450+
sourceFiles = sourceFiles.filter { !$0.value.targets.intersection(targets).isEmpty }
451+
}
452+
_ = await scheduleIndexing(
453+
of: sourceFiles.keys,
454+
indexFilesWithUpToDateUnit: false,
455+
priority: .low
456+
)
457+
}
458+
}
459+
428460
/// Returns the files that should be indexed to get up-to-date index information for the given files.
429461
///
430462
/// 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
@@ -433,20 +433,7 @@ package final class Workspace: Sendable, BuildSystemManagerDelegate {
433433

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

Tests/SourceKitLSPTests/BackgroundIndexingTests.swift

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1950,6 +1950,69 @@ final class BackgroundIndexingTests: XCTestCase {
19501950
return true
19511951
}
19521952
}
1953+
1954+
func testRePrepareTargetsWhenBuildServerChanges() async throws {
1955+
let project = try await SwiftPMTestProject(
1956+
files: [
1957+
"LibA/LibA.swift": """
1958+
#if ENABLE_FOO
1959+
public func foo() {}
1960+
#endif
1961+
""",
1962+
"LibB/LibB.swift": """
1963+
import LibA
1964+
1965+
func test() {
1966+
1️⃣foo()
1967+
}
1968+
""",
1969+
],
1970+
manifest: """
1971+
// swift-tools-version: 5.7
1972+
1973+
import PackageDescription
1974+
1975+
let package = Package(
1976+
name: "MyLibrary",
1977+
targets: [
1978+
.target(name: "LibA"),
1979+
.target(name: "LibB", dependencies: ["LibA"]),
1980+
]
1981+
)
1982+
""",
1983+
enableBackgroundIndexing: true
1984+
)
1985+
1986+
let (uri, positions) = try project.openDocument("LibB.swift")
1987+
let hoverWithMissingDependencyDeclaration = try await project.testClient.send(
1988+
HoverRequest(textDocument: TextDocumentIdentifier(uri), position: positions["1️⃣"])
1989+
)
1990+
XCTAssertNil(hoverWithMissingDependencyDeclaration)
1991+
1992+
let manifestUri = try project.uri(for: "Package.swift")
1993+
try """
1994+
// swift-tools-version: 5.7
1995+
1996+
import PackageDescription
1997+
1998+
let package = Package(
1999+
name: "MyLibrary",
2000+
targets: [
2001+
.target(name: "LibA", swiftSettings: [.define("ENABLE_FOO")]),
2002+
.target(name: "LibB", dependencies: ["LibA"]),
2003+
]
2004+
)
2005+
""".write(to: XCTUnwrap(project.uri(for: "Package.swift").fileURL), atomically: true, encoding: .utf8)
2006+
2007+
project.testClient.send(DidChangeWatchedFilesNotification(changes: [FileEvent(uri: manifestUri, type: .changed)]))
2008+
2009+
try await repeatUntilExpectedResult {
2010+
let hoverAfterAddingDependencyDeclaration = try await project.testClient.send(
2011+
HoverRequest(textDocument: TextDocumentIdentifier(uri), position: positions["1️⃣"])
2012+
)
2013+
return hoverAfterAddingDependencyDeclaration != nil
2014+
}
2015+
}
19532016
}
19542017

19552018
extension HoverResponseContents {

0 commit comments

Comments
 (0)