Skip to content

Commit 51c96a4

Browse files
Merge pull request #37351 from apple/QuietMisdreavus/protocol-req-sourceOrigin
[SymbolGraph] add sourceOrigin field for symbols implementing remote protocol requirements
2 parents 63b85fd + 8ae8dbc commit 51c96a4

File tree

3 files changed

+110
-0
lines changed

3 files changed

+110
-0
lines changed

lib/SymbolGraphGen/Edge.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,29 @@
1515
#include "Symbol.h"
1616
#include "SymbolGraphASTWalker.h"
1717

18+
#include <queue>
19+
1820
using namespace swift;
1921
using namespace symbolgraphgen;
2022

23+
namespace {
24+
const ValueDecl *getForeignProtocolRequirement(const ValueDecl *VD, const ModuleDecl *M) {
25+
std::queue<const ValueDecl *> requirements;
26+
while (true) {
27+
for (auto *req : VD->getSatisfiedProtocolRequirements()) {
28+
if (req->getModuleContext()->getNameStr() != M->getNameStr())
29+
return req;
30+
else
31+
requirements.push(req);
32+
}
33+
if (requirements.empty())
34+
return nullptr;
35+
VD = requirements.front();
36+
requirements.pop();
37+
}
38+
}
39+
} // end anonymous namespace
40+
2141
void Edge::serialize(llvm::json::OStream &OS) const {
2242
OS.object([&](){
2343
OS.attribute("kind", Kind.Name);
@@ -66,6 +86,11 @@ void Edge::serialize(llvm::json::OStream &OS) const {
6686

6787
if (!InheritingDecl && Source.getSynthesizedBaseTypeDecl())
6888
InheritingDecl = Source.getSymbolDecl();
89+
90+
if (!InheritingDecl) {
91+
if (const auto *ID = getForeignProtocolRequirement(Source.getSymbolDecl(), &Graph->M))
92+
InheritingDecl = ID;
93+
}
6994

7095
// If our source symbol is a inheriting decl, write in information about
7196
// where it's inheriting docs from.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/// Some Protocol
2+
public protocol P {
3+
func someFunc()
4+
5+
/// This one has docs!
6+
func otherFunc()
7+
8+
func bonusFunc()
9+
}
10+
11+
public extension P {
12+
/// Extra default docs!
13+
func extraFunc() {}
14+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend %S/Inputs/RemoteP.swift -module-name RemoteP -emit-module -emit-module-path %t/RemoteP.swiftmodule -emit-module-source-info-path %t/RemoteP.swiftsourceinfo -emit-module-doc-path %t/RemoteP.swiftdoc
3+
// RUN: %target-swift-frontend %s -module-name RemoteInheritedDocs -emit-module -emit-module-path %t/RemoteInheritedDocs.swiftmodule -emit-module-source-info-path %t/RemoteInheritedDocs.swiftsourceinfo -emit-module-doc-path %t/RemoteInheritedDocs.swiftdoc -I %t
4+
5+
// RUN: %target-swift-symbolgraph-extract -module-name RemoteInheritedDocs -I %t -pretty-print -output-dir %t
6+
// RUN: %FileCheck %s --input-file %t/RemoteInheritedDocs.symbols.json --check-prefix SOME
7+
// RUN: %FileCheck %s --input-file %t/RemoteInheritedDocs.symbols.json --check-prefix OTHER
8+
// RUN: %FileCheck %s --input-file %t/RemoteInheritedDocs.symbols.json --check-prefix BONUS
9+
// RUN: %FileCheck %s --input-file %t/RemoteInheritedDocs.symbols.json --check-prefix INHERIT
10+
// RUN: %FileCheck %s --input-file %t/RemoteInheritedDocs.symbols.json --check-prefix LOCAL
11+
// RUN: %FileCheck %s --input-file %t/RemoteInheritedDocs.symbols.json --check-prefix OVERRIDE
12+
13+
// RUN: %target-swift-symbolgraph-extract -module-name RemoteInheritedDocs -I %t -pretty-print -output-dir %t -skip-inherited-docs
14+
// RUN: %FileCheck %s --input-file %t/RemoteInheritedDocs.symbols.json --check-prefix SOME
15+
// RUN: %FileCheck %s --input-file %t/RemoteInheritedDocs.symbols.json --check-prefix OTHER
16+
// RUN: %FileCheck %s --input-file %t/RemoteInheritedDocs.symbols.json --check-prefix BONUS
17+
// RUN: %FileCheck %s --input-file %t/RemoteInheritedDocs.symbols.json --check-prefix SKIP
18+
// RUN: %FileCheck %s --input-file %t/RemoteInheritedDocs.symbols.json --check-prefix LOCAL
19+
// RUN: %FileCheck %s --input-file %t/RemoteInheritedDocs.symbols.json --check-prefix OVERRIDE
20+
21+
// SOME: "source": "s:19RemoteInheritedDocs1SV8someFuncyyF"
22+
// SOME-NEXT: "target": "s:19RemoteInheritedDocs1SV"
23+
// SOME-NEXT: "sourceOrigin"
24+
// SOME-NEXT: "identifier": "s:7RemoteP1PP8someFuncyyF"
25+
// SOME-NEXT: "displayName": "P.someFunc()"
26+
27+
// OTHER: "source": "s:19RemoteInheritedDocs1SV9otherFuncyyF"
28+
// OTHER-NEXT: "target": "s:19RemoteInheritedDocs1SV"
29+
// OTHER-NEXT: "sourceOrigin"
30+
// OTHER-NEXT: "identifier": "s:7RemoteP1PP9otherFuncyyF"
31+
// OTHER-NEXT: "displayName": "P.otherFunc()"
32+
33+
// BONUS: "source": "s:19RemoteInheritedDocs1SV9bonusFuncyyF"
34+
// BONUS-NEXT: "target": "s:19RemoteInheritedDocs1SV"
35+
// BONUS-NEXT: "sourceOrigin"
36+
// BONUS-NEXT: "identifier": "s:7RemoteP1PP9bonusFuncyyF"
37+
// BONUS-NEXT: "displayName": "P.bonusFunc()"
38+
39+
// INHERIT: This one has docs!
40+
// SKIP-NOT: This one has docs!
41+
42+
// LOCAL: Local docs override!
43+
44+
// OVERRIDE-NOT: Extra default docs!
45+
// OVERRIDE-NOT: Extension override!
46+
47+
import RemoteP
48+
49+
// The `RemoteP.P` protocol has three methods: `someFunc` and `bonusFunc` don't have docs upstream,
50+
// but `otherFunc` does. Regardless, each one needs a `sourceOrigin` field connecting it to
51+
// upstream.
52+
53+
// `RemoteP.P` also has an extension with a default implementation for `extraFunc` that does have
54+
// docs, but overriding it here should prevent those from appearing
55+
56+
public struct S: P {
57+
public func someFunc() {}
58+
59+
public func otherFunc() {}
60+
61+
/// Local docs override!
62+
public func bonusFunc() {}
63+
64+
public func extraFunc() {}
65+
}
66+
67+
public extension P {
68+
/// Extension override!
69+
func someFunc() {}
70+
}
71+

0 commit comments

Comments
 (0)