in Sources/SourceKitLSP/SourceKitServer.swift [982:1045]
func definition(
_ req: Request<DefinitionRequest>,
workspace: Workspace,
languageService: ToolchainLanguageServer
) {
let symbolInfo = SymbolInfoRequest(textDocument: req.params.textDocument, position: req.params.position)
let index = self.workspace?.index
// If we're unable to handle the definition request using our index, see if the
// language service can handle it (e.g. clangd can provide AST based definitions).
let resultHandler: ([Location], ResponseError?) -> Void = { (locs, error) in
guard locs.isEmpty else {
req.reply(.locations(locs))
return
}
let handled = languageService.definition(req)
guard !handled else { return }
if let error = error {
req.reply(.failure(error))
} else {
req.reply(.locations([]))
}
}
let callback = callbackOnQueue(self.queue) { (result: Result<SymbolInfoRequest.Response, ResponseError>) in
guard let symbols: [SymbolDetails] = result.success ?? nil, let symbol = symbols.first else {
resultHandler([], result.failure)
return
}
let fallbackLocation = [symbol.bestLocalDeclaration].compactMap { $0 }
guard let usr = symbol.usr, let index = index else {
resultHandler(fallbackLocation, nil)
return
}
log("performing indexed jump-to-def with usr \(usr)")
var occurs = index.occurrences(ofUSR: usr, roles: [.definition])
if occurs.isEmpty {
occurs = index.occurrences(ofUSR: usr, roles: [.declaration])
}
// FIXME: overrided method logic
let locations = occurs.compactMap { occur -> Location? in
if occur.location.path.isEmpty {
return nil
}
return Location(
uri: DocumentURI(URL(fileURLWithPath: occur.location.path)),
range: Range(Position(
line: occur.location.line - 1, // 1-based -> 0-based
// FIXME: we need to convert the utf8/utf16 column, which may require reading the file!
utf16index: occur.location.utf8Column - 1
))
)
}
resultHandler(locations.isEmpty ? fallbackLocation : locations, nil)
}
let request = Request(symbolInfo, id: req.id, clientID: ObjectIdentifier(self),
cancellation: req.cancellationToken, reply: callback)
languageService.symbolInfo(request)
}