Skip to content

Commit 9aa348e

Browse files
authored
Report whether a target is part of the root package in the sourcekit-lsp API (#7492)
This is used so we don’t search for tests in targets of package dependencies. Companion of swiftlang/sourcekit-lsp#1201 rdar://126965614
1 parent 8db2401 commit 9aa348e

File tree

3 files changed

+44
-14
lines changed

3 files changed

+44
-14
lines changed

Sources/SourceKitLSPAPI/BuildDescription.swift

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,31 +22,45 @@ import class Build.BuildPlan
2222
import class Build.ClangTargetBuildDescription
2323
import class Build.SwiftTargetBuildDescription
2424
import struct PackageGraph.ResolvedModule
25+
import struct PackageGraph.ModulesGraph
2526

2627
public protocol BuildTarget {
2728
var sources: [URL] { get }
2829

30+
/// Whether the target is part of the root package that the user opened or if it's part of a package dependency.
31+
var isPartOfRootPackage: Bool { get }
32+
2933
func compileArguments(for fileURL: URL) throws -> [String]
30-
}
34+
}
35+
36+
private struct WrappedClangTargetBuildDescription: BuildTarget {
37+
private let description: ClangTargetBuildDescription
38+
let isPartOfRootPackage: Bool
39+
40+
init(description: ClangTargetBuildDescription, isPartOfRootPackage: Bool) {
41+
self.description = description
42+
self.isPartOfRootPackage = isPartOfRootPackage
43+
}
3144

32-
extension ClangTargetBuildDescription: BuildTarget {
3345
public var sources: [URL] {
34-
return (try? compilePaths().map { URL(fileURLWithPath: $0.source.pathString) }) ?? []
46+
return (try? description.compilePaths().map { URL(fileURLWithPath: $0.source.pathString) }) ?? []
3547
}
3648

3749
public func compileArguments(for fileURL: URL) throws -> [String] {
3850
let filePath = try resolveSymlinks(try AbsolutePath(validating: fileURL.path))
39-
let commandLine = try self.emitCommandLine(for: filePath)
51+
let commandLine = try description.emitCommandLine(for: filePath)
4052
// First element on the command line is the compiler itself, not an argument.
4153
return Array(commandLine.dropFirst())
4254
}
4355
}
4456

4557
private struct WrappedSwiftTargetBuildDescription: BuildTarget {
4658
private let description: SwiftTargetBuildDescription
59+
let isPartOfRootPackage: Bool
4760

48-
init(description: SwiftTargetBuildDescription) {
61+
init(description: SwiftTargetBuildDescription, isPartOfRootPackage: Bool) {
4962
self.description = description
63+
self.isPartOfRootPackage = isPartOfRootPackage
5064
}
5165

5266
var sources: [URL] {
@@ -71,17 +85,27 @@ public struct BuildDescription {
7185
}
7286

7387
// FIXME: should not use `ResolvedTarget` in the public interface
74-
public func getBuildTarget(for target: ResolvedModule) -> BuildTarget? {
88+
public func getBuildTarget(for target: ResolvedModule, in modulesGraph: ModulesGraph) -> BuildTarget? {
7589
if let description = buildPlan.targetMap[target.id] {
7690
switch description {
7791
case .clang(let description):
78-
return description
92+
return WrappedClangTargetBuildDescription(
93+
description: description,
94+
isPartOfRootPackage: modulesGraph.rootPackages.map(\.id).contains(description.package.id)
95+
)
7996
case .swift(let description):
80-
return WrappedSwiftTargetBuildDescription(description: description)
97+
return WrappedSwiftTargetBuildDescription(
98+
description: description,
99+
isPartOfRootPackage: modulesGraph.rootPackages.map(\.id).contains(description.package.id)
100+
)
81101
}
82102
} else {
83103
if target.type == .plugin, let package = self.buildPlan.graph.package(for: target) {
84-
return PluginTargetBuildDescription(target: target, toolsVersion: package.manifest.toolsVersion)
104+
return PluginTargetBuildDescription(
105+
target: target,
106+
toolsVersion: package.manifest.toolsVersion,
107+
isPartOfRootPackage: modulesGraph.rootPackages.map(\.id).contains(package.id)
108+
)
85109
}
86110
return nil
87111
}

Sources/SourceKitLSPAPI/PluginTargetBuildDescription.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@ private import class PackageModel.UserToolchain
2121
struct PluginTargetBuildDescription: BuildTarget {
2222
private let target: ResolvedModule
2323
private let toolsVersion: ToolsVersion
24+
let isPartOfRootPackage: Bool
2425

25-
init(target: ResolvedModule, toolsVersion: ToolsVersion) {
26+
init(target: ResolvedModule, toolsVersion: ToolsVersion, isPartOfRootPackage: Bool) {
2627
assert(target.type == .plugin)
2728
self.target = target
2829
self.toolsVersion = toolsVersion
30+
self.isPartOfRootPackage = isPartOfRootPackage
2931
}
3032

3133
var sources: [URL] {

Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ class SourceKitLSPAPITests: XCTestCase {
6363
"-emit-dependencies",
6464
"-emit-module",
6565
"-emit-module-path", "/path/to/build/\(buildParameters.triple)/debug/exe.build/exe.swiftmodule"
66-
]
66+
],
67+
isPartOfRootPackage: true
6768
)
6869
try description.checkArguments(
6970
for: "lib",
@@ -73,7 +74,8 @@ class SourceKitLSPAPITests: XCTestCase {
7374
"-emit-dependencies",
7475
"-emit-module",
7576
"-emit-module-path", "/path/to/build/\(buildParameters.triple)/debug/Modules/lib.swiftmodule"
76-
]
77+
],
78+
isPartOfRootPackage: true
7779
)
7880
}
7981
}
@@ -82,10 +84,11 @@ extension SourceKitLSPAPI.BuildDescription {
8284
@discardableResult func checkArguments(
8385
for targetName: String,
8486
graph: ModulesGraph,
85-
partialArguments: [String]
87+
partialArguments: [String],
88+
isPartOfRootPackage: Bool
8689
) throws -> Bool {
8790
let target = try XCTUnwrap(graph.allTargets.first(where: { $0.name == targetName }))
88-
let buildTarget = try XCTUnwrap(self.getBuildTarget(for: target))
91+
let buildTarget = try XCTUnwrap(self.getBuildTarget(for: target, in: graph))
8992

9093
guard let file = buildTarget.sources.first else {
9194
XCTFail("build target \(targetName) contains no files")
@@ -96,6 +99,7 @@ extension SourceKitLSPAPI.BuildDescription {
9699
let result = arguments.contains(partialArguments)
97100

98101
XCTAssertTrue(result, "could not match \(partialArguments) to actual arguments \(arguments)")
102+
XCTAssertEqual(buildTarget.isPartOfRootPackage, isPartOfRootPackage)
99103
return result
100104
}
101105
}

0 commit comments

Comments
 (0)