Skip to content

Commit 23c5fb4

Browse files
add sourceOrigin field for symbols implementing remote protocol requirements
rdar://77626724
1 parent ab8b0a5 commit 23c5fb4

File tree

3 files changed

+90
-0
lines changed

3 files changed

+90
-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: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/// Some Protocol
2+
public protocol P {
3+
func someFunc()
4+
5+
/// This one has docs!
6+
func otherFunc()
7+
8+
func bonusFunc()
9+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
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+
12+
// RUN: %target-swift-symbolgraph-extract -module-name RemoteInheritedDocs -I %t -pretty-print -output-dir %t -skip-inherited-docs
13+
// RUN: %FileCheck %s --input-file %t/RemoteInheritedDocs.symbols.json --check-prefix SOME
14+
// RUN: %FileCheck %s --input-file %t/RemoteInheritedDocs.symbols.json --check-prefix OTHER
15+
// RUN: %FileCheck %s --input-file %t/RemoteInheritedDocs.symbols.json --check-prefix BONUS
16+
// RUN: %FileCheck %s --input-file %t/RemoteInheritedDocs.symbols.json --check-prefix SKIP
17+
// RUN: %FileCheck %s --input-file %t/RemoteInheritedDocs.symbols.json --check-prefix LOCAL
18+
19+
// SOME: "source": "s:19RemoteInheritedDocs1SV8someFuncyyF"
20+
// SOME-NEXT: "target": "s:19RemoteInheritedDocs1SV"
21+
// SOME-NEXT: "sourceOrigin"
22+
// SOME-NEXT: "identifier": "s:7RemoteP1PP8someFuncyyF"
23+
// SOME-NEXT: "displayName": "P.someFunc()"
24+
25+
// OTHER: "source": "s:19RemoteInheritedDocs1SV9otherFuncyyF"
26+
// OTHER-NEXT: "target": "s:19RemoteInheritedDocs1SV"
27+
// OTHER-NEXT: "sourceOrigin"
28+
// OTHER-NEXT: "identifier": "s:7RemoteP1PP9otherFuncyyF"
29+
// OTHER-NEXT: "displayName": "P.otherFunc()"
30+
31+
// BONUS: "source": "s:19RemoteInheritedDocs1SV9bonusFuncyyF"
32+
// BONUS-NEXT: "target": "s:19RemoteInheritedDocs1SV"
33+
// BONUS-NEXT: "sourceOrigin"
34+
// BONUS-NEXT: "identifier": "s:7RemoteP1PP9bonusFuncyyF"
35+
// BONUS-NEXT: "displayName": "P.bonusFunc()"
36+
37+
// INHERIT: This one has docs!
38+
// SKIP-NOT: This one has docs!
39+
40+
// LOCAL: Local docs override!
41+
42+
import RemoteP
43+
44+
// The `RemoteP.P` protocol has three methods: `someFunc` and `bonusFunc` don't have docs upstream,
45+
// but `otherFunc` does. Regardless, each one needs a `sourceOrigin` field connecting it to
46+
// upstream.
47+
48+
public struct S: P {
49+
public func someFunc() {}
50+
51+
public func otherFunc() {}
52+
53+
/// Local docs override!
54+
public func bonusFunc() {}
55+
}
56+

0 commit comments

Comments
 (0)