Skip to content

Commit 5196c48

Browse files
authored
Merge pull request #1953 from ahoppen/clean-up-toolchain
Cache the mapping from compiler to toolchain
2 parents 6bde06b + fc100d2 commit 5196c48

File tree

7 files changed

+39
-30
lines changed

7 files changed

+39
-30
lines changed

Sources/BuildSystemIntegration/SwiftPMBuildSystem.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ package actor SwiftPMBuildSystem: BuiltInBuildSystem {
425425
languageIds: [.c, .cpp, .objective_c, .objective_cpp, .swift],
426426
dependencies: self.targetDependencies[targetId, default: []].sorted { $0.uri.stringValue < $1.uri.stringValue },
427427
dataKind: .sourceKit,
428-
data: SourceKitBuildTarget(toolchain: toolchain.path.map(URI.init)).encodeToLSPAny()
428+
data: SourceKitBuildTarget(toolchain: URI(toolchain.path)).encodeToLSPAny()
429429
)
430430
}
431431
targets.append(

Sources/Diagnose/ReproducerBundle.swift

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,12 @@ func makeReproducerBundle(for requestInfo: RequestInfo, toolchain: Toolchain, bu
2828
atomically: true,
2929
encoding: .utf8
3030
)
31-
if let toolchainPath = toolchain.path {
32-
try toolchainPath.realpath.filePath
33-
.write(
34-
to: bundlePath.appendingPathComponent("toolchain.txt"),
35-
atomically: true,
36-
encoding: .utf8
37-
)
38-
}
31+
try toolchain.path.realpath.filePath
32+
.write(
33+
to: bundlePath.appendingPathComponent("toolchain.txt"),
34+
atomically: true,
35+
encoding: .utf8
36+
)
3937
if requestInfo.requestTemplate == RequestInfo.fakeRequestTemplateForFrontendIssues {
4038
let command =
4139
"swift-frontend \\\n"

Sources/SourceKitLSP/SourceKitLSPServer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ package actor SourceKitLSPServer {
567567

568568
logger.log(
569569
"""
570-
Using toolchain at \(toolchain.path?.description ?? "<nil>") (\(toolchain.identifier, privacy: .public)) \
570+
Using toolchain at \(toolchain.path.description) (\(toolchain.identifier, privacy: .public)) \
571571
for \(uri.forLogging)
572572
"""
573573
)

Sources/SourceKitLSP/Swift/SwiftLanguageService.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ package actor SwiftLanguageService: LanguageService, Sendable {
237237
} else if let clientPlugin = toolchain.sourceKitClientPlugin, let servicePlugin = toolchain.sourceKitServicePlugin {
238238
pluginPaths = PluginPaths(clientPlugin: clientPlugin, servicePlugin: servicePlugin)
239239
} else {
240-
logger.fault("Failed to find SourceKit plugin for toolchain at \(toolchain.path?.path ?? "nil")")
240+
logger.fault("Failed to find SourceKit plugin for toolchain at \(toolchain.path.path)")
241241
pluginPaths = nil
242242
}
243243
self.sourcekitd = try await DynamicallyLoadedSourceKitD.getOrCreate(

Sources/ToolchainRegistry/Toolchain.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public final class Toolchain: Sendable {
7777
/// The path to this toolchain, if applicable.
7878
///
7979
/// For example, this may be the path to an ".xctoolchain" directory.
80-
package let path: URL?
80+
package let path: URL
8181

8282
// MARK: Tool Paths
8383

Sources/ToolchainRegistry/ToolchainRegistry.swift

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import Dispatch
14+
import SKLogging
1415
import SwiftExtensions
1516
import TSCExtensions
1617

@@ -68,10 +69,14 @@ package final actor ToolchainRegistry {
6869
private let toolchainsByIdentifier: [String: [Toolchain]]
6970

7071
/// The toolchains indexed by their path.
71-
///
72-
/// Note: Not all toolchains have a path.
7372
private let toolchainsByPath: [URL: Toolchain]
7473

74+
/// Map from compiler paths (`clang`, `swift`, `swiftc`) mapping to the toolchain that contained them.
75+
///
76+
/// This allows us to find the toolchain that should be used for semantic functionality based on which compiler it is
77+
/// built with in the `compile_commands.json`.
78+
private let toolchainsByCompiler: [URL: Toolchain]
79+
7580
/// The currently selected toolchain identifier on Darwin.
7681
package let darwinToolchainOverride: String?
7782

@@ -98,29 +103,40 @@ package final actor ToolchainRegistry {
98103
var toolchainsAndReasons: [(toolchain: Toolchain, reason: ToolchainRegisterReason)] = []
99104
var toolchainsByIdentifier: [String: [Toolchain]] = [:]
100105
var toolchainsByPath: [URL: Toolchain] = [:]
106+
var toolchainsByCompiler: [URL: Toolchain] = [:]
101107
for (toolchain, reason) in toolchainsAndReasonsParam {
102108
// Non-XcodeDefault toolchain: disallow all duplicates.
103-
if toolchain.identifier != ToolchainRegistry.darwinDefaultToolchainIdentifier {
104-
guard toolchainsByIdentifier[toolchain.identifier] == nil else {
105-
continue
106-
}
109+
if toolchainsByIdentifier[toolchain.identifier] != nil,
110+
toolchain.identifier != ToolchainRegistry.darwinDefaultToolchainIdentifier
111+
{
112+
logger.error("Found two toolchains with the same identifier: \(toolchain.identifier)")
113+
continue
114+
}
115+
116+
// Toolchain should always be unique by path.
117+
if toolchainsByPath[toolchain.path] != nil {
118+
logger.fault("Found two toolchains with the same path: \(toolchain.path)")
119+
continue
107120
}
108121

109-
// Toolchain should always be unique by path if it is present.
110-
if let path = toolchain.path {
111-
guard toolchainsByPath[path] == nil else {
122+
toolchainsByPath[toolchain.path] = toolchain
123+
toolchainsByIdentifier[toolchain.identifier, default: []].append(toolchain)
124+
125+
for case .some(let compiler) in [toolchain.clang, toolchain.swift, toolchain.swiftc] {
126+
guard toolchainsByCompiler[compiler] == nil else {
127+
logger.fault("Found two toolchains with the same compiler: \(compiler)")
112128
continue
113129
}
114-
toolchainsByPath[path] = toolchain
130+
toolchainsByCompiler[compiler] = toolchain
115131
}
116132

117-
toolchainsByIdentifier[toolchain.identifier, default: []].append(toolchain)
118133
toolchainsAndReasons.append((toolchain, reason))
119134
}
120135

121136
self.toolchainsAndReasons = toolchainsAndReasons
122137
self.toolchainsByIdentifier = toolchainsByIdentifier
123138
self.toolchainsByPath = toolchainsByPath
139+
self.toolchainsByCompiler = toolchainsByCompiler
124140

125141
if let darwinToolchainOverride, !darwinToolchainOverride.isEmpty, darwinToolchainOverride != "default" {
126142
self.darwinToolchainOverride = darwinToolchainOverride
@@ -267,12 +283,7 @@ package final actor ToolchainRegistry {
267283
/// If we have a toolchain in the toolchain registry that contains the compiler with the given URL, return it.
268284
/// Otherwise, return `nil`.
269285
package func toolchain(withCompiler compiler: URL) -> Toolchain? {
270-
for toolchain in toolchains {
271-
if [toolchain.clang, toolchain.swift, toolchain.swiftc].contains(compiler) {
272-
return toolchain
273-
}
274-
}
275-
return nil
286+
return toolchainsByCompiler[compiler]
276287
}
277288
}
278289

Tests/DiagnoseTests/DiagnoseTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ private func assertReduceSourceKitD(
239239
let (markers, fileContents) = extractMarkers(markedFileContents)
240240

241241
let toolchain = try await unwrap(ToolchainRegistry.forTesting.default)
242-
logger.debug("Using \(toolchain.path?.description ?? "<nil>") to reduce source file")
242+
logger.debug("Using \(toolchain.path.description) to reduce source file")
243243

244244
let markerOffset = try XCTUnwrap(markers["1️⃣"], "Failed to find position marker 1️⃣ in file contents")
245245

0 commit comments

Comments
 (0)