Skip to content

Commit 55ef104

Browse files
authored
Merge pull request #1464 from ahoppen/protocol-requirement-satisfied-in-extension
Show protocol requirements satisfied in extensions in jump-to-definition
2 parents 2d2bac8 + 0c42c01 commit 55ef104

File tree

2 files changed

+33
-6
lines changed

2 files changed

+33
-6
lines changed

Sources/SourceKitLSP/SourceKitLSPServer.swift

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1717,9 +1717,12 @@ extension SourceKitLSPServer {
17171717
}
17181718
}()
17191719
occurrences += occurrences.flatMap {
1720-
let overrides = index.occurrences(relatedToUSR: $0.symbol.usr, roles: .overrideOf)
1721-
// Only contain overrides that are children of one of the receiver types or their subtypes.
1722-
return overrides.filter { override in
1720+
let overriddenUsrs = index.occurrences(relatedToUSR: $0.symbol.usr, roles: .overrideOf).map(\.symbol.usr)
1721+
let overriddenSymbolDefinitions = overriddenUsrs.compactMap {
1722+
index.primaryDefinitionOrDeclarationOccurrence(ofUSR: $0)
1723+
}
1724+
// Only contain overrides that are children of one of the receiver types or their subtypes or extensions.
1725+
return overriddenSymbolDefinitions.filter { override in
17231726
override.relations.contains(where: {
17241727
guard $0.roles.contains(.childOf) else {
17251728
return false
@@ -2473,13 +2476,13 @@ fileprivate struct DocumentNotificationRequestQueue {
24732476
}
24742477
}
24752478

2476-
/// Returns the USRs of the subtypes of `usrs` as well as their subtypes, transitively.
2479+
/// Returns the USRs of the subtypes of `usrs` as well as their subtypes and extensions, transitively.
24772480
fileprivate func transitiveSubtypeClosure(ofUsrs usrs: [String], index: CheckedIndex) -> [String] {
24782481
var result: [String] = []
24792482
for usr in usrs {
24802483
result.append(usr)
2481-
let directSubtypes = index.occurrences(ofUSR: usr, roles: .baseOf).flatMap { occurrence in
2482-
occurrence.relations.filter { $0.roles.contains(.baseOf) }.map(\.symbol.usr)
2484+
let directSubtypes = index.occurrences(ofUSR: usr, roles: [.baseOf, .extendedBy]).flatMap { occurrence in
2485+
occurrence.relations.filter { $0.roles.contains(.baseOf) || $0.roles.contains(.extendedBy) }.map(\.symbol.usr)
24832486
}
24842487
let transitiveSubtypes = transitiveSubtypeClosure(ofUsrs: directSubtypes, index: index)
24852488
result += transitiveSubtypes

Tests/SourceKitLSPTests/DefinitionTests.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,4 +601,28 @@ class DefinitionTests: XCTestCase {
601601
])
602602
)
603603
}
604+
605+
func testJumpToSatisfiedProtocolRequirementInExtension() async throws {
606+
let project = try await IndexedSingleSwiftFileTestProject(
607+
"""
608+
protocol TestProtocol {
609+
func 1️⃣doThing()
610+
}
611+
612+
struct TestImpl: TestProtocol {}
613+
extension TestImpl {
614+
func 2️⃣doThing() { }
615+
}
616+
"""
617+
)
618+
619+
let response = try await project.testClient.send(
620+
DefinitionRequest(textDocument: TextDocumentIdentifier(project.fileURI), position: project.positions["1️⃣"])
621+
)
622+
guard case .locations(let locations) = response else {
623+
XCTFail("Expected locations response")
624+
return
625+
}
626+
XCTAssertEqual(locations, [Location(uri: project.fileURI, range: Range(project.positions["2️⃣"]))])
627+
}
604628
}

0 commit comments

Comments
 (0)