Skip to content

Commit 429f15f

Browse files
authored
connect memberOf relationship of default implementation targets to extension block symbol if extension block symbol format is used (#61406)
1 parent d398166 commit 429f15f

File tree

3 files changed

+68
-5
lines changed

3 files changed

+68
-5
lines changed

lib/SymbolGraphGen/SymbolGraph.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -412,11 +412,21 @@ void SymbolGraph::recordDefaultImplementationRelationships(Symbol S) {
412412

413413
// If P is from a different module, and it's being added to a type
414414
// from the current module, add a `memberOf` relation to the extended
415-
// protocol.
415+
// protocol or the respective extension block.
416416
if (!Walker.isOurModule(MemberVD->getModuleContext()) && VD->getDeclContext()) {
417-
if (auto *ExP = VD->getDeclContext()->getSelfNominalTypeDecl()) {
417+
if (const auto *Extension =
418+
dyn_cast_or_null<ExtensionDecl>(VD->getDeclContext())) {
419+
if (this->Walker.shouldBeRecordedAsExtension(Extension)) {
420+
recordEdge(Symbol(this, VD, nullptr),
421+
Symbol(this, Extension, nullptr),
422+
RelationshipKind::MemberOf());
423+
continue;
424+
}
425+
}
426+
if (auto *ExtendedProtocol =
427+
VD->getDeclContext()->getSelfNominalTypeDecl()) {
418428
recordEdge(Symbol(this, VD, nullptr),
419-
Symbol(this, ExP, nullptr),
429+
Symbol(this, ExtendedProtocol, nullptr),
420430
RelationshipKind::MemberOf());
421431
}
422432
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift %S/Inputs/RemoteP.swift -module-name RemoteP -emit-module -emit-module-path %t/
3+
// RUN: %target-build-swift %s -module-name External -emit-module -emit-module-path %t/ -I %t
4+
// RUN: %target-swift-symbolgraph-extract -module-name External -I %t -pretty-print -output-dir %t
5+
// RUN: %FileCheck %s --input-file %t/[email protected]
6+
// RUN: %FileCheck %s --input-file %t/[email protected] --check-prefix MEMBER
7+
8+
// RUN: %empty-directory(%t)
9+
// RUN: %target-build-swift %S/Inputs/RemoteP.swift -module-name RemoteP -emit-module -emit-module-path %t/
10+
// RUN: %target-build-swift %s -module-name External -emit-module -emit-module-path %t/ -I %t
11+
// RUN: %target-swift-symbolgraph-extract -module-name External -I %t -pretty-print -output-dir %t -emit-extension-block-symbols
12+
// RUN: %FileCheck %s --input-file %t/[email protected]
13+
// RUN: %FileCheck %s --input-file %t/[email protected] --check-prefix MEMBEREBS
14+
// RUN: %FileCheck %s --input-file %t/[email protected] --check-prefix EXTENSIONTOEBS
15+
16+
import RemoteP
17+
18+
public extension RemoteP {
19+
func someFunc() {}
20+
}
21+
22+
// Default implementations that are for protocols in a different module should have a `memberOf`
23+
// relation linking them to a local symbol. If the default implementation is not defined on a local
24+
// protocol, the extension block symbol defining the default implementation should be the target
25+
// of the memberOf relationship.
26+
27+
// CHECK: "kind": "defaultImplementationOf"
28+
// CHECK-NEXT: "source": "s:7RemotePAAP8ExternalE8someFuncyyF"
29+
// CHECK-NEXT: "target": "s:7RemotePAAP8someFuncyyF"
30+
// CHECK-NEXT: "targetFallback": "RemoteP.RemoteP.someFunc()"
31+
32+
// MEMBER: "kind": "memberOf"
33+
// MEMBER-NEXT: "source": "s:7RemotePAAP8ExternalE8someFuncyyF"
34+
// MEMBER-NEXT: "target": "s:7RemotePAAP"
35+
// MEMBER-NEXT: "targetFallback": "RemoteP.RemoteP"
36+
37+
// MEMBEREBS: "kind": "memberOf"
38+
// MEMBEREBS-NEXT: "source": "s:7RemotePAAP8ExternalE8someFuncyyF"
39+
// MEMBEREBS-NEXT: "target": "s:e:s:7RemotePAAP8ExternalE8someFuncyyF"
40+
// MEMBEREBS-NEXT: "targetFallback": "RemoteP.RemoteP"
41+
42+
// EXTENSIONTOEBS: "kind": "extensionTo"
43+
// EXTENSIONTOEBS-NEXT: "source": "s:e:s:7RemotePAAP8ExternalE8someFuncyyF"
44+
// EXTENSIONTOEBS-NEXT: "target": "s:7RemotePAAP"
45+
// EXTENSIONTOEBS-NEXT: "targetFallback": "RemoteP.RemoteP"

test/SymbolGraph/Relationships/DefaultImplementationOf/Remote.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
// RUN: %FileCheck %s --input-file %t/Remote.symbols.json
66
// RUN: %FileCheck %s --input-file %t/Remote.symbols.json --check-prefix MEMBER
77

8+
// RUN: %empty-directory(%t)
9+
// RUN: %target-build-swift %S/Inputs/RemoteP.swift -module-name RemoteP -emit-module -emit-module-path %t/
10+
// RUN: %target-build-swift %s -module-name Remote -emit-module -emit-module-path %t/ -I %t
11+
// RUN: %target-swift-symbolgraph-extract -module-name Remote -I %t -pretty-print -output-dir %t -emit-extension-block-symbols
12+
// RUN: %FileCheck %s --input-file %t/Remote.symbols.json
13+
// RUN: %FileCheck %s --input-file %t/Remote.symbols.json --check-prefix MEMBER
14+
815
import RemoteP
916

1017
public protocol LocalP: RemoteP {}
@@ -13,8 +20,9 @@ public extension LocalP {
1320
func someFunc() {}
1421
}
1522

16-
// default implementations that are for protocols in a different module should have a `memberOf`
17-
// relation linking them to a local symbol, if one exists
23+
// Default implementations that are for protocols in a different module should have a `memberOf`
24+
// relation linking them to a local symbol. If the default implementation is defined on a local
25+
// protocol, this local protocol is the target of the memberOf relationship.
1826

1927
// CHECK: "kind": "defaultImplementationOf"
2028
// CHECK-NEXT: "source": "s:6Remote6LocalPPAAE8someFuncyyF"

0 commit comments

Comments
 (0)