Skip to content

Commit 490871b

Browse files
authored
Merge pull request #1307 from ahoppen/background-prepare-targets
When interacting with a document, prepare the target it belongs to
2 parents 012a64f + 7208376 commit 490871b

File tree

7 files changed

+265
-81
lines changed

7 files changed

+265
-81
lines changed

Sources/SKCore/BuildSystem.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import BuildServerProtocol
14+
import LSPLogging
1415
import LanguageServerProtocol
1516

1617
import struct TSCBasic.AbsolutePath
@@ -50,7 +51,7 @@ public struct SourceFileInfo: Sendable {
5051

5152
/// A target / run destination combination. For example, a configured target can represent building the target
5253
/// `MyLibrary` for iOS.
53-
public struct ConfiguredTarget: Hashable, Sendable {
54+
public struct ConfiguredTarget: Hashable, Sendable, CustomLogStringConvertible {
5455
/// An opaque string that represents the target.
5556
///
5657
/// The target's ID should be generated by the build system that handles the target and only interpreted by that
@@ -67,6 +68,14 @@ public struct ConfiguredTarget: Hashable, Sendable {
6768
self.targetID = targetID
6869
self.runDestinationID = runDestinationID
6970
}
71+
72+
public var description: String {
73+
"\(targetID)-\(runDestinationID)"
74+
}
75+
76+
public var redactedDescription: String {
77+
"\(targetID.hashForLogging)-\(runDestinationID.hashForLogging)"
78+
}
7079
}
7180

7281
/// An error build systems can throw from `prepare` if they don't support preparation of targets.

Sources/SKSwiftPMWorkspace/SwiftPMBuildSystem.swift

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,9 @@ public actor SwiftPMBuildSystem {
128128
logger.log(level: diagnostic.severity.asLogLevel, "SwiftPM log: \(diagnostic.description)")
129129
})
130130

131-
/// Whether the SwiftPMBuildSystem may modify `Package.resolved` or not.
132-
///
133-
/// This is `false` if the `SwiftPMBuildSystem` is pointed at a `.index-build` directory that's independent of the
134-
/// user's build. In this case `SwiftPMBuildSystem` is allowed to clone repositories even if no `Package.resolved`
135-
/// exists.
136-
private let forceResolvedVersions: Bool
131+
/// Whether the `SwiftPMBuildSystem` is pointed at a `.index-build` directory that's independent of the
132+
/// user's build.
133+
private let isForIndexBuild: Bool
137134

138135
/// Creates a build system using the Swift Package Manager, if this workspace is a package.
139136
///
@@ -148,13 +145,13 @@ public actor SwiftPMBuildSystem {
148145
toolchainRegistry: ToolchainRegistry,
149146
fileSystem: FileSystem = localFileSystem,
150147
buildSetup: BuildSetup,
151-
forceResolvedVersions: Bool,
148+
isForIndexBuild: Bool,
152149
reloadPackageStatusCallback: @escaping (ReloadPackageStatus) async -> Void = { _ in }
153150
) async throws {
154151
self.workspacePath = workspacePath
155152
self.fileSystem = fileSystem
156153
self.toolchainRegistry = toolchainRegistry
157-
self.forceResolvedVersions = forceResolvedVersions
154+
self.isForIndexBuild = isForIndexBuild
158155

159156
guard let packageRoot = findPackageDirectory(containing: workspacePath, fileSystem) else {
160157
throw Error.noManifest(workspacePath: workspacePath)
@@ -234,7 +231,7 @@ public actor SwiftPMBuildSystem {
234231
url: URL,
235232
toolchainRegistry: ToolchainRegistry,
236233
buildSetup: BuildSetup,
237-
forceResolvedVersions: Bool,
234+
isForIndexBuild: Bool,
238235
reloadPackageStatusCallback: @escaping (ReloadPackageStatus) async -> Void
239236
) async {
240237
do {
@@ -243,7 +240,7 @@ public actor SwiftPMBuildSystem {
243240
toolchainRegistry: toolchainRegistry,
244241
fileSystem: localFileSystem,
245242
buildSetup: buildSetup,
246-
forceResolvedVersions: forceResolvedVersions,
243+
isForIndexBuild: isForIndexBuild,
247244
reloadPackageStatusCallback: reloadPackageStatusCallback
248245
)
249246
} catch Error.noManifest {
@@ -272,7 +269,7 @@ extension SwiftPMBuildSystem {
272269

273270
let modulesGraph = try self.workspace.loadPackageGraph(
274271
rootInput: PackageGraphRootInput(packages: [AbsolutePath(projectRoot)]),
275-
forceResolvedVersions: forceResolvedVersions,
272+
forceResolvedVersions: !isForIndexBuild,
276273
observabilityScope: observabilitySystem.topScope
277274
)
278275

@@ -430,6 +427,8 @@ extension SwiftPMBuildSystem: SKCore.BuildSystem {
430427
for target in targets {
431428
try await prepare(singleTarget: target)
432429
}
430+
let filesInPreparedTargets = targets.flatMap { self.targets[$0.targetID]?.buildTarget.sources ?? [] }
431+
await fileDependenciesUpdatedDebouncer.scheduleCall(Set(filesInPreparedTargets.map(DocumentURI.init)))
433432
}
434433

435434
private func prepare(singleTarget target: ConfiguredTarget) async throws {
@@ -561,9 +560,9 @@ extension SwiftPMBuildSystem: SKCore.BuildSystem {
561560
// The file watching here is somewhat fragile as well because it assumes that the `.swiftmodule` files are being
562561
// written to a directory within the workspace root. This is not necessarily true if the user specifies a build
563562
// directory outside the source tree.
564-
// All of this shouldn't be necessary once we have background preparation, in which case we know when preparation of
565-
// a target has finished.
566-
if events.contains(where: { $0.uri.fileURL?.pathExtension == "swiftmodule" }) {
563+
// If we have background indexing enabled, this is not necessary because we call `fileDependenciesUpdated` when
564+
// preparation of a target finishes.
565+
if !isForIndexBuild, events.contains(where: { $0.uri.fileURL?.pathExtension == "swiftmodule" }) {
567566
filesWithUpdatedDependencies.formUnion(self.fileToTarget.keys.map { DocumentURI($0.asURL) })
568567
}
569568
await self.fileDependenciesUpdatedDebouncer.scheduleCall(filesWithUpdatedDependencies)

0 commit comments

Comments
 (0)