From c40476c1918c5f1a6271f11dca211dded4a90abb Mon Sep 17 00:00:00 2001 From: "lijunliang.9819" Date: Wed, 31 Dec 2025 13:07:18 +0800 Subject: [PATCH] feat: Fallback to swiftmodule interface when index lookup fails for definition Currently, `indexBasedDefinition` relies heavily on IndexStoreDB. If a symbol belongs to a binary framework or a library that hasn't been indexed (but has module info provided by sourcekitd), the definition request fails or returns empty results. This change adds a fallback mechanism in `definitionLocations`. When no occurrences are found in the index, we check if `systemModule` information is available on the symbol. If so, we trigger `definitionInInterface` to generate the textual interface (via `editor.open.interface`) and return that location. This improves navigation for binary dependencies (XCFrameworks) and SDKs partially covered by the index. --- Sources/SourceKitLSP/SourceKitLSPServer.swift | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/Sources/SourceKitLSP/SourceKitLSPServer.swift b/Sources/SourceKitLSP/SourceKitLSPServer.swift index 4237895d..fc6effa3 100644 --- a/Sources/SourceKitLSP/SourceKitLSPServer.swift +++ b/Sources/SourceKitLSP/SourceKitLSPServer.swift @@ -2027,8 +2027,23 @@ extension SourceKitLSPServer { } } - if occurrences.isEmpty, let bestLocalDeclaration = symbol.bestLocalDeclaration { - return [bestLocalDeclaration] + if occurrences.isEmpty { + if let bestLocalDeclaration = symbol.bestLocalDeclaration { + return [bestLocalDeclaration] + } + // Fallback: The symbol was not found in the index. This often happens with + // third-party binary frameworks or libraries where indexing data is missing. + // If module info is available, fallback to generating the textual interface. + if let systemModule = symbol.systemModule { + let location = try await self.definitionInInterface( + moduleName: systemModule.moduleName, + groupName: systemModule.groupName, + symbolUSR: symbol.usr, + originatorUri: uri, + languageService: languageService + ) + return [location] + } } return occurrences.compactMap { indexToLSPLocation($0.location) }.sorted()