Skip to content

Commit ecffdf0

Browse files
committed
Fix incorrect ConfiguredTargets for Package.swift w/ multiple workspaces
In a project with multiple folders each containing a Package.swift, the `bestWorkspace` found in `workspaceForDocument(uri:)` was always the first one encountered. `fileHandlingCapability(for:)` checks if there are configured targets for the Package.swift and if there are, the workspace is chosen since the Package.swift is determined to be part of the workspace. However the check in `configuredTargets(for:)` always returned a target for any `Package.swift`, even if that `Package.swift` was not part of the workspace associated with the BuildSystem. Ultimately this manifested as code completion not working in all but one of the Package.swift files in a multi workspace project. Some work was done in #1210 to address swiftlang/vscode-swift#768, which is where this issue originated from. However while verifying swiftlang/vscode-swift#768 I found that #1210 didn't fully address code completion of `Package.swift` files in multi workspace projects.
1 parent 91c55f9 commit ecffdf0

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
lines changed

Sources/SKSwiftPMWorkspace/SwiftPMBuildSystem.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ extension SwiftPMBuildSystem {
399399
)
400400

401401
self.fileToTargets = [DocumentURI: [SwiftBuildTarget]](
402-
modulesGraph.allTargets.flatMap { target in
402+
modulesGraph.allModules.flatMap { target in
403403
return target.sources.paths.compactMap { (filePath) -> (key: DocumentURI, value: [SwiftBuildTarget])? in
404404
guard let buildTarget = buildDescription.getBuildTarget(for: target, in: modulesGraph) else {
405405
return nil
@@ -411,7 +411,7 @@ extension SwiftPMBuildSystem {
411411
)
412412

413413
self.sourceDirToTargets = [DocumentURI: [SwiftBuildTarget]](
414-
modulesGraph.allTargets.compactMap { (target) -> (DocumentURI, [SwiftBuildTarget])? in
414+
modulesGraph.allModules.compactMap { (target) -> (DocumentURI, [SwiftBuildTarget])? in
415415
guard let buildTarget = buildDescription.getBuildTarget(for: target, in: modulesGraph) else {
416416
return nil
417417
}
@@ -544,7 +544,7 @@ extension SwiftPMBuildSystem: SKCore.BuildSystem {
544544
return targets.map(ConfiguredTarget.init)
545545
}
546546

547-
if path.basename == "Package.swift" {
547+
if path.basename == "Package.swift" && AbsolutePath(projectRoot) == path.parentDirectory {
548548
// We use an empty target name to represent the package manifest since an empty target name is not valid for any
549549
// user-defined target.
550550
return [ConfiguredTarget.forPackageManifest]

Tests/SourceKitLSPTests/WorkspaceTests.swift

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,49 @@ final class WorkspaceTests: XCTestCase {
191191
XCTAssertEqual(diags, .full(RelatedFullDocumentDiagnosticReport(items: [])))
192192
}
193193

194+
func testCorrectWorkspaceForPackageSwiftInMultiSwiftPMWorkspaceSetup() async throws {
195+
let project = try await MultiFileTestProject(
196+
files: [
197+
// PackageA
198+
"PackageA/Sources/MyLibrary/libA.swift": "",
199+
"PackageA/Package.swift": SwiftPMTestProject.defaultPackageManifest,
200+
201+
// PackageB
202+
"PackageB/Sources/MyLibrary/libB.swift": "",
203+
"PackageB/Package.swift": SwiftPMTestProject.defaultPackageManifest,
204+
],
205+
workspaces: { scratchDir in
206+
return [
207+
WorkspaceFolder(uri: DocumentURI(scratchDir)),
208+
WorkspaceFolder(uri: DocumentURI(scratchDir.appendingPathComponent("PackageA"))),
209+
WorkspaceFolder(uri: DocumentURI(scratchDir.appendingPathComponent("PackageB"))),
210+
]
211+
}
212+
)
213+
214+
let pkgA = DocumentURI(
215+
project.scratchDirectory
216+
.appendingPathComponent("PackageA")
217+
.appendingPathComponent("Package.swift")
218+
)
219+
220+
let pkgB = DocumentURI(
221+
project.scratchDirectory
222+
.appendingPathComponent("PackageB")
223+
.appendingPathComponent("Package.swift")
224+
)
225+
226+
assertEqual(
227+
await project.testClient.server.workspaceForDocument(uri: pkgA)?.rootUri,
228+
DocumentURI(project.scratchDirectory.appendingPathComponent("PackageA"))
229+
)
230+
231+
assertEqual(
232+
await project.testClient.server.workspaceForDocument(uri: pkgB)?.rootUri,
233+
DocumentURI(project.scratchDirectory.appendingPathComponent("PackageB"))
234+
)
235+
}
236+
194237
func testSwiftPMPackageInSubfolder() async throws {
195238
let packageManifest = """
196239
// swift-tools-version: 5.7

0 commit comments

Comments
 (0)