Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Documentation/Background Indexing.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ Next, point your editor to use the just-built copy of SourceKit-LSP and enable b
"swift.sourcekit-lsp.serverArguments": [ "--experimental-feature", "background-indexing" ],
```

Background indexing requires a Swift 6 toolchain. You can download Swift 6 nightly toolchains from https://www.swift.org/download/#swift-60-development.

## Known issues

- The only supported toolchain for background indexing are currently [Swift 6.0 nightly toolchain snapshots](https://www.swift.org/download/#swift-60-development). Older toolchains are not supported and the nightly toolchains from `main` are having issues because building a target non-deterministically builds for tools or the destination [#1288](https://github.com/apple/sourcekit-lsp/pull/1288#issuecomment-2111400459) [rdar://128100158](rdar://128100158)
- Not really a background indexing related issue but Swift nightly toolchain snapshots are crashing on macOS 14.4 and 14.5 (swift#73327)[https://github.com/apple/swift/issues/73327]
- Workaround: Run the toolchains on an older version of macOS, if possible
- Background Indexing is only supported for SwiftPM projects [#1269](https://github.com/apple/sourcekit-lsp/issues/1269), [#1271](https://github.com/apple/sourcekit-lsp/issues/1271)
Expand Down
4 changes: 4 additions & 0 deletions Sources/SKCore/BuildServerBuildSystem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,10 @@ extension BuildServerBuildSystem: BuildSystem {
return nil
}

public func toolchain(for uri: DocumentURI, _ language: Language) async -> SKCore.Toolchain? {
return nil
}

public func configuredTargets(for document: DocumentURI) async -> [ConfiguredTarget] {
return [ConfiguredTarget(targetID: "dummy", runDestinationID: "dummy")]
}
Expand Down
5 changes: 5 additions & 0 deletions Sources/SKCore/BuildSystem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,11 @@ public protocol BuildSystem: AnyObject, Sendable {
/// If `nil` is returned, the language based on the file's extension.
func defaultLanguage(for document: DocumentURI) async -> Language?

/// The toolchain that should be used to open the given document.
///
/// If `nil` is returned, then the default toolchain for the given language is used.
func toolchain(for uri: DocumentURI, _ language: Language) async -> Toolchain?

/// Register the given file for build-system level change notifications, such
/// as command line flag changes, dependency changes, etc.
///
Expand Down
15 changes: 12 additions & 3 deletions Sources/SKCore/BuildSystemManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,18 @@ extension BuildSystemManager {

/// Returns the toolchain that should be used to process the given document.
public func toolchain(for uri: DocumentURI, _ language: Language) async -> Toolchain? {
// To support multiple toolchains within a single workspace, we need to ask the build system which toolchain to use
// for this document.
return await toolchainRegistry.defaultToolchain(for: language)
if let toolchain = await buildSystem?.toolchain(for: uri, language) {
return toolchain
}

switch language {
case .swift:
return await toolchainRegistry.preferredToolchain(containing: [\.sourcekitd, \.swift, \.swiftc])
case .c, .cpp, .objective_c, .objective_cpp:
return await toolchainRegistry.preferredToolchain(containing: [\.clang, \.clangd])
default:
return nil
}
}

/// - Note: Needed so we can set the delegate from a different isolation context.
Expand Down
4 changes: 4 additions & 0 deletions Sources/SKCore/CompilationDatabaseBuildSystem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ extension CompilationDatabaseBuildSystem: BuildSystem {
return nil
}

public func toolchain(for uri: DocumentURI, _ language: Language) async -> SKCore.Toolchain? {
return nil
}

public func configuredTargets(for document: DocumentURI) async -> [ConfiguredTarget] {
return [ConfiguredTarget(targetID: "dummy", runDestinationID: "dummy")]
}
Expand Down
20 changes: 4 additions & 16 deletions Sources/SKCore/ToolchainRegistry.swift
Original file line number Diff line number Diff line change
Expand Up @@ -246,26 +246,14 @@ public final actor ToolchainRegistry {
return darwinToolchainOverride ?? ToolchainRegistry.darwinDefaultToolchainIdentifier
}

/// The toolchain to use for a document in the given language if the build system doesn't override it.
func defaultToolchain(for language: Language) -> Toolchain? {
let supportsLang = { (toolchain: Toolchain) -> Bool in
// FIXME: the fact that we're looking at clangd/sourcekitd instead of the compiler indicates this method needs a parameter stating what kind of tool we're looking for.
switch language {
case .swift:
return toolchain.sourcekitd != nil
case .c, .cpp, .objective_c, .objective_cpp:
return toolchain.clangd != nil
default:
return false
}
}

if let toolchain = self.default, supportsLang(toolchain) {
/// Returns the preferred toolchain that contains all the tools at the given key paths.
public func preferredToolchain(containing requiredTools: [KeyPath<Toolchain, AbsolutePath?>]) -> Toolchain? {
if let toolchain = self.default, requiredTools.allSatisfy({ toolchain[keyPath: $0] != nil }) {
return toolchain
}

for toolchain in toolchains {
if supportsLang(toolchain) {
if requiredTools.allSatisfy({ toolchain[keyPath: $0] != nil }) {
return toolchain
}
}
Expand Down
Loading