@@ -1454,13 +1454,24 @@ extension SourceKitLSPServer {
1454
1454
range: Range ( symbolPosition)
1455
1455
)
1456
1456
1457
+ let containerNames = index. containerNames ( of: symbolOccurrence)
1458
+ let containerName : String ?
1459
+ if containerNames. isEmpty {
1460
+ containerName = nil
1461
+ } else {
1462
+ switch symbolOccurrence. symbol. language {
1463
+ case . cxx, . c, . objc: containerName = containerNames. joined ( separator: " :: " )
1464
+ case . swift: containerName = containerNames. joined ( separator: " . " )
1465
+ }
1466
+ }
1467
+
1457
1468
return WorkspaceSymbolItem . symbolInformation (
1458
1469
SymbolInformation (
1459
1470
name: symbolOccurrence. symbol. name,
1460
1471
kind: symbolOccurrence. symbol. kind. asLspSymbolKind ( ) ,
1461
1472
deprecated: nil ,
1462
1473
location: symbolLocation,
1463
- containerName: index . containerName ( of : symbolOccurrence )
1474
+ containerName: containerName
1464
1475
)
1465
1476
)
1466
1477
}
@@ -1934,27 +1945,14 @@ extension SourceKitLSPServer {
1934
1945
}
1935
1946
1936
1947
private func indexToLSPCallHierarchyItem(
1937
- symbol: Symbol ,
1938
- containerName: String ? ,
1939
- location: Location
1940
- ) -> CallHierarchyItem {
1941
- let name : String
1942
- if let containerName {
1943
- switch symbol. language {
1944
- case . objc where symbol. kind == . instanceMethod || symbol. kind == . instanceProperty:
1945
- name = " -[ \( containerName) \( symbol. name) ] "
1946
- case . objc where symbol. kind == . classMethod || symbol. kind == . classProperty:
1947
- name = " +[ \( containerName) \( symbol. name) ] "
1948
- case . cxx, . c, . objc:
1949
- // C shouldn't have container names for call hierarchy and Objective-C should be covered above.
1950
- // Fall back to using the C++ notation using `::`.
1951
- name = " \( containerName) :: \( symbol. name) "
1952
- case . swift:
1953
- name = " \( containerName) . \( symbol. name) "
1954
- }
1955
- } else {
1956
- name = symbol. name
1948
+ definition: SymbolOccurrence ,
1949
+ index: CheckedIndex
1950
+ ) -> CallHierarchyItem ? {
1951
+ guard let location = indexToLSPLocation ( definition. location) else {
1952
+ return nil
1957
1953
}
1954
+ let name = index. fullyQualifiedName ( of: definition)
1955
+ let symbol = definition. symbol
1958
1956
return CallHierarchyItem (
1959
1957
name: name,
1960
1958
kind: symbol. kind. asLspSymbolKind ( ) ,
@@ -1994,14 +1992,7 @@ extension SourceKitLSPServer {
1994
1992
guard let definition = index. primaryDefinitionOrDeclarationOccurrence ( ofUSR: usr) else {
1995
1993
return nil
1996
1994
}
1997
- guard let location = indexToLSPLocation ( definition. location) else {
1998
- return nil
1999
- }
2000
- return self . indexToLSPCallHierarchyItem (
2001
- symbol: definition. symbol,
2002
- containerName: index. containerName ( of: definition) ,
2003
- location: location
2004
- )
1995
+ return self . indexToLSPCallHierarchyItem ( definition: definition, index: index)
2005
1996
} . sorted ( by: { Location ( uri: $0. uri, range: $0. range) < Location ( uri: $1. uri, range: $1. range) } )
2006
1997
2007
1998
// Ideally, we should show multiple symbols. But VS Code fails to display call hierarchies with multiple root items,
@@ -2063,38 +2054,27 @@ extension SourceKitLSPServer {
2063
2054
2064
2055
// TODO: Remove this workaround once https://github.com/swiftlang/swift/issues/75600 is fixed
2065
2056
func indexToLSPCallHierarchyItem2(
2066
- symbol: Symbol ,
2067
- containerName: String ? ,
2068
- location: Location
2069
- ) -> CallHierarchyItem {
2070
- return self . indexToLSPCallHierarchyItem ( symbol: symbol, containerName: containerName, location: location)
2057
+ definition: SymbolOccurrence ,
2058
+ index: CheckedIndex
2059
+ ) -> CallHierarchyItem ? {
2060
+ return self . indexToLSPCallHierarchyItem ( definition: definition, index: index)
2071
2061
}
2072
2062
2073
2063
let calls = callersToCalls. compactMap { ( caller: Symbol , calls: [ SymbolOccurrence ] ) -> CallHierarchyIncomingCall ? in
2074
2064
// Resolve the caller's definition to find its location
2075
- let definition = index. primaryDefinitionOrDeclarationOccurrence ( ofUSR: caller. usr)
2076
- let definitionSymbolLocation = definition? . location
2077
- let definitionLocation = definitionSymbolLocation. flatMap ( indexToLSPLocation2)
2078
- let containerName : String ? =
2079
- if let definition {
2080
- index. containerName ( of: definition)
2081
- } else {
2082
- nil
2083
- }
2065
+ guard let definition = index. primaryDefinitionOrDeclarationOccurrence ( ofUSR: caller. usr) else {
2066
+ return nil
2067
+ }
2084
2068
2085
2069
let locations = calls. compactMap { indexToLSPLocation2 ( $0. location) } . sorted ( )
2086
2070
guard !locations. isEmpty else {
2087
2071
return nil
2088
2072
}
2073
+ guard let item = indexToLSPCallHierarchyItem2 ( definition: definition, index: index) else {
2074
+ return nil
2075
+ }
2089
2076
2090
- return CallHierarchyIncomingCall (
2091
- from: indexToLSPCallHierarchyItem2 (
2092
- symbol: caller,
2093
- containerName: containerName,
2094
- location: definitionLocation ?? locations. first!
2095
- ) ,
2096
- fromRanges: locations. map ( \. range)
2097
- )
2077
+ return CallHierarchyIncomingCall ( from: item, fromRanges: locations. map ( \. range) )
2098
2078
}
2099
2079
return calls. sorted ( by: { $0. from. name < $1. from. name } )
2100
2080
}
@@ -2113,11 +2093,10 @@ extension SourceKitLSPServer {
2113
2093
2114
2094
// TODO: Remove this workaround once https://github.com/swiftlang/swift/issues/75600 is fixed
2115
2095
func indexToLSPCallHierarchyItem2(
2116
- symbol: Symbol ,
2117
- containerName: String ? ,
2118
- location: Location
2119
- ) -> CallHierarchyItem {
2120
- return self . indexToLSPCallHierarchyItem ( symbol: symbol, containerName: containerName, location: location)
2096
+ definition: SymbolOccurrence ,
2097
+ index: CheckedIndex
2098
+ ) -> CallHierarchyItem ? {
2099
+ return self . indexToLSPCallHierarchyItem ( definition: definition, index: index)
2121
2100
}
2122
2101
2123
2102
let callableUsrs = [ data. usr] + index. occurrences ( relatedToUSR: data. usr, roles: . accessorOf) . map ( \. symbol. usr)
@@ -2131,37 +2110,32 @@ extension SourceKitLSPServer {
2131
2110
}
2132
2111
2133
2112
// Resolve the callee's definition to find its location
2134
- let definition = index. primaryDefinitionOrDeclarationOccurrence ( ofUSR: occurrence. symbol. usr)
2135
- let definitionSymbolLocation = definition? . location
2136
- let definitionLocation = definitionSymbolLocation. flatMap ( indexToLSPLocation2)
2137
- let containerName : String ? =
2138
- if let definition {
2139
- index. containerName ( of: definition)
2140
- } else {
2141
- nil
2142
- }
2113
+ guard let definition = index. primaryDefinitionOrDeclarationOccurrence ( ofUSR: occurrence. symbol. usr) else {
2114
+ return nil
2115
+ }
2143
2116
2144
- return CallHierarchyOutgoingCall (
2145
- to: indexToLSPCallHierarchyItem2 (
2146
- symbol: occurrence. symbol,
2147
- containerName: containerName,
2148
- location: definitionLocation ?? location // Use occurrence location as fallback
2149
- ) ,
2150
- fromRanges: [ location. range]
2151
- )
2117
+ guard let item = indexToLSPCallHierarchyItem2 ( definition: definition, index: index) else {
2118
+ return nil
2119
+ }
2120
+
2121
+ return CallHierarchyOutgoingCall ( to: item, fromRanges: [ location. range] )
2152
2122
}
2153
2123
return calls. sorted ( by: { $0. to. name < $1. to. name } )
2154
2124
}
2155
2125
2156
2126
private func indexToLSPTypeHierarchyItem(
2157
- symbol : Symbol ,
2127
+ definition : SymbolOccurrence ,
2158
2128
moduleName: String ? ,
2159
- location: Location ,
2160
2129
index: CheckedIndex
2161
- ) -> TypeHierarchyItem {
2130
+ ) -> TypeHierarchyItem ? {
2162
2131
let name : String
2163
2132
let detail : String ?
2164
2133
2134
+ guard let location = indexToLSPLocation ( definition. location) else {
2135
+ return nil
2136
+ }
2137
+
2138
+ let symbol = definition. symbol
2165
2139
switch symbol. kind {
2166
2140
case . extension:
2167
2141
// Query the conformance added by this extension
@@ -2182,7 +2156,7 @@ extension SourceKitLSPServer {
2182
2156
detail = " Extension "
2183
2157
}
2184
2158
default :
2185
- name = symbol . name
2159
+ name = index . fullyQualifiedName ( of : definition )
2186
2160
detail = moduleName
2187
2161
}
2188
2162
@@ -2231,16 +2205,12 @@ extension SourceKitLSPServer {
2231
2205
}
2232
2206
. compactMap ( \. usr)
2233
2207
let typeHierarchyItems = usrs. compactMap { ( usr) -> TypeHierarchyItem ? in
2234
- guard
2235
- let info = index. primaryDefinitionOrDeclarationOccurrence ( ofUSR: usr) ,
2236
- let location = indexToLSPLocation ( info. location)
2237
- else {
2208
+ guard let info = index. primaryDefinitionOrDeclarationOccurrence ( ofUSR: usr) else {
2238
2209
return nil
2239
2210
}
2240
2211
return self . indexToLSPTypeHierarchyItem (
2241
- symbol : info. symbol ,
2212
+ definition : info,
2242
2213
moduleName: info. location. moduleName,
2243
- location: location,
2244
2214
index: index
2245
2215
)
2246
2216
}
@@ -2305,30 +2275,28 @@ extension SourceKitLSPServer {
2305
2275
2306
2276
// TODO: Remove this workaround once https://github.com/swiftlang/swift/issues/75600 is fixed
2307
2277
func indexToLSPTypeHierarchyItem2(
2308
- symbol : Symbol ,
2278
+ definition : SymbolOccurrence ,
2309
2279
moduleName: String ? ,
2310
- location: Location ,
2311
2280
index: CheckedIndex
2312
- ) -> TypeHierarchyItem {
2313
- return self . indexToLSPTypeHierarchyItem ( symbol: symbol, moduleName: moduleName, location: location, index: index)
2281
+ ) -> TypeHierarchyItem ? {
2282
+ return self . indexToLSPTypeHierarchyItem (
2283
+ definition: definition,
2284
+ moduleName: moduleName,
2285
+ index: index
2286
+ )
2314
2287
}
2315
2288
2316
2289
// Convert occurrences to type hierarchy items
2317
2290
let occurs = baseOccurs + retroactiveConformanceOccurs
2318
2291
let types = occurs. compactMap { occurrence -> TypeHierarchyItem ? in
2319
- guard let location = indexToLSPLocation2 ( occurrence. location) else {
2292
+ // Resolve the supertype's definition to find its location
2293
+ guard let definition = index. primaryDefinitionOrDeclarationOccurrence ( ofUSR: occurrence. symbol. usr) else {
2320
2294
return nil
2321
2295
}
2322
2296
2323
- // Resolve the supertype's definition to find its location
2324
- let definition = index. primaryDefinitionOrDeclarationOccurrence ( ofUSR: occurrence. symbol. usr)
2325
- let definitionSymbolLocation = definition? . location
2326
- let definitionLocation = definitionSymbolLocation. flatMap ( indexToLSPLocation2)
2327
-
2328
2297
return indexToLSPTypeHierarchyItem2 (
2329
- symbol: occurrence. symbol,
2330
- moduleName: definitionSymbolLocation? . moduleName,
2331
- location: definitionLocation ?? location, // Use occurrence location as fallback
2298
+ definition: definition,
2299
+ moduleName: definition. location. moduleName,
2332
2300
index: index
2333
2301
)
2334
2302
}
@@ -2352,12 +2320,15 @@ extension SourceKitLSPServer {
2352
2320
2353
2321
// TODO: Remove this workaround once https://github.com/swiftlang/swift/issues/75600 is fixed
2354
2322
func indexToLSPTypeHierarchyItem2(
2355
- symbol : Symbol ,
2323
+ definition : SymbolOccurrence ,
2356
2324
moduleName: String ? ,
2357
- location: Location ,
2358
2325
index: CheckedIndex
2359
- ) -> TypeHierarchyItem {
2360
- return self . indexToLSPTypeHierarchyItem ( symbol: symbol, moduleName: moduleName, location: location, index: index)
2326
+ ) -> TypeHierarchyItem ? {
2327
+ return self . indexToLSPTypeHierarchyItem (
2328
+ definition: definition,
2329
+ moduleName: moduleName,
2330
+ index: index
2331
+ )
2361
2332
}
2362
2333
2363
2334
// Convert occurrences to type hierarchy items
@@ -2368,20 +2339,18 @@ extension SourceKitLSPServer {
2368
2339
// to.
2369
2340
logger. fault ( " Expected at most extendedBy or baseOf relation but got \( occurrence. relations. count) " )
2370
2341
}
2371
- guard let related = occurrence. relations. sorted ( ) . first, let location = indexToLSPLocation2 ( occurrence. location)
2372
- else {
2342
+ guard let related = occurrence. relations. sorted ( ) . first else {
2373
2343
return nil
2374
2344
}
2375
2345
2376
2346
// Resolve the subtype's definition to find its location
2377
- let definition = index. primaryDefinitionOrDeclarationOccurrence ( ofUSR: related. symbol. usr)
2378
- let definitionSymbolLocation = definition . map ( \ . location )
2379
- let definitionLocation = definitionSymbolLocation . flatMap ( indexToLSPLocation2 )
2347
+ guard let definition = index. primaryDefinitionOrDeclarationOccurrence ( ofUSR: related. symbol. usr) else {
2348
+ return nil
2349
+ }
2380
2350
2381
2351
return indexToLSPTypeHierarchyItem2 (
2382
- symbol: related. symbol,
2383
- moduleName: definitionSymbolLocation? . moduleName,
2384
- location: definitionLocation ?? location, // Use occurrence location as fallback
2352
+ definition: definition,
2353
+ moduleName: definition. location. moduleName,
2385
2354
index: index
2386
2355
)
2387
2356
}
@@ -2426,24 +2395,23 @@ private let maxWorkspaceSymbolResults = 4096
2426
2395
package typealias Diagnostic = LanguageServerProtocol . Diagnostic
2427
2396
2428
2397
fileprivate extension CheckedIndex {
2429
- /// Get the name of the symbol that is a parent of this symbol, if one exists
2430
- func containerName( of symbol: SymbolOccurrence ) -> String ? {
2398
+ func containerNames( of symbol: SymbolOccurrence ) -> [ String ] {
2431
2399
// The container name of accessors is the container of the surrounding variable.
2432
2400
let accessorOf = symbol. relations. filter { $0. roles. contains ( . accessorOf) }
2433
2401
if let primaryVariable = accessorOf. sorted ( ) . first {
2434
2402
if accessorOf. count > 1 {
2435
2403
logger. fault ( " Expected an occurrence to an accessor of at most one symbol, not multiple " )
2436
2404
}
2437
2405
if let primaryVariable = primaryDefinitionOrDeclarationOccurrence ( ofUSR: primaryVariable. symbol. usr) {
2438
- return containerName ( of: primaryVariable)
2406
+ return containerNames ( of: primaryVariable)
2439
2407
}
2440
2408
}
2441
2409
2442
2410
let containers = symbol. relations. filter { $0. roles. contains ( . childOf) }
2443
2411
if containers. count > 1 {
2444
2412
logger. fault ( " Expected an occurrence to a child of at most one symbol, not multiple " )
2445
2413
}
2446
- return containers. filter {
2414
+ let container = containers. filter {
2447
2415
switch $0. symbol. kind {
2448
2416
case . module, . namespace, . enum, . struct, . class, . protocol, . extension, . union:
2449
2417
return true
@@ -2452,7 +2420,39 @@ fileprivate extension CheckedIndex {
2452
2420
. destructor, . conversionFunction, . parameter, . using, . concept, . commentTag:
2453
2421
return false
2454
2422
}
2455
- } . sorted ( ) . first? . symbol. name
2423
+ } . sorted ( ) . first
2424
+
2425
+ if let container {
2426
+ if let containerDefinition = primaryDefinitionOrDeclarationOccurrence ( ofUSR: container. symbol. usr) {
2427
+ return self . containerNames ( of: containerDefinition) + [ container. symbol. name]
2428
+ }
2429
+ return [ container. symbol. name]
2430
+ } else {
2431
+ return [ ]
2432
+ }
2433
+ }
2434
+
2435
+ /// Take the name of containers into account to form a fully-qualified name for the given symbol.
2436
+ /// This means that we will form names of nested types and type-qualify methods.
2437
+ func fullyQualifiedName( of symbolOccurrence: SymbolOccurrence ) -> String {
2438
+ let symbol = symbolOccurrence. symbol
2439
+ let containerNames = containerNames ( of: symbolOccurrence)
2440
+ guard let containerName = containerNames. last else {
2441
+ // No containers, so nothing to do.
2442
+ return symbol. name
2443
+ }
2444
+ switch symbol. language {
2445
+ case . objc where symbol. kind == . instanceMethod || symbol. kind == . instanceProperty:
2446
+ return " -[ \( containerName) \( symbol. name) ] "
2447
+ case . objc where symbol. kind == . classMethod || symbol. kind == . classProperty:
2448
+ return " +[ \( containerName) \( symbol. name) ] "
2449
+ case . cxx, . c, . objc:
2450
+ // C shouldn't have container names for call hierarchy and Objective-C should be covered above.
2451
+ // Fall back to using the C++ notation using `::`.
2452
+ return ( containerNames + [ symbol. name] ) . joined ( separator: " :: " )
2453
+ case . swift:
2454
+ return ( containerNames + [ symbol. name] ) . joined ( separator: " . " )
2455
+ }
2456
2456
}
2457
2457
}
2458
2458
0 commit comments