@@ -1444,13 +1444,24 @@ extension SourceKitLSPServer {
1444
1444
range: Range ( symbolPosition)
1445
1445
)
1446
1446
1447
+ let containerNames = index. containerNames ( of: symbolOccurrence)
1448
+ let containerName : String ?
1449
+ if containerNames. isEmpty {
1450
+ containerName = nil
1451
+ } else {
1452
+ switch symbolOccurrence. symbol. language {
1453
+ case . cxx, . c, . objc: containerName = containerNames. joined ( separator: " :: " )
1454
+ case . swift: containerName = containerNames. joined ( separator: " . " )
1455
+ }
1456
+ }
1457
+
1447
1458
return WorkspaceSymbolItem . symbolInformation (
1448
1459
SymbolInformation (
1449
1460
name: symbolOccurrence. symbol. name,
1450
1461
kind: symbolOccurrence. symbol. kind. asLspSymbolKind ( ) ,
1451
1462
deprecated: nil ,
1452
1463
location: symbolLocation,
1453
- containerName: index . containerName ( of : symbolOccurrence )
1464
+ containerName: containerName
1454
1465
)
1455
1466
)
1456
1467
}
@@ -1916,27 +1927,14 @@ extension SourceKitLSPServer {
1916
1927
}
1917
1928
1918
1929
private func indexToLSPCallHierarchyItem(
1919
- symbol: Symbol ,
1920
- containerName: String ? ,
1921
- location: Location
1922
- ) -> CallHierarchyItem {
1923
- let name : String
1924
- if let containerName {
1925
- switch symbol. language {
1926
- case . objc where symbol. kind == . instanceMethod || symbol. kind == . instanceProperty:
1927
- name = " -[ \( containerName) \( symbol. name) ] "
1928
- case . objc where symbol. kind == . classMethod || symbol. kind == . classProperty:
1929
- name = " +[ \( containerName) \( symbol. name) ] "
1930
- case . cxx, . c, . objc:
1931
- // C shouldn't have container names for call hierarchy and Objective-C should be covered above.
1932
- // Fall back to using the C++ notation using `::`.
1933
- name = " \( containerName) :: \( symbol. name) "
1934
- case . swift:
1935
- name = " \( containerName) . \( symbol. name) "
1936
- }
1937
- } else {
1938
- name = symbol. name
1930
+ definition: SymbolOccurrence ,
1931
+ index: CheckedIndex
1932
+ ) -> CallHierarchyItem ? {
1933
+ guard let location = indexToLSPLocation ( definition. location) else {
1934
+ return nil
1939
1935
}
1936
+ let name = index. fullyQualifiedName ( of: definition)
1937
+ let symbol = definition. symbol
1940
1938
return CallHierarchyItem (
1941
1939
name: name,
1942
1940
kind: symbol. kind. asLspSymbolKind ( ) ,
@@ -1976,14 +1974,7 @@ extension SourceKitLSPServer {
1976
1974
guard let definition = index. primaryDefinitionOrDeclarationOccurrence ( ofUSR: usr) else {
1977
1975
return nil
1978
1976
}
1979
- guard let location = indexToLSPLocation ( definition. location) else {
1980
- return nil
1981
- }
1982
- return self . indexToLSPCallHierarchyItem (
1983
- symbol: definition. symbol,
1984
- containerName: index. containerName ( of: definition) ,
1985
- location: location
1986
- )
1977
+ return self . indexToLSPCallHierarchyItem ( definition: definition, index: index)
1987
1978
} . sorted ( by: { Location ( uri: $0. uri, range: $0. range) < Location ( uri: $1. uri, range: $1. range) } )
1988
1979
1989
1980
// Ideally, we should show multiple symbols. But VS Code fails to display call hierarchies with multiple root items,
@@ -2045,38 +2036,27 @@ extension SourceKitLSPServer {
2045
2036
2046
2037
// TODO: Remove this workaround once https://github.com/swiftlang/swift/issues/75600 is fixed
2047
2038
func indexToLSPCallHierarchyItem2(
2048
- symbol: Symbol ,
2049
- containerName: String ? ,
2050
- location: Location
2051
- ) -> CallHierarchyItem {
2052
- return self . indexToLSPCallHierarchyItem ( symbol: symbol, containerName: containerName, location: location)
2039
+ definition: SymbolOccurrence ,
2040
+ index: CheckedIndex
2041
+ ) -> CallHierarchyItem ? {
2042
+ return self . indexToLSPCallHierarchyItem ( definition: definition, index: index)
2053
2043
}
2054
2044
2055
2045
let calls = callersToCalls. compactMap { ( caller: Symbol , calls: [ SymbolOccurrence ] ) -> CallHierarchyIncomingCall ? in
2056
2046
// Resolve the caller's definition to find its location
2057
- let definition = index. primaryDefinitionOrDeclarationOccurrence ( ofUSR: caller. usr)
2058
- let definitionSymbolLocation = definition? . location
2059
- let definitionLocation = definitionSymbolLocation. flatMap ( indexToLSPLocation2)
2060
- let containerName : String ? =
2061
- if let definition {
2062
- index. containerName ( of: definition)
2063
- } else {
2064
- nil
2065
- }
2047
+ guard let definition = index. primaryDefinitionOrDeclarationOccurrence ( ofUSR: caller. usr) else {
2048
+ return nil
2049
+ }
2066
2050
2067
2051
let locations = calls. compactMap { indexToLSPLocation2 ( $0. location) } . sorted ( )
2068
2052
guard !locations. isEmpty else {
2069
2053
return nil
2070
2054
}
2055
+ guard let item = indexToLSPCallHierarchyItem2 ( definition: definition, index: index) else {
2056
+ return nil
2057
+ }
2071
2058
2072
- return CallHierarchyIncomingCall (
2073
- from: indexToLSPCallHierarchyItem2 (
2074
- symbol: caller,
2075
- containerName: containerName,
2076
- location: definitionLocation ?? locations. first!
2077
- ) ,
2078
- fromRanges: locations. map ( \. range)
2079
- )
2059
+ return CallHierarchyIncomingCall ( from: item, fromRanges: locations. map ( \. range) )
2080
2060
}
2081
2061
return calls. sorted ( by: { $0. from. name < $1. from. name } )
2082
2062
}
@@ -2095,11 +2075,10 @@ extension SourceKitLSPServer {
2095
2075
2096
2076
// TODO: Remove this workaround once https://github.com/swiftlang/swift/issues/75600 is fixed
2097
2077
func indexToLSPCallHierarchyItem2(
2098
- symbol: Symbol ,
2099
- containerName: String ? ,
2100
- location: Location
2101
- ) -> CallHierarchyItem {
2102
- return self . indexToLSPCallHierarchyItem ( symbol: symbol, containerName: containerName, location: location)
2078
+ definition: SymbolOccurrence ,
2079
+ index: CheckedIndex
2080
+ ) -> CallHierarchyItem ? {
2081
+ return self . indexToLSPCallHierarchyItem ( definition: definition, index: index)
2103
2082
}
2104
2083
2105
2084
let callableUsrs = [ data. usr] + index. occurrences ( relatedToUSR: data. usr, roles: . accessorOf) . map ( \. symbol. usr)
@@ -2113,37 +2092,32 @@ extension SourceKitLSPServer {
2113
2092
}
2114
2093
2115
2094
// Resolve the callee's definition to find its location
2116
- let definition = index. primaryDefinitionOrDeclarationOccurrence ( ofUSR: occurrence. symbol. usr)
2117
- let definitionSymbolLocation = definition? . location
2118
- let definitionLocation = definitionSymbolLocation. flatMap ( indexToLSPLocation2)
2119
- let containerName : String ? =
2120
- if let definition {
2121
- index. containerName ( of: definition)
2122
- } else {
2123
- nil
2124
- }
2095
+ guard let definition = index. primaryDefinitionOrDeclarationOccurrence ( ofUSR: occurrence. symbol. usr) else {
2096
+ return nil
2097
+ }
2125
2098
2126
- return CallHierarchyOutgoingCall (
2127
- to: indexToLSPCallHierarchyItem2 (
2128
- symbol: occurrence. symbol,
2129
- containerName: containerName,
2130
- location: definitionLocation ?? location // Use occurrence location as fallback
2131
- ) ,
2132
- fromRanges: [ location. range]
2133
- )
2099
+ guard let item = indexToLSPCallHierarchyItem2 ( definition: definition, index: index) else {
2100
+ return nil
2101
+ }
2102
+
2103
+ return CallHierarchyOutgoingCall ( to: item, fromRanges: [ location. range] )
2134
2104
}
2135
2105
return calls. sorted ( by: { $0. to. name < $1. to. name } )
2136
2106
}
2137
2107
2138
2108
private func indexToLSPTypeHierarchyItem(
2139
- symbol : Symbol ,
2109
+ definition : SymbolOccurrence ,
2140
2110
moduleName: String ? ,
2141
- location: Location ,
2142
2111
index: CheckedIndex
2143
- ) -> TypeHierarchyItem {
2112
+ ) -> TypeHierarchyItem ? {
2144
2113
let name : String
2145
2114
let detail : String ?
2146
2115
2116
+ guard let location = indexToLSPLocation ( definition. location) else {
2117
+ return nil
2118
+ }
2119
+
2120
+ let symbol = definition. symbol
2147
2121
switch symbol. kind {
2148
2122
case . extension:
2149
2123
// Query the conformance added by this extension
@@ -2164,7 +2138,7 @@ extension SourceKitLSPServer {
2164
2138
detail = " Extension "
2165
2139
}
2166
2140
default :
2167
- name = symbol . name
2141
+ name = index . fullyQualifiedName ( of : definition )
2168
2142
detail = moduleName
2169
2143
}
2170
2144
@@ -2213,16 +2187,12 @@ extension SourceKitLSPServer {
2213
2187
}
2214
2188
. compactMap ( \. usr)
2215
2189
let typeHierarchyItems = usrs. compactMap { ( usr) -> TypeHierarchyItem ? in
2216
- guard
2217
- let info = index. primaryDefinitionOrDeclarationOccurrence ( ofUSR: usr) ,
2218
- let location = indexToLSPLocation ( info. location)
2219
- else {
2190
+ guard let info = index. primaryDefinitionOrDeclarationOccurrence ( ofUSR: usr) else {
2220
2191
return nil
2221
2192
}
2222
2193
return self . indexToLSPTypeHierarchyItem (
2223
- symbol : info. symbol ,
2194
+ definition : info,
2224
2195
moduleName: info. location. moduleName,
2225
- location: location,
2226
2196
index: index
2227
2197
)
2228
2198
}
@@ -2287,30 +2257,28 @@ extension SourceKitLSPServer {
2287
2257
2288
2258
// TODO: Remove this workaround once https://github.com/swiftlang/swift/issues/75600 is fixed
2289
2259
func indexToLSPTypeHierarchyItem2(
2290
- symbol : Symbol ,
2260
+ definition : SymbolOccurrence ,
2291
2261
moduleName: String ? ,
2292
- location: Location ,
2293
2262
index: CheckedIndex
2294
- ) -> TypeHierarchyItem {
2295
- return self . indexToLSPTypeHierarchyItem ( symbol: symbol, moduleName: moduleName, location: location, index: index)
2263
+ ) -> TypeHierarchyItem ? {
2264
+ return self . indexToLSPTypeHierarchyItem (
2265
+ definition: definition,
2266
+ moduleName: moduleName,
2267
+ index: index
2268
+ )
2296
2269
}
2297
2270
2298
2271
// Convert occurrences to type hierarchy items
2299
2272
let occurs = baseOccurs + retroactiveConformanceOccurs
2300
2273
let types = occurs. compactMap { occurrence -> TypeHierarchyItem ? in
2301
- guard let location = indexToLSPLocation2 ( occurrence. location) else {
2274
+ // Resolve the supertype's definition to find its location
2275
+ guard let definition = index. primaryDefinitionOrDeclarationOccurrence ( ofUSR: occurrence. symbol. usr) else {
2302
2276
return nil
2303
2277
}
2304
2278
2305
- // Resolve the supertype's definition to find its location
2306
- let definition = index. primaryDefinitionOrDeclarationOccurrence ( ofUSR: occurrence. symbol. usr)
2307
- let definitionSymbolLocation = definition? . location
2308
- let definitionLocation = definitionSymbolLocation. flatMap ( indexToLSPLocation2)
2309
-
2310
2279
return indexToLSPTypeHierarchyItem2 (
2311
- symbol: occurrence. symbol,
2312
- moduleName: definitionSymbolLocation? . moduleName,
2313
- location: definitionLocation ?? location, // Use occurrence location as fallback
2280
+ definition: definition,
2281
+ moduleName: definition. location. moduleName,
2314
2282
index: index
2315
2283
)
2316
2284
}
@@ -2334,12 +2302,15 @@ extension SourceKitLSPServer {
2334
2302
2335
2303
// TODO: Remove this workaround once https://github.com/swiftlang/swift/issues/75600 is fixed
2336
2304
func indexToLSPTypeHierarchyItem2(
2337
- symbol : Symbol ,
2305
+ definition : SymbolOccurrence ,
2338
2306
moduleName: String ? ,
2339
- location: Location ,
2340
2307
index: CheckedIndex
2341
- ) -> TypeHierarchyItem {
2342
- return self . indexToLSPTypeHierarchyItem ( symbol: symbol, moduleName: moduleName, location: location, index: index)
2308
+ ) -> TypeHierarchyItem ? {
2309
+ return self . indexToLSPTypeHierarchyItem (
2310
+ definition: definition,
2311
+ moduleName: moduleName,
2312
+ index: index
2313
+ )
2343
2314
}
2344
2315
2345
2316
// Convert occurrences to type hierarchy items
@@ -2350,20 +2321,18 @@ extension SourceKitLSPServer {
2350
2321
// to.
2351
2322
logger. fault ( " Expected at most extendedBy or baseOf relation but got \( occurrence. relations. count) " )
2352
2323
}
2353
- guard let related = occurrence. relations. sorted ( ) . first, let location = indexToLSPLocation2 ( occurrence. location)
2354
- else {
2324
+ guard let related = occurrence. relations. sorted ( ) . first else {
2355
2325
return nil
2356
2326
}
2357
2327
2358
2328
// Resolve the subtype's definition to find its location
2359
- let definition = index. primaryDefinitionOrDeclarationOccurrence ( ofUSR: related. symbol. usr)
2360
- let definitionSymbolLocation = definition . map ( \ . location )
2361
- let definitionLocation = definitionSymbolLocation . flatMap ( indexToLSPLocation2 )
2329
+ guard let definition = index. primaryDefinitionOrDeclarationOccurrence ( ofUSR: related. symbol. usr) else {
2330
+ return nil
2331
+ }
2362
2332
2363
2333
return indexToLSPTypeHierarchyItem2 (
2364
- symbol: related. symbol,
2365
- moduleName: definitionSymbolLocation? . moduleName,
2366
- location: definitionLocation ?? location, // Use occurrence location as fallback
2334
+ definition: definition,
2335
+ moduleName: definition. location. moduleName,
2367
2336
index: index
2368
2337
)
2369
2338
}
@@ -2408,24 +2377,23 @@ private let maxWorkspaceSymbolResults = 4096
2408
2377
package typealias Diagnostic = LanguageServerProtocol . Diagnostic
2409
2378
2410
2379
fileprivate extension CheckedIndex {
2411
- /// Get the name of the symbol that is a parent of this symbol, if one exists
2412
- func containerName( of symbol: SymbolOccurrence ) -> String ? {
2380
+ func containerNames( of symbol: SymbolOccurrence ) -> [ String ] {
2413
2381
// The container name of accessors is the container of the surrounding variable.
2414
2382
let accessorOf = symbol. relations. filter { $0. roles. contains ( . accessorOf) }
2415
2383
if let primaryVariable = accessorOf. sorted ( ) . first {
2416
2384
if accessorOf. count > 1 {
2417
2385
logger. fault ( " Expected an occurrence to an accessor of at most one symbol, not multiple " )
2418
2386
}
2419
2387
if let primaryVariable = primaryDefinitionOrDeclarationOccurrence ( ofUSR: primaryVariable. symbol. usr) {
2420
- return containerName ( of: primaryVariable)
2388
+ return containerNames ( of: primaryVariable)
2421
2389
}
2422
2390
}
2423
2391
2424
2392
let containers = symbol. relations. filter { $0. roles. contains ( . childOf) }
2425
2393
if containers. count > 1 {
2426
2394
logger. fault ( " Expected an occurrence to a child of at most one symbol, not multiple " )
2427
2395
}
2428
- return containers. filter {
2396
+ let container = containers. filter {
2429
2397
switch $0. symbol. kind {
2430
2398
case . module, . namespace, . enum, . struct, . class, . protocol, . extension, . union:
2431
2399
return true
@@ -2434,7 +2402,39 @@ fileprivate extension CheckedIndex {
2434
2402
. destructor, . conversionFunction, . parameter, . using, . concept, . commentTag:
2435
2403
return false
2436
2404
}
2437
- } . sorted ( ) . first? . symbol. name
2405
+ } . sorted ( ) . first
2406
+
2407
+ if let container {
2408
+ if let containerDefinition = primaryDefinitionOrDeclarationOccurrence ( ofUSR: container. symbol. usr) {
2409
+ return self . containerNames ( of: containerDefinition) + [ container. symbol. name]
2410
+ }
2411
+ return [ container. symbol. name]
2412
+ } else {
2413
+ return [ ]
2414
+ }
2415
+ }
2416
+
2417
+ /// Take the name of containers into account to form a fully-qualified name for the given symbol.
2418
+ /// This means that we will form names of nested types and type-qualify methods.
2419
+ func fullyQualifiedName( of symbolOccurrence: SymbolOccurrence ) -> String {
2420
+ let symbol = symbolOccurrence. symbol
2421
+ let containerNames = containerNames ( of: symbolOccurrence)
2422
+ guard let containerName = containerNames. last else {
2423
+ // No containers, so nothing to do.
2424
+ return symbol. name
2425
+ }
2426
+ switch symbol. language {
2427
+ case . objc where symbol. kind == . instanceMethod || symbol. kind == . instanceProperty:
2428
+ return " -[ \( containerName) \( symbol. name) ] "
2429
+ case . objc where symbol. kind == . classMethod || symbol. kind == . classProperty:
2430
+ return " +[ \( containerName) \( symbol. name) ] "
2431
+ case . cxx, . c, . objc:
2432
+ // C shouldn't have container names for call hierarchy and Objective-C should be covered above.
2433
+ // Fall back to using the C++ notation using `::`.
2434
+ return ( containerNames + [ symbol. name] ) . joined ( separator: " :: " )
2435
+ case . swift:
2436
+ return ( containerNames + [ symbol. name] ) . joined ( separator: " . " )
2437
+ }
2438
2438
}
2439
2439
}
2440
2440
0 commit comments