@@ -1682,9 +1682,8 @@ extension SourceKitServer {
1682
1682
return [ ]
1683
1683
}
1684
1684
1685
- if let symbol = symbols. first, let bestLocalDeclaration = symbol. bestLocalDeclaration, !( symbol. isDynamic ?? false )
1686
- {
1687
- // If we have a non-dynamic symbol, we don't need to do an index lookup
1685
+ if let bestLocalDeclaration = symbol. bestLocalDeclaration, !( symbol. isDynamic ?? true ) {
1686
+ // If we have a known non-dynamic symbol, we don't need to do an index lookup
1688
1687
return [ bestLocalDeclaration]
1689
1688
}
1690
1689
@@ -1704,38 +1703,49 @@ extension SourceKitServer {
1704
1703
}
1705
1704
guard let usr = symbol. usr else { return [ ] }
1706
1705
logger. info ( " performing indexed jump-to-def with usr \( usr) " )
1707
- var occurances = index. occurrences ( ofUSR: usr, roles: [ . definition] )
1708
- if occurances. isEmpty {
1709
- occurances = index. occurrences ( ofUSR: usr, roles: [ . declaration] )
1710
- }
1711
- if symbol. isDynamic ?? false {
1712
- lazy var transitiveReceiverUsrs : [ String ] = transitiveSubtypeClosure (
1713
- ofUsrs: symbol. receiverUsrs ?? [ ] ,
1714
- index: index
1715
- )
1716
- occurances += occurances. flatMap {
1706
+ var occurrences = index. occurrences ( ofUSR: usr, roles: [ . definition] )
1707
+ if occurrences. isEmpty {
1708
+ occurrences = index. occurrences ( ofUSR: usr, roles: [ . declaration] )
1709
+ }
1710
+ if symbol. isDynamic ?? true {
1711
+ lazy var transitiveReceiverUsrs : [ String ] ? = {
1712
+ if let receiverUsrs = symbol. receiverUsrs {
1713
+ return transitiveSubtypeClosure (
1714
+ ofUsrs: receiverUsrs,
1715
+ index: index
1716
+ )
1717
+ } else {
1718
+ return nil
1719
+ }
1720
+ } ( )
1721
+ occurrences += occurrences. flatMap {
1717
1722
let overrides = index. occurrences ( relatedToUSR: $0. symbol. usr, roles: . overrideOf)
1718
1723
// Only contain overrides that are children of one of the receiver types or their subtypes.
1719
1724
return overrides. filter { override in
1720
1725
override. relations. contains ( where: {
1721
- $0. roles. contains ( . childOf) && transitiveReceiverUsrs. contains ( $0. symbol. usr)
1726
+ guard $0. roles. contains ( . childOf) else {
1727
+ return false
1728
+ }
1729
+ if let transitiveReceiverUsrs, !transitiveReceiverUsrs. contains ( $0. symbol. usr) {
1730
+ return false
1731
+ }
1732
+ return true
1722
1733
} )
1723
1734
}
1724
1735
}
1725
1736
}
1726
1737
1727
- return try await occurances. asyncCompactMap { occurance in
1728
- if URL ( fileURLWithPath: occurance. location. path) . pathExtension == " swiftinterface " {
1729
- // if first resolved location is in `.swiftinterface` file. Use moduleName to return
1730
- // textual interface
1738
+ return try await occurrences. asyncCompactMap { occurrence in
1739
+ if URL ( fileURLWithPath: occurrence. location. path) . pathExtension == " swiftinterface " {
1740
+ // If the location is in `.swiftinterface` file, use moduleName to return textual interface.
1731
1741
return try await self . definitionInInterface (
1732
1742
req,
1733
- moduleName: occurance . location. moduleName,
1734
- symbolUSR: occurance . symbol. usr,
1743
+ moduleName: occurrence . location. moduleName,
1744
+ symbolUSR: occurrence . symbol. usr,
1735
1745
languageService: languageService
1736
1746
)
1737
1747
}
1738
- return indexToLSPLocation ( occurance . location)
1748
+ return indexToLSPLocation ( occurrence . location)
1739
1749
}
1740
1750
}
1741
1751
@@ -1747,10 +1757,14 @@ extension SourceKitServer {
1747
1757
let indexBasedResponse = try await indexBasedDefinition ( req, workspace: workspace, languageService: languageService)
1748
1758
// If we're unable to handle the definition request using our index, see if the
1749
1759
// language service can handle it (e.g. clangd can provide AST based definitions).
1760
+ // We are on only calling the language service's `definition` function if your index-based lookup failed.
1761
+ // If this fallback request fails, its error is usually not very enlightening. For example the `SwiftLanguageServer`
1762
+ // will always respond with `unsupported method`. Thus, only log such a failure instead of returning it to the
1763
+ // client.
1750
1764
if indexBasedResponse. isEmpty {
1751
- do {
1765
+ return await orLog ( " Fallback definition request " ) {
1752
1766
return try await languageService. definition ( req)
1753
- } catch { }
1767
+ }
1754
1768
}
1755
1769
return . locations( indexBasedResponse)
1756
1770
}
0 commit comments