Skip to content

Commit f830432

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 aca98d3 commit f830432

File tree

2 files changed

+48
-3
lines changed

2 files changed

+48
-3
lines changed

Sources/SKSwiftPMWorkspace/SwiftPMBuildSystem.swift

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

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

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

548-
if path.basename == "Package.swift" {
548+
if path.basename == "Package.swift"
549+
&& projectRoot == (try? TSCBasic.resolveSymlinks(TSCBasic.AbsolutePath(path.parentDirectory)))
550+
{
549551
// We use an empty target name to represent the package manifest since an empty target name is not valid for any
550552
// user-defined target.
551553
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)