From e0c2ab07ede8b7e2f1a3857385ab355b0040a27d Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Fri, 22 May 2026 11:18:47 -0700 Subject: [PATCH] SourceKitLSP: fallback to Swift source for SDK symbol resolve When resolving a workspace symbol whose location points at an SDK .swiftmodule/.swiftinterface, SourceKit-LSP currently asks IndexStoreDB for main files containing that module file and uses one of those files to provide build settings for opening the generated interface. That relationship is not guaranteed to exist for SDK module files. The module file can appear as the indexed symbol location, while mainFiles(containing:) still returns no source file. This causes workspaceSymbol/resolve to fail before calling sourcekitd, with errors like: No source file found that imports Swift.String; cannot open generated interface If no main file is found for the module file, fall back to a buildable Swift source file from the workspace. The file is only used as the source of compiler arguments for generating the interface, so any buildable Swift source in the workspace is sufficient. This fixes resolving stdlib/SDK workspace symbols such as Swift.String on Windows SDK layouts where the stdlib location is a .swiftmodule under the SDK. --- Sources/SourceKitLSP/SourceKitLSPServer.swift | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/Sources/SourceKitLSP/SourceKitLSPServer.swift b/Sources/SourceKitLSP/SourceKitLSPServer.swift index 59bf0b7fb..e547e5d6d 100644 --- a/Sources/SourceKitLSP/SourceKitLSPServer.swift +++ b/Sources/SourceKitLSP/SourceKitLSPServer.swift @@ -1733,10 +1733,21 @@ extension SourceKitLSPServer { }() ) for workspace in workspaces { - let mainFile = await workspace.buildServerManager + var candidateMainFiles = await workspace.buildServerManager .mainFiles(containing: moduleFileURI) .sorted(by: { $0.arbitrarySchemeURL.absoluteString < $1.arbitrarySchemeURL.absoluteString }) - .first + if candidateMainFiles.isEmpty { + // SDK module files don't necessarily have a recorded main-file relationship in the index. We only need a Swift + // source file from the workspace to provide compiler arguments for generating the interface. + candidateMainFiles = + await orLog("Getting Swift source files for workspaceSymbol/resolve generated interface") { + try await workspace.buildServerManager.projectSourceFiles() + .keys + .filter { $0.fileURL?.pathExtension == "swift" } + .sorted(by: { $0.arbitrarySchemeURL.absoluteString < $1.arbitrarySchemeURL.absoluteString }) + } ?? [] + } + let mainFile = candidateMainFiles.first guard let mainFile else { continue }