@@ -1752,10 +1752,7 @@ extension SourceKitServer {
1752
1752
}
1753
1753
guard let usr = symbol. usr else { return [ ] }
1754
1754
logger. info ( " performing indexed jump-to-def with usr \( usr) " )
1755
- var occurrences = index. occurrences ( ofUSR: usr, roles: [ . definition] )
1756
- if occurrences. isEmpty {
1757
- occurrences = index. occurrences ( ofUSR: usr, roles: [ . declaration] )
1758
- }
1755
+ var occurrences = index. definitionOrDeclarationOccurrences ( ofUSR: usr)
1759
1756
if symbol. isDynamic ?? true {
1760
1757
lazy var transitiveReceiverUsrs : [ String ] ? = {
1761
1758
if let receiverUsrs = symbol. receiverUsrs {
@@ -1861,7 +1858,7 @@ extension SourceKitServer {
1861
1858
/// to get to the definition of `symbolUSR`.
1862
1859
///
1863
1860
/// `originatorUri` is the URI of the file from which the definition request is performed. It is used to determine the
1864
- /// compiler arguments to generate the generated inteface .
1861
+ /// compiler arguments to generate the generated interface .
1865
1862
func definitionInInterface(
1866
1863
moduleName: String ,
1867
1864
symbolUSR: String ? ,
@@ -1898,12 +1895,12 @@ extension SourceKitServer {
1898
1895
return nil
1899
1896
}
1900
1897
guard let usr = symbol. usr else { return nil }
1901
- var occurrances = index. occurrences ( ofUSR: usr, roles: . baseOf)
1902
- if occurrances . isEmpty {
1903
- occurrances = index. occurrences ( relatedToUSR: usr, roles: . overrideOf)
1898
+ var occurrences = index. occurrences ( ofUSR: usr, roles: . baseOf)
1899
+ if occurrences . isEmpty {
1900
+ occurrences = index. occurrences ( relatedToUSR: usr, roles: . overrideOf)
1904
1901
}
1905
1902
1906
- return . locations( occurrances . compactMap { indexToLSPLocation ( $0. location) } )
1903
+ return . locations( occurrences . compactMap { indexToLSPLocation ( $0. location) } )
1907
1904
}
1908
1905
1909
1906
func references(
@@ -1968,17 +1965,23 @@ extension SourceKitServer {
1968
1965
}
1969
1966
// For call hierarchy preparation we only locate the definition
1970
1967
guard let usr = symbol. usr else { return nil }
1971
- return index. occurrences ( ofUSR: usr, roles: [ . definition, . declaration] )
1972
- . compactMap { info -> CallHierarchyItem ? in
1973
- guard let location = indexToLSPLocation ( info. location) else {
1974
- return nil
1975
- }
1976
- return self . indexToLSPCallHierarchyItem (
1977
- symbol: info. symbol,
1978
- moduleName: info. location. moduleName,
1979
- location: location
1980
- )
1981
- }
1968
+
1969
+ // Only return a single call hierarchy item. Returning multiple doesn't make sense because they will all have the
1970
+ // same USR (because we query them by USR) and will thus expand to the exact same call hierarchy.
1971
+ // Also, VS Code doesn't seem to like multiple call hierarchy items being returned and fails to display any results
1972
+ // if they are, failing with `Cannot read properties of undefined (reading 'map')`.
1973
+ guard let definition = index. definitionOrDeclarationOccurrences ( ofUSR: usr) . first else {
1974
+ return nil
1975
+ }
1976
+ guard let location = indexToLSPLocation ( definition. location) else {
1977
+ return nil
1978
+ }
1979
+ let callHierarchyItem = self . indexToLSPCallHierarchyItem (
1980
+ symbol: definition. symbol,
1981
+ moduleName: definition. location. moduleName,
1982
+ location: location
1983
+ )
1984
+ return [ callHierarchyItem]
1982
1985
}
1983
1986
1984
1987
/// Extracts our implementation-specific data about a call hierarchy
@@ -2260,6 +2263,18 @@ private let maxWorkspaceSymbolResults = 4096
2260
2263
2261
2264
public typealias Diagnostic = LanguageServerProtocol . Diagnostic
2262
2265
2266
+ fileprivate extension IndexStoreDB {
2267
+ /// If there are any definition occurrences of the given USR, return these.
2268
+ /// Otherwise return declaration occurrences.
2269
+ func definitionOrDeclarationOccurrences( ofUSR usr: String ) -> [ SymbolOccurrence ] {
2270
+ let definitions = occurrences ( ofUSR: usr, roles: [ . definition] )
2271
+ if !definitions. isEmpty {
2272
+ return definitions
2273
+ }
2274
+ return occurrences ( ofUSR: usr, roles: [ . declaration] )
2275
+ }
2276
+ }
2277
+
2263
2278
extension IndexSymbolKind {
2264
2279
func asLspSymbolKind( ) -> SymbolKind {
2265
2280
switch self {
@@ -2333,8 +2348,8 @@ fileprivate func transitiveSubtypeClosure(ofUsrs usrs: [String], index: IndexSto
2333
2348
var result : [ String ] = [ ]
2334
2349
for usr in usrs {
2335
2350
result. append ( usr)
2336
- let directSubtypes = index. occurrences ( ofUSR: usr, roles: . baseOf) . flatMap { occurance in
2337
- occurance . relations. filter { $0. roles. contains ( . baseOf) } . map ( \. symbol. usr)
2351
+ let directSubtypes = index. occurrences ( ofUSR: usr, roles: . baseOf) . flatMap { occurrence in
2352
+ occurrence . relations. filter { $0. roles. contains ( . baseOf) } . map ( \. symbol. usr)
2338
2353
}
2339
2354
let transitiveSubtypes = transitiveSubtypeClosure ( ofUsrs: directSubtypes, index: index)
2340
2355
result += transitiveSubtypes
0 commit comments