Skip to content

Commit e15bdd7

Browse files
committed
Review SwiftPMBuildSystem.swift
1 parent 2c2d9f9 commit e15bdd7

File tree

5 files changed

+75
-130
lines changed

5 files changed

+75
-130
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
package struct BuildSystemTestHooks: Sendable {
14+
package var swiftPMTestHooks: SwiftPMTestHooks
15+
16+
package init(swiftPMTestHooks: SwiftPMTestHooks = SwiftPMTestHooks()) {
17+
self.swiftPMTestHooks = swiftPMTestHooks
18+
}
19+
}

Sources/BuildSystemIntegration/BuiltInBuildSystemAdapter.swift

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,15 @@ private func createBuildSystem(
5858
connectionToSourceKitLSP: connectionToSourceKitLSP
5959
)
6060
case .swiftPM(let projectRoot):
61-
return await SwiftPMBuildSystem(
62-
projectRoot: projectRoot,
63-
toolchainRegistry: toolchainRegistry,
64-
options: options,
65-
connectionToSourceKitLSP: connectionToSourceKitLSP,
66-
testHooks: buildSystemTestHooks.swiftPMTestHooks
67-
)
61+
return await orLog("Creating SwiftPMBuildSystem") {
62+
return try await SwiftPMBuildSystem(
63+
projectRoot: projectRoot,
64+
toolchainRegistry: toolchainRegistry,
65+
options: options,
66+
connectionToSourceKitLSP: connectionToSourceKitLSP,
67+
testHooks: buildSystemTestHooks.swiftPMTestHooks
68+
)
69+
}
6870
case .testBuildSystem(let projectRoot):
6971
return TestBuildSystem(projectRoot: projectRoot, connectionToSourceKitLSP: connectionToSourceKitLSP)
7072
}

