diff --git a/Sources/SKSwiftPMWorkspace/SwiftPMBuildSystem.swift b/Sources/SKSwiftPMWorkspace/SwiftPMBuildSystem.swift index bd9df1e0d..2690a39e9 100644 --- a/Sources/SKSwiftPMWorkspace/SwiftPMBuildSystem.swift +++ b/Sources/SKSwiftPMWorkspace/SwiftPMBuildSystem.swift @@ -400,7 +400,7 @@ extension SwiftPMBuildSystem { ) self.fileToTargets = [DocumentURI: [SwiftBuildTarget]]( - modulesGraph.allTargets.flatMap { target in + modulesGraph.allModules.flatMap { target in return target.sources.paths.compactMap { (filePath) -> (key: DocumentURI, value: [SwiftBuildTarget])? in guard let buildTarget = buildDescription.getBuildTarget(for: target, in: modulesGraph) else { return nil @@ -412,7 +412,7 @@ extension SwiftPMBuildSystem { ) self.sourceDirToTargets = [DocumentURI: [SwiftBuildTarget]]( - modulesGraph.allTargets.compactMap { (target) -> (DocumentURI, [SwiftBuildTarget])? in + modulesGraph.allModules.compactMap { (target) -> (DocumentURI, [SwiftBuildTarget])? in guard let buildTarget = buildDescription.getBuildTarget(for: target, in: modulesGraph) else { return nil } @@ -545,7 +545,9 @@ extension SwiftPMBuildSystem: SKCore.BuildSystem { return targets.map(ConfiguredTarget.init) } - if path.basename == "Package.swift" { + if path.basename == "Package.swift" + && projectRoot == (try? TSCBasic.resolveSymlinks(TSCBasic.AbsolutePath(path.parentDirectory))) + { // We use an empty target name to represent the package manifest since an empty target name is not valid for any // user-defined target. return [ConfiguredTarget.forPackageManifest] diff --git a/Tests/SourceKitLSPTests/WorkspaceTests.swift b/Tests/SourceKitLSPTests/WorkspaceTests.swift index 5542c44f1..6a81b2338 100644 --- a/Tests/SourceKitLSPTests/WorkspaceTests.swift +++ b/Tests/SourceKitLSPTests/WorkspaceTests.swift @@ -191,6 +191,49 @@ final class WorkspaceTests: XCTestCase { XCTAssertEqual(diags, .full(RelatedFullDocumentDiagnosticReport(items: []))) } + func testCorrectWorkspaceForPackageSwiftInMultiSwiftPMWorkspaceSetup() async throws { + let project = try await MultiFileTestProject( + files: [ + // PackageA + "PackageA/Sources/MyLibrary/libA.swift": "", + "PackageA/Package.swift": SwiftPMTestProject.defaultPackageManifest, + + // PackageB + "PackageB/Sources/MyLibrary/libB.swift": "", + "PackageB/Package.swift": SwiftPMTestProject.defaultPackageManifest, + ], + workspaces: { scratchDir in + return [ + WorkspaceFolder(uri: DocumentURI(scratchDir)), + WorkspaceFolder(uri: DocumentURI(scratchDir.appendingPathComponent("PackageA"))), + WorkspaceFolder(uri: DocumentURI(scratchDir.appendingPathComponent("PackageB"))), + ] + } + ) + + let pkgA = DocumentURI( + project.scratchDirectory + .appendingPathComponent("PackageA") + .appendingPathComponent("Package.swift") + ) + + let pkgB = DocumentURI( + project.scratchDirectory + .appendingPathComponent("PackageB") + .appendingPathComponent("Package.swift") + ) + + assertEqual( + await project.testClient.server.workspaceForDocument(uri: pkgA)?.rootUri, + DocumentURI(project.scratchDirectory.appendingPathComponent("PackageA")) + ) + + assertEqual( + await project.testClient.server.workspaceForDocument(uri: pkgB)?.rootUri, + DocumentURI(project.scratchDirectory.appendingPathComponent("PackageB")) + ) + } + func testSwiftPMPackageInSubfolder() async throws { let packageManifest = """ // swift-tools-version: 5.7