Skip to content

Commit ff2e4fc

Browse files
committed
Adopt faster traverseModules implementation in SwiftPM
Opening the SourceKit-LSP workspace using a debug build of sourcekit-lsp takes about 35s because `traverseModules` generates about 800,000 callback calls. All SourceKit-LSP needs now are the modules and their dependencies, so we can refactor `traverseModules` to just return that information avoid visiting the same modules multiple times. With theses changes getting all modules and their dependencies only takes ~0.013s. rdar://136107035
1 parent aec8bf0 commit ff2e4fc

File tree

1 file changed

+12
-16
lines changed

1 file changed

+12
-16
lines changed

Sources/BuildSystemIntegration/SwiftPMBuildSystem.swift

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -205,9 +205,8 @@ package actor SwiftPMBuildSystem: BuiltInBuildSystem {
205205
private var buildDescription: SourceKitLSPAPI.BuildDescription?
206206

207207
/// Maps target ids to their SwiftPM build target.
208-
private var swiftPMTargets: [BuildTargetIdentifier: SwiftBuildTarget] = [:]
209-
210-
private var targetDependencies: [BuildTargetIdentifier: Set<BuildTargetIdentifier>] = [:]
208+
private var swiftPMTargets:
209+
[BuildTargetIdentifier: (target: SwiftBuildTarget, dependencies: Set<BuildTargetIdentifier>)] = [:]
211210

212211
static package func projectRoot(
213212
for path: TSCBasic.AbsolutePath,
@@ -402,19 +401,16 @@ package actor SwiftPMBuildSystem: BuiltInBuildSystem {
402401
/// with only some properties modified.
403402

404403
self.swiftPMTargets = [:]
405-
self.targetDependencies = [:]
406404

407-
buildDescription.traverseModules { buildTarget, parent, depth in
405+
buildDescription.traverseModules { buildTarget, dependencies in
408406
let targetIdentifier = orLog("Getting build target identifier") { try BuildTargetIdentifier(buildTarget) }
409407
guard let targetIdentifier else {
410408
return
411409
}
412-
if let parent,
413-
let parentIdentifier = orLog("Getting parent build target identifier", { try BuildTargetIdentifier(parent) })
414-
{
415-
self.targetDependencies[parentIdentifier, default: []].insert(targetIdentifier)
410+
let dependencies = dependencies.compactMap { dependency in
411+
orLog("Getting build target identifier of dependency") { try BuildTargetIdentifier(dependency) }
416412
}
417-
swiftPMTargets[targetIdentifier] = buildTarget
413+
swiftPMTargets[targetIdentifier] = (buildTarget, Set(dependencies))
418414
}
419415

420416
connectionToSourceKitLSP.send(OnBuildTargetDidChangeNotification(changes: nil))
@@ -454,18 +450,18 @@ package actor SwiftPMBuildSystem: BuiltInBuildSystem {
454450
package func buildTargets(request: WorkspaceBuildTargetsRequest) async throws -> WorkspaceBuildTargetsResponse {
455451
var targets = self.swiftPMTargets.map { (targetId, target) in
456452
var tags: [BuildTargetTag] = [.test]
457-
if !target.isPartOfRootPackage {
453+
if !target.target.isPartOfRootPackage {
458454
tags.append(.dependency)
459455
}
460456
return BuildTarget(
461457
id: targetId,
462-
displayName: target.name,
458+
displayName: target.target.name,
463459
baseDirectory: nil,
464460
tags: tags,
465461
capabilities: BuildTargetCapabilities(),
466462
// Be conservative with the languages that might be used in the target. SourceKit-LSP doesn't use this property.
467463
languageIds: [.c, .cpp, .objective_c, .objective_cpp, .swift],
468-
dependencies: self.targetDependencies[targetId, default: []].sorted { $0.uri.stringValue < $1.uri.stringValue },
464+
dependencies: target.dependencies.sorted { $0.uri.stringValue < $1.uri.stringValue },
469465
dataKind: .sourceKit,
470466
data: SourceKitBuildTarget(toolchain: toolchain.path?.asURI).encodeToLSPAny()
471467
)
@@ -503,7 +499,7 @@ package actor SwiftPMBuildSystem: BuiltInBuildSystem {
503499
)
504500
)
505501
}
506-
guard let swiftPMTarget = self.swiftPMTargets[target] else {
502+
guard let swiftPMTarget = self.swiftPMTargets[target]?.target else {
507503
continue
508504
}
509505
var sources = swiftPMTarget.sources.map {
@@ -535,7 +531,7 @@ package actor SwiftPMBuildSystem: BuiltInBuildSystem {
535531
return try settings(forPackageManifest: path)
536532
}
537533

538-
guard let swiftPMTarget = self.swiftPMTargets[request.target] else {
534+
guard let swiftPMTarget = self.swiftPMTargets[request.target]?.target else {
539535
logger.error("Did not find target \(request.target.forLogging)")
540536
return nil
541537
}
@@ -630,7 +626,7 @@ package actor SwiftPMBuildSystem: BuiltInBuildSystem {
630626
logMessageToIndexLog(
631627
taskID,
632628
"""
633-
Preparing \(self.swiftPMTargets[target]?.name ?? target.uri.stringValue)
629+
Preparing \(self.swiftPMTargets[target]?.target.name ?? target.uri.stringValue)
634630
\(arguments.joined(separator: " "))
635631
"""
636632
)

0 commit comments

Comments
 (0)