Skip to content

Commit 89f7613

Browse files
authored
Merge pull request #1952 from bnbarham/cherry-workspace-fixes
[6.1] Allow workspace options to affect build system search
2 parents 2e2ef46 + c670558 commit 89f7613

File tree

50 files changed

+1000
-691
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1000
-691
lines changed

Package.swift

+22-11
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,12 @@ var targets: [Target] = [
8080
"SwiftExtensions",
8181
"ToolchainRegistry",
8282
"TSCExtensions",
83-
.product(name: "SwiftPM-auto", package: "swift-package-manager"),
84-
.product(name: "SwiftPMDataModel-auto", package: "swift-package-manager"),
8583
.product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"),
86-
],
84+
]
85+
+ swiftPMDependency([
86+
.product(name: "SwiftPM-auto", package: "swift-package-manager"),
87+
.product(name: "SwiftPMDataModel-auto", package: "swift-package-manager"),
88+
]),
8789
exclude: ["CMakeLists.txt"],
8890
swiftSettings: globalSwiftSettings
8991
),
@@ -387,8 +389,10 @@ var targets: [Target] = [
387389
.product(name: "IndexStoreDB", package: "indexstore-db"),
388390
.product(name: "Crypto", package: "swift-crypto"),
389391
.product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"),
390-
.product(name: "SwiftPM-auto", package: "swift-package-manager"),
391392
]
393+
+ swiftPMDependency([
394+
.product(name: "SwiftPM-auto", package: "swift-package-manager")
395+
])
392396
+ swiftSyntaxDependencies([
393397
"SwiftBasicFormat", "SwiftDiagnostics", "SwiftIDEUtils", "SwiftParser", "SwiftParserDiagnostics",
394398
"SwiftRefactor", "SwiftSyntax",
@@ -449,8 +453,6 @@ var targets: [Target] = [
449453
"SKUtilities",
450454
"SwiftExtensions",
451455
"TSCExtensions",
452-
.product(name: "SwiftPMDataModel-auto", package: "swift-package-manager"),
453-
.product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"),
454456
],
455457
exclude: ["CMakeLists.txt"],
456458
swiftSettings: globalSwiftSettings
@@ -461,8 +463,6 @@ var targets: [Target] = [
461463
dependencies: [
462464
"SKTestSupport",
463465
"ToolchainRegistry",
464-
.product(name: "SwiftPMDataModel-auto", package: "swift-package-manager"),
465-
.product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"),
466466
],
467467
swiftSettings: globalSwiftSettings
468468
),
@@ -524,6 +524,13 @@ func swiftSyntaxDependencies(_ names: [String]) -> [Target.Dependency] {
524524
}
525525
}
526526

527+
func swiftPMDependency<T>(_ values: [T]) -> [T] {
528+
if noSwiftPMDependency {
529+
return []
530+
}
531+
return values
532+
}
533+
527534
// MARK: - Parse build arguments
528535

529536
func hasEnvironmentVariable(_ name: String) -> Bool {
@@ -558,6 +565,9 @@ var buildDynamicSwiftSyntaxLibrary: Bool { hasEnvironmentVariable("SWIFTSYNTAX_B
558565
/// the `swift test` invocation so that all pre-built modules can be found.
559566
var buildOnlyTests: Bool { hasEnvironmentVariable("SOURCEKIT_LSP_BUILD_ONLY_TESTS") }
560567

568+
/// Build SourceKit-LSP without a dependency on SwiftPM, ie. without support for SwiftPM projects.
569+
var noSwiftPMDependency: Bool { hasEnvironmentVariable("SOURCEKIT_LSP_NO_SWIFTPM_DEPENDENCY") }
570+
561571
// MARK: - Dependencies
562572

563573
// When building with the swift build-script, use local dependencies whose contents are controlled
@@ -570,25 +580,26 @@ var dependencies: [Package.Dependency] {
570580
} else if useLocalDependencies {
571581
return [
572582
.package(path: "../indexstore-db"),
573-
.package(name: "swift-package-manager", path: "../swiftpm"),
574583
.package(path: "../swift-tools-support-core"),
575584
.package(path: "../swift-argument-parser"),
576585
.package(path: "../swift-syntax"),
577586
.package(path: "../swift-crypto"),
578-
]
587+
] + swiftPMDependency([.package(name: "swift-package-manager", path: "../swiftpm")])
579588
} else {
580589
let relatedDependenciesBranch = "release/6.1"
581590

582591
return [
583592
.package(url: "https://github.com/swiftlang/indexstore-db.git", branch: relatedDependenciesBranch),
584-
.package(url: "https://github.com/swiftlang/swift-package-manager.git", branch: relatedDependenciesBranch),
585593
.package(url: "https://github.com/apple/swift-tools-support-core.git", branch: relatedDependenciesBranch),
586594
.package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.4.0"),
587595
.package(url: "https://github.com/swiftlang/swift-syntax.git", branch: relatedDependenciesBranch),
588596
.package(url: "https://github.com/apple/swift-crypto.git", from: "3.0.0"),
589597
// Not a build dependency. Used so the "Format Source Code" command plugin can be used to format sourcekit-lsp
590598
.package(url: "https://github.com/swiftlang/swift-format.git", branch: relatedDependenciesBranch),
591599
]
600+
+ swiftPMDependency([
601+
.package(url: "https://github.com/swiftlang/swift-package-manager.git", branch: relatedDependenciesBranch)
602+
])
592603
}
593604
}
594605

Sources/BuildSystemIntegration/BuildSystemManager.swift

+32-45
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,9 @@ private enum BuildSystemAdapter {
142142
}
143143

144144
private extension BuildSystemSpec {
145-
private static func createBuiltInBuildSystemAdapter(
146-
projectRoot: URL,
145+
private func createBuiltInBuildSystemAdapter(
147146
messagesToSourceKitLSPHandler: any MessageHandler,
148-
buildSystemTestHooks: BuildSystemTestHooks,
147+
buildSystemHooks: BuildSystemHooks,
149148
_ createBuildSystem: @Sendable (_ connectionToSourceKitLSP: any Connection) async throws -> BuiltInBuildSystem?
150149
) async -> BuildSystemAdapter? {
151150
let connectionToSourceKitLSP = LocalConnection(
@@ -164,7 +163,7 @@ private extension BuildSystemSpec {
164163
let buildSystemAdapter = BuiltInBuildSystemAdapter(
165164
underlyingBuildSystem: buildSystem,
166165
connectionToSourceKitLSP: connectionToSourceKitLSP,
167-
buildSystemTestHooks: buildSystemTestHooks
166+
buildSystemHooks: buildSystemHooks
168167
)
169168
let connectionToBuildSystem = LocalConnection(
170169
receiverName: "\(type(of: buildSystem)) for \(projectRoot.lastPathComponent)"
@@ -178,14 +177,15 @@ private extension BuildSystemSpec {
178177
func createBuildSystemAdapter(
179178
toolchainRegistry: ToolchainRegistry,
180179
options: SourceKitLSPOptions,
181-
buildSystemTestHooks testHooks: BuildSystemTestHooks,
180+
buildSystemHooks: BuildSystemHooks,
182181
messagesToSourceKitLSPHandler: any MessageHandler
183182
) async -> BuildSystemAdapter? {
184183
switch self.kind {
185184
case .buildServer:
186185
let buildSystem = await orLog("Creating external build system") {
187186
try await ExternalBuildSystemAdapter(
188187
projectRoot: projectRoot,
188+
configPath: configPath,
189189
messagesToSourceKitLSPHandler: messagesToSourceKitLSPHandler
190190
)
191191
}
@@ -196,40 +196,38 @@ private extension BuildSystemSpec {
196196
logger.log("Created external build server at \(projectRoot)")
197197
return .external(buildSystem)
198198
case .compilationDatabase:
199-
return await Self.createBuiltInBuildSystemAdapter(
200-
projectRoot: projectRoot,
199+
return await createBuiltInBuildSystemAdapter(
201200
messagesToSourceKitLSPHandler: messagesToSourceKitLSPHandler,
202-
buildSystemTestHooks: testHooks
201+
buildSystemHooks: buildSystemHooks
203202
) { connectionToSourceKitLSP in
204-
CompilationDatabaseBuildSystem(
205-
projectRoot: projectRoot,
206-
searchPaths: (options.compilationDatabaseOrDefault.searchPaths ?? []).compactMap {
207-
try? RelativePath(validating: $0)
208-
},
203+
try CompilationDatabaseBuildSystem(
204+
configPath: configPath,
209205
connectionToSourceKitLSP: connectionToSourceKitLSP
210206
)
211207
}
212208
case .swiftPM:
213-
return await Self.createBuiltInBuildSystemAdapter(
214-
projectRoot: projectRoot,
209+
#if canImport(PackageModel)
210+
return await createBuiltInBuildSystemAdapter(
215211
messagesToSourceKitLSPHandler: messagesToSourceKitLSPHandler,
216-
buildSystemTestHooks: testHooks
212+
buildSystemHooks: buildSystemHooks
217213
) { connectionToSourceKitLSP in
218214
try await SwiftPMBuildSystem(
219215
projectRoot: projectRoot,
220216
toolchainRegistry: toolchainRegistry,
221217
options: options,
222218
connectionToSourceKitLSP: connectionToSourceKitLSP,
223-
testHooks: testHooks.swiftPMTestHooks
219+
testHooks: buildSystemHooks.swiftPMTestHooks
224220
)
225221
}
226-
case .testBuildSystem:
227-
return await Self.createBuiltInBuildSystemAdapter(
228-
projectRoot: projectRoot,
222+
#else
223+
return nil
224+
#endif
225+
case .injected(let injector):
226+
return await createBuiltInBuildSystemAdapter(
229227
messagesToSourceKitLSPHandler: messagesToSourceKitLSPHandler,
230-
buildSystemTestHooks: testHooks
228+
buildSystemHooks: buildSystemHooks
231229
) { connectionToSourceKitLSP in
232-
TestBuildSystem(projectRoot: projectRoot, connectionToSourceKitLSP: connectionToSourceKitLSP)
230+
await injector.createBuildSystem(projectRoot: projectRoot, connectionToSourceKitLSP: connectionToSourceKitLSP)
233231
}
234232
}
235233
}
@@ -244,13 +242,14 @@ package actor BuildSystemManager: QueueBasedMessageHandler {
244242

245243
package let messageHandlingQueue = AsyncQueue<BuildSystemMessageDependencyTracker>()
246244

247-
/// The root of the project that this build system manages.
245+
/// The path to the main configuration file (or directory) that this build system manages.
248246
///
249-
/// For example, in SwiftPM packages this is the folder containing Package.swift.
250-
/// For compilation databases it is the root folder based on which the compilation database was found.
247+
/// Some examples:
248+
/// - The path to `Package.swift` for SwiftPM packages
249+
/// - The path to `compile_commands.json` for a JSON compilation database
251250
///
252251
/// `nil` if the `BuildSystemManager` does not have an underlying build system.
253-
package let projectRoot: URL?
252+
package let configPath: URL?
254253

255254
/// The files for which the delegate has requested change notifications, ie. the files for which the delegate wants to
256255
/// get `fileBuildSettingsChanged` and `filesDependenciesUpdated` callbacks.
@@ -271,19 +270,6 @@ package actor BuildSystemManager: QueueBasedMessageHandler {
271270
}
272271
}
273272

274-
/// If the underlying build system is a `TestBuildSystem`, return it. Otherwise, `nil`
275-
///
276-
/// - Important: For testing purposes only.
277-
package var testBuildSystem: TestBuildSystem? {
278-
get async {
279-
switch buildSystemAdapter {
280-
case .builtIn(let builtInBuildSystemAdapter, _): return await builtInBuildSystemAdapter.testBuildSystem
281-
case .external: return nil
282-
case nil: return nil
283-
}
284-
}
285-
}
286-
287273
/// Provider of file to main file mappings.
288274
private var mainFilesProvider: MainFilesProvider?
289275

@@ -363,16 +349,16 @@ package actor BuildSystemManager: QueueBasedMessageHandler {
363349
toolchainRegistry: ToolchainRegistry,
364350
options: SourceKitLSPOptions,
365351
connectionToClient: BuildSystemManagerConnectionToClient,
366-
buildSystemTestHooks: BuildSystemTestHooks
352+
buildSystemHooks: BuildSystemHooks
367353
) async {
368354
self.toolchainRegistry = toolchainRegistry
369355
self.options = options
370356
self.connectionToClient = connectionToClient
371-
self.projectRoot = buildSystemSpec?.projectRoot
357+
self.configPath = buildSystemSpec?.configPath
372358
self.buildSystemAdapter = await buildSystemSpec?.createBuildSystemAdapter(
373359
toolchainRegistry: toolchainRegistry,
374360
options: options,
375-
buildSystemTestHooks: buildSystemTestHooks,
361+
buildSystemHooks: buildSystemHooks,
376362
messagesToSourceKitLSPHandler: WeakMessageHandler(self)
377363
)
378364

@@ -422,13 +408,14 @@ package actor BuildSystemManager: QueueBasedMessageHandler {
422408
logger.log("Launched a legacy BSP server. Using push-based build settings model.")
423409
let legacyBuildServer = await LegacyBuildServerBuildSystem(
424410
projectRoot: buildSystemSpec.projectRoot,
411+
configPath: buildSystemSpec.configPath,
425412
initializationData: initializeResponse,
426413
externalBuildSystemAdapter
427414
)
428415
let adapter = BuiltInBuildSystemAdapter(
429416
underlyingBuildSystem: legacyBuildServer,
430417
connectionToSourceKitLSP: legacyBuildServer.connectionToSourceKitLSP,
431-
buildSystemTestHooks: buildSystemTestHooks
418+
buildSystemHooks: buildSystemHooks
432419
)
433420
let connectionToBuildSystem = LocalConnection(receiverName: "Legacy BSP server")
434421
connectionToBuildSystem.start(handler: adapter)
@@ -688,8 +675,8 @@ package actor BuildSystemManager: QueueBasedMessageHandler {
688675
result.formUnion(targets)
689676
}
690677
if !filesAndDirectories.directories.isEmpty, let documentPathComponents = document.fileURL?.pathComponents {
691-
for (directory, (directoryPathComponents, info)) in filesAndDirectories.directories {
692-
guard let directoryPathComponents, let directoryPath = directory.fileURL else {
678+
for (_, (directoryPathComponents, info)) in filesAndDirectories.directories {
679+
guard let directoryPathComponents else {
693680
continue
694681
}
695682
if isDescendant(documentPathComponents, of: directoryPathComponents) {

Sources/BuildSystemIntegration/BuildSystemTestHooks.swift

+29-4
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,48 @@
1212

1313
#if compiler(>=6)
1414
package import LanguageServerProtocol
15+
package import Foundation
1516
#else
1617
import LanguageServerProtocol
18+
import Foundation
1719
#endif
1820

19-
package struct BuildSystemTestHooks: Sendable {
21+
package struct SwiftPMTestHooks: Sendable {
22+
package var reloadPackageDidStart: (@Sendable () async -> Void)?
23+
package var reloadPackageDidFinish: (@Sendable () async -> Void)?
24+
25+
package init(
26+
reloadPackageDidStart: (@Sendable () async -> Void)? = nil,
27+
reloadPackageDidFinish: (@Sendable () async -> Void)? = nil
28+
) {
29+
self.reloadPackageDidStart = reloadPackageDidStart
30+
self.reloadPackageDidFinish = reloadPackageDidFinish
31+
}
32+
}
33+
34+
/// When running SourceKit-LSP in-process, allows the creator of `SourceKitLSPServer` to create the build system instead
35+
/// of SourceKit-LSP creating build systems as needed.
36+
package protocol BuildSystemInjector: Sendable {
37+
func createBuildSystem(projectRoot: URL, connectionToSourceKitLSP: any Connection) async -> BuiltInBuildSystem
38+
}
39+
40+
package struct BuildSystemHooks: Sendable {
2041
package var swiftPMTestHooks: SwiftPMTestHooks
2142

2243
/// A hook that will be executed before a request is handled by a `BuiltInBuildSystem`.
2344
///
2445
/// This allows requests to be artificially delayed.
25-
package var handleRequest: (@Sendable (any RequestType) async -> Void)?
46+
package var preHandleRequest: (@Sendable (any RequestType) async -> Void)?
47+
48+
package var buildSystemInjector: BuildSystemInjector?
2649

2750
package init(
2851
swiftPMTestHooks: SwiftPMTestHooks = SwiftPMTestHooks(),
29-
handleRequest: (@Sendable (any RequestType) async -> Void)? = nil
52+
preHandleRequest: (@Sendable (any RequestType) async -> Void)? = nil,
53+
buildSystemInjector: BuildSystemInjector? = nil
3054
) {
3155
self.swiftPMTestHooks = swiftPMTestHooks
32-
self.handleRequest = handleRequest
56+
self.preHandleRequest = preHandleRequest
57+
self.buildSystemInjector = buildSystemInjector
3358
}
3459
}

0 commit comments

Comments
 (0)