mirror of
https://github.com/apple/sourcekit-lsp.git
synced 2026-03-02 18:23:24 +01:00
78 lines
2.8 KiB
Swift
78 lines
2.8 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2026 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
import IndexStoreDB
|
|
@_spi(SourceKitLSP) package import LanguageServerProtocol
|
|
import SemanticIndex
|
|
import SourceKitD
|
|
import SourceKitLSP
|
|
|
|
extension SwiftLanguageService {
|
|
/// Handles the textDocument/typeDefinition request.
|
|
package func typeDefinition(_ request: TypeDefinitionRequest) async throws -> LocationsOrLocationLinksResponse? {
|
|
let uri = request.textDocument.uri
|
|
let position = request.position
|
|
|
|
let snapshot = try await self.latestSnapshot(for: uri)
|
|
let compileCommand = await self.compileCommand(for: uri, fallbackAfterTimeout: false)
|
|
|
|
let skreq = sourcekitd.dictionary([
|
|
keys.cancelOnSubsequentRequest: 0,
|
|
keys.offset: snapshot.utf8Offset(of: position),
|
|
keys.sourceFile: snapshot.uri.sourcekitdSourceFile,
|
|
keys.primaryFile: snapshot.uri.primaryFile?.pseudoPath,
|
|
keys.compilerArgs: compileCommand?.compilerArgs as [any SKDRequestValue]?,
|
|
])
|
|
|
|
let dict = try await send(sourcekitdRequest: \.cursorInfo, skreq, snapshot: snapshot)
|
|
let documentManager = try self.documentManager
|
|
|
|
// If the cursor is on a type symbol itself, use its USR directly.
|
|
// Otherwise get the type of the symbol at this position.
|
|
let symbol: SymbolDetails
|
|
if let cursorInfo = CursorInfo(dict, snapshot: snapshot, documentManager: documentManager, sourcekitd: sourcekitd) {
|
|
switch cursorInfo.symbolInfo.kind {
|
|
case .class, .struct, .enum, .interface, .typeParameter:
|
|
symbol = cursorInfo.symbolInfo
|
|
default:
|
|
guard let typeUsr: String = dict[keys.typeUsr],
|
|
let typeSymbol = try await cursorInfoFromTypeUSR(typeUsr, in: snapshot)?.symbolInfo
|
|
else {
|
|
return nil
|
|
}
|
|
symbol = typeSymbol
|
|
}
|
|
} else {
|
|
guard let typeUsr: String = dict[keys.typeUsr],
|
|
let typeSymbol = try await cursorInfoFromTypeUSR(typeUsr, in: snapshot)?.symbolInfo
|
|
else {
|
|
return nil
|
|
}
|
|
symbol = typeSymbol
|
|
}
|
|
|
|
let index = await sourceKitLSPServer?.workspaceForDocument(uri: uri)?.index(checkedFor: .deletedFiles)
|
|
let locations = try await SourceKitLSP.definitionLocations(
|
|
for: symbol,
|
|
originatorUri: uri,
|
|
index: index,
|
|
languageService: self
|
|
).locations
|
|
|
|
if locations.isEmpty {
|
|
return nil
|
|
}
|
|
|
|
return .locations(locations)
|
|
}
|
|
}
|