Sources/BuildSystemIntegration/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ add_library(BuildSystemIntegration STATIC
55
BuildSystemManager.swift
66
BuildSystemManagerDelegate.swift
77
BuildSystemMessageDependencyTracker.swift
8+
BuildSystemTestHooks.swift
89
BuildTargetIdentifierExtensions.swift
910
BuiltInBuildSystem.swift
1011
BuiltInBuildSystemAdapter.swift

Sources/BuildSystemIntegration/SwiftPMBuildSystem.swift

Lines changed: 32 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,16 @@ package typealias SwiftBuildTarget = SourceKitLSPAPI.BuildTarget
5151
/// A build target in `BuildServerProtocol`
5252
package typealias BuildServerTarget = BuildServerProtocol.BuildTarget
5353

54+
fileprivate extension Basics.Diagnostic.Severity {
55+
var asLogLevel: LogLevel {
56+
switch self {
57+
case .error, .warning: return .default
58+
case .info: return .info
59+
case .debug: return .debug
60+
}
61+
}
62+
}
63+
5464
fileprivate extension BuildDestination {
5565
/// A string that can be used to identify the build triple in a `BuildTargetIdentifier`.
5666
///
@@ -132,14 +142,6 @@ fileprivate extension TSCBasic.AbsolutePath {
132142

133143
fileprivate let preparationTaskID: AtomicUInt32 = AtomicUInt32(initialValue: 0)
134144

135-
package struct BuildSystemTestHooks: Sendable {
136-
package var swiftPMTestHooks: SwiftPMTestHooks
137-
138-
package init(swiftPMTestHooks: SwiftPMTestHooks = SwiftPMTestHooks()) {
139-
self.swiftPMTestHooks = swiftPMTestHooks
140-
}
141-
}
142-
143145
package struct SwiftPMTestHooks: Sendable {
144146
package var reloadPackageDidStart: (@Sendable () async -> Void)?
145147
package var reloadPackageDidFinish: (@Sendable () async -> Void)?
@@ -155,14 +157,11 @@ package struct SwiftPMTestHooks: Sendable {
155157

156158
/// Swift Package Manager build system and workspace support.
157159
///
158-
/// This class implements the `BuildSystem` interface to provide the build settings for a Swift
160+
/// This class implements the `BuiltInBuildSystem` interface to provide the build settings for a Swift
159161
/// Package Manager (SwiftPM) package. The settings are determined by loading the Package.swift
160162
/// manifest using `libSwiftPM` and constructing a build plan using the default (debug) parameters.
161-
package actor SwiftPMBuildSystem {
163+
package actor SwiftPMBuildSystem: BuiltInBuildSystem {
162164
package enum Error: Swift.Error {
163-
/// Could not find a manifest (Package.swift file). This is not a package.
164-
case noManifest(workspacePath: TSCAbsolutePath)
165-
166165
/// Could not determine an appropriate toolchain for swiftpm to use for manifest loading.
167166
case cannotDetermineHostToolchain
168167
}
@@ -192,9 +191,8 @@ package actor SwiftPMBuildSystem {
192191
package let toolsBuildParameters: BuildParameters
193192
package let destinationBuildParameters: BuildParameters
194193

195-
private let fileSystem: FileSystem
196194
private let toolchain: Toolchain
197-
private let workspace: Workspace
195+
private let swiftPMWorkspace: Workspace
198196

199197
/// A `ObservabilitySystem` from `SwiftPM` that logs.
200198
private let observabilitySystem = ObservabilitySystem({ scope, diagnostic in
@@ -248,14 +246,12 @@ package actor SwiftPMBuildSystem {
248246
package init(
249247
projectRoot: TSCAbsolutePath,
250248
toolchainRegistry: ToolchainRegistry,
251-
fileSystem: FileSystem = localFileSystem,
252249
options: SourceKitLSPOptions,
253250
connectionToSourceKitLSP: any Connection,
254251
testHooks: SwiftPMTestHooks
255252
) async throws {
256253
self.projectRoot = projectRoot
257254
self.options = options
258-
self.fileSystem = fileSystem
259255
let toolchain = await toolchainRegistry.preferredToolchain(containing: [
260256
\.clang, \.clangd, \.sourcekitd, \.swift, \.swiftc,
261257
])
@@ -280,22 +276,22 @@ package actor SwiftPMBuildSystem {
280276
customCompileTriple: options.swiftPMOrDefault.triple.map { try Triple($0) },
281277
swiftSDKSelector: options.swiftPMOrDefault.swiftSDK,
282278
store: SwiftSDKBundleStore(
283-
swiftSDKsDirectory: fileSystem.getSharedSwiftSDKsDirectory(
279+
swiftSDKsDirectory: localFileSystem.getSharedSwiftSDKsDirectory(
284280
explicitDirectory: options.swiftPMOrDefault.swiftSDKsDirectory.map { try AbsolutePath(validating: $0) }
285281
),
286-
fileSystem: fileSystem,
282+
fileSystem: localFileSystem,
287283
observabilityScope: observabilitySystem.topScope,
288284
outputHandler: { _ in }
289285
),
290286
observabilityScope: observabilitySystem.topScope,
291-
fileSystem: fileSystem
287+
fileSystem: localFileSystem
292288
)
293289

294290
let destinationSwiftPMToolchain = try UserToolchain(swiftSDK: destinationSDK)
295291

296292
var location = try Workspace.Location(
297293
forRootPackage: AbsolutePath(projectRoot),
298-
fileSystem: fileSystem
294+
fileSystem: localFileSystem
299295
)
300296
if options.backgroundIndexingOrDefault {
301297
location.scratchDirectory = AbsolutePath(projectRoot.appending(component: ".index-build"))
@@ -308,8 +304,8 @@ package actor SwiftPMBuildSystem {
308304
var configuration = WorkspaceConfiguration.default
309305
configuration.skipDependenciesUpdates = true
310306

311-
self.workspace = try Workspace(
312-
fileSystem: fileSystem,
307+
self.swiftPMWorkspace = try Workspace(
308+
fileSystem: localFileSystem,
313309
location: location,
314310
configuration: configuration,
315311
customHostToolchain: hostSwiftPMToolchain,
@@ -367,35 +363,6 @@ package actor SwiftPMBuildSystem {
367363
}
368364
}
369365

370-
/// Creates a build system using the Swift Package Manager, if this workspace is a package.
371-
///
372-
/// - Returns: nil if `workspacePath` is not part of a package or there is an error.
373-
package init?(
374-
projectRoot: TSCBasic.AbsolutePath,
375-
toolchainRegistry: ToolchainRegistry,
376-
options: SourceKitLSPOptions,
377-
connectionToSourceKitLSP: any Connection,
378-
testHooks: SwiftPMTestHooks
379-
) async {
380-
do {
381-
try await self.init(
382-
projectRoot: projectRoot,
383-
toolchainRegistry: toolchainRegistry,
384-
fileSystem: localFileSystem,
385-
options: options,
386-
connectionToSourceKitLSP: connectionToSourceKitLSP,
387-
testHooks: testHooks
388-
)
389-
} catch Error.noManifest {
390-
return nil
391-
} catch {
392-
logger.error("Failed to create SwiftPMWorkspace at \(projectRoot.pathString): \(error.forLogging)")
393-
return nil
394-
}
395-
}
396-
}
397-
398-
extension SwiftPMBuildSystem {
399366
/// (Re-)load the package settings by parsing the manifest and resolving all the targets and
400367
/// dependencies.
401368
///
@@ -416,7 +383,7 @@ extension SwiftPMBuildSystem {
416383
}
417384
}
418385

419-
let modulesGraph = try await self.workspace.loadPackageGraph(
386+
let modulesGraph = try await self.swiftPMWorkspace.loadPackageGraph(
420387
rootInput: PackageGraphRootInput(packages: [AbsolutePath(projectRoot)]),
421388
forceResolvedVersions: !isForIndexBuild,
422389
observabilityScope: observabilitySystem.topScope
@@ -427,7 +394,7 @@ extension SwiftPMBuildSystem {
427394
toolsBuildParameters: toolsBuildParameters,
428395
graph: modulesGraph,
429396
disableSandbox: options.swiftPMOrDefault.disableSandbox ?? false,
430-
fileSystem: fileSystem,
397+
fileSystem: localFileSystem,
431398
observabilityScope: observabilitySystem.topScope
432399
)
433400
let buildDescription = BuildDescription(buildPlan: plan)
@@ -461,16 +428,7 @@ extension SwiftPMBuildSystem {
461428

462429
connectionToSourceKitLSP.send(OnBuildTargetDidChangeNotification(changes: nil))
463430
}
464-
}
465-
466-
fileprivate struct NonFileURIError: Error, CustomStringConvertible {
467-
let uri: DocumentURI
468-
var description: String {
469-
"Trying to get build settings for non-file URI: \(uri)"
470-
}
471-
}
472431

473-
extension SwiftPMBuildSystem: BuildSystemIntegration.BuiltInBuildSystem {
474432
package nonisolated var supportsPreparation: Bool { true }
475433

476434
package var buildPath: TSCAbsolutePath {
@@ -490,6 +448,13 @@ extension SwiftPMBuildSystem: BuildSystemIntegration.BuiltInBuildSystem {
490448
/// account for differences in the SwiftPM versions being linked into SwiftPM and being installed in the toolchain.
491449
private func compilerArguments(for file: DocumentURI, in buildTarget: any SwiftBuildTarget) async throws -> [String] {
492450
guard let fileURL = file.fileURL else {
451+
struct NonFileURIError: Swift.Error, CustomStringConvertible {
452+
let uri: DocumentURI
453+
var description: String {
454+
"Trying to get build settings for non-file URI: \(uri)"
455+
}
456+
}
457+
493458
throw NonFileURIError(uri: file)
494459
}
495460
let compileArguments = try buildTarget.compileArguments(for: fileURL)
@@ -504,7 +469,7 @@ extension SwiftPMBuildSystem: BuildSystemIntegration.BuiltInBuildSystem {
504469
return compileArguments
505470
}
506471
return compileArguments.map { argument in
507-
if argument.hasSuffix("/Modules"), argument.contains(self.workspace.location.scratchDirectory.pathString) {
472+
if argument.hasSuffix("/Modules"), argument.contains(self.swiftPMWorkspace.location.scratchDirectory.pathString) {
508473
return String(argument.dropLast(8))
509474
}
510475
return argument
@@ -596,7 +561,7 @@ extension SwiftPMBuildSystem: BuildSystemIntegration.BuiltInBuildSystem {
596561
}
597562

598563
guard let swiftPMTarget = self.swiftPMTargets[request.target] else {
599-
logger.fault("Did not find target \(request.target.forLogging)")
564+
logger.error("Did not find target \(request.target.forLogging)")
600565
return nil
601566
}
602567

@@ -642,8 +607,6 @@ extension SwiftPMBuildSystem: BuildSystemIntegration.BuiltInBuildSystem {
642607
if path.basename == "Package.swift"
643608
&& projectRoot == (try? TSCBasic.resolveSymlinks(TSCBasic.AbsolutePath(path.parentDirectory)))
644609
{
645-
// We use an empty target name to represent the package manifest since an empty target name is not valid for any
646-
// user-defined target.
647610
return [BuildTargetIdentifier.forPackageManifest]
648611
}
649612

@@ -675,7 +638,6 @@ extension SwiftPMBuildSystem: BuildSystemIntegration.BuiltInBuildSystem {
675638
return
676639
}
677640

678-
// TODO: Add a proper 'prepare' job in SwiftPM instead of building the target. (https://github.com/swiftlang/sourcekit-lsp/issues/1254)
679641
guard let swift = toolchain.swift else {
680642
logger.error(
681643
"Not preparing because toolchain at \(self.toolchain.identifier) does not contain a Swift compiler"
@@ -686,7 +648,7 @@ extension SwiftPMBuildSystem: BuildSystemIntegration.BuiltInBuildSystem {
686648
var arguments = [
687649
swift.pathString, "build",
688650
"--package-path", projectRoot.pathString,
689-
"--scratch-path", self.workspace.location.scratchDirectory.pathString,
651+
"--scratch-path", self.swiftPMWorkspace.location.scratchDirectory.pathString,
690652
"--disable-index-store",
691653
"--target", try target.targetProperties.target,
692654
]
@@ -810,17 +772,7 @@ extension SwiftPMBuildSystem: BuildSystemIntegration.BuiltInBuildSystem {
810772

811773
/// Retrieve settings for a package manifest (Package.swift).
812774
private func settings(forPackageManifest path: AbsolutePath) throws -> TextDocumentSourceKitOptionsResponse? {
813-
let compilerArgs = workspace.interpreterFlags(for: path.parentDirectory) + [path.pathString]
775+
let compilerArgs = swiftPMWorkspace.interpreterFlags(for: path.parentDirectory) + [path.pathString]
814776
return TextDocumentSourceKitOptionsResponse(compilerArguments: compilerArgs)
815777
}
816778
}
817-
818-
extension Basics.Diagnostic.Severity {
819-
var asLogLevel: LogLevel {
820-
switch self {
821-
case .error, .warning: return .default
822-
case .info: return .info
823-
case .debug: return .debug
824-
}
825-
}
826-
}

0 commit comments

Comments
 (0)