Skip to content

Commit 16e39ff

Browse files
authored
Merge pull request #15796 from nkcsgexi/digester-ignore-objc-protocol
swift-api-digester: ignore synthesized type members from conformed clang protocols.
2 parents da6bff5 + 9042db5 commit 16e39ff

File tree

5 files changed

+132
-3
lines changed

5 files changed

+132
-3
lines changed

test/api-digester/Inputs/Foo/foo.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#import <Foundation.h>
2+
3+
@protocol ObjcProt
4+
-(void) someFunctionFromProt;
5+
@end
6+
7+
@interface ClangInterface: NSObject <ObjcProt>
8+
- (void)someFunction;
9+
@end
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module Foo {
2+
header "foo.h"
3+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
{
2+
"kind": "Root",
3+
"name": "TopLevel",
4+
"printedName": "TopLevel",
5+
"children": [
6+
{
7+
"kind": "TypeDecl",
8+
"name": "ClangInterface",
9+
"printedName": "ClangInterface",
10+
"declKind": "Class",
11+
"usr": "c:objc(cs)ClangInterface",
12+
"location": "",
13+
"moduleName": "Foo",
14+
"superclassUsr": "c:objc(cs)NSObject",
15+
"conformingProtocols": [
16+
"ObjcProt",
17+
"NSObjectProtocol"
18+
],
19+
"children": [
20+
{
21+
"kind": "Function",
22+
"name": "someFunction",
23+
"printedName": "someFunction()",
24+
"declKind": "Func",
25+
"usr": "c:objc(cs)ClangInterface(im)someFunction",
26+
"location": "",
27+
"moduleName": "Foo",
28+
"children": [
29+
{
30+
"kind": "TypeNameAlias",
31+
"name": "Void",
32+
"printedName": "Void",
33+
"children": [
34+
{
35+
"kind": "TypeNominal",
36+
"name": "Void",
37+
"printedName": "()"
38+
}
39+
]
40+
}
41+
]
42+
},
43+
{
44+
"kind": "Constructor",
45+
"name": "init",
46+
"printedName": "init()",
47+
"declKind": "Constructor",
48+
"usr": "c:objc(cs)NSObject(im)init",
49+
"location": "",
50+
"moduleName": "Foo",
51+
"children": [
52+
{
53+
"kind": "TypeNominal",
54+
"name": "ClangInterface",
55+
"printedName": "ClangInterface",
56+
"usr": "c:objc(cs)ClangInterface"
57+
}
58+
]
59+
}
60+
]
61+
},
62+
{
63+
"kind": "TypeDecl",
64+
"name": "ObjcProt",
65+
"printedName": "ObjcProt",
66+
"declKind": "Protocol",
67+
"usr": "c:objc(pl)ObjcProt",
68+
"location": "",
69+
"moduleName": "Foo",
70+
"children": [
71+
{
72+
"kind": "Function",
73+
"name": "someFunctionFromProt",
74+
"printedName": "someFunctionFromProt()",
75+
"declKind": "Func",
76+
"usr": "c:objc(pl)ObjcProt(im)someFunctionFromProt",
77+
"location": "",
78+
"moduleName": "Foo",
79+
"children": [
80+
{
81+
"kind": "TypeNameAlias",
82+
"name": "Void",
83+
"printedName": "Void",
84+
"children": [
85+
{
86+
"kind": "TypeNominal",
87+
"name": "Void",
88+
"printedName": "()"
89+
}
90+
]
91+
}
92+
]
93+
}
94+
]
95+
}
96+
]
97+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// REQUIRES: OS=macosx
2+
// RUN: %empty-directory(%t.mod)
3+
// RUN: %empty-directory(%t.sdk)
4+
// RUN: %empty-directory(%t.module-cache)
5+
// RUN: %api-digester -dump-sdk -module Foo -o %t.result -module-cache-path %t.module-cache %clang-importer-sdk-nosource -swift-version 4 -I %S/Inputs/Foo -avoid-location
6+
// RUN: diff -u %S/Outputs/clang-module-dump.txt %t.result

tools/swift-api-digester/swift-api-digester.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,10 @@ SwiftVersion("swift-version",
163163

164164
static llvm::cl::opt<bool>
165165
OutputInJson("json", llvm::cl::desc("Print output in JSON format."));
166+
167+
static llvm::cl::opt<bool>
168+
AvoidLocation("avoid-location",
169+
llvm::cl::desc("Avoid serializing the file paths of SDK nodes."));
166170
} // namespace options
167171

168172
namespace {
@@ -1225,6 +1229,9 @@ static StringRef calculateUsr(SDKContext &Ctx, ValueDecl *VD) {
12251229
}
12261230

12271231
static StringRef calculateLocation(SDKContext &SDKCtx, ValueDecl *VD) {
1232+
if (options::AvoidLocation) {
1233+
return StringRef();
1234+
}
12281235
auto &Ctx = VD->getASTContext();
12291236
auto &Importer = static_cast<ClangImporter &>(*Ctx.getClangModuleLoader());
12301237

@@ -1483,7 +1490,7 @@ static SDKNode* constructInitNode(SDKContext &Ctx, ConstructorDecl *CD) {
14831490
return Func;
14841491
}
14851492

1486-
static bool shouldIgnore(Decl *D) {
1493+
static bool shouldIgnore(Decl *D, const Decl* Parent) {
14871494
if (D->isPrivateStdlibDecl(false))
14881495
return true;
14891496
if (AvailableAttr::isUnavailable(D))
@@ -1518,6 +1525,13 @@ static bool shouldIgnore(Decl *D) {
15181525
return true;
15191526
if (ClangD->hasAttr<clang::SwiftPrivateAttr>())
15201527
return true;
1528+
1529+
// If this decl is a synthesized member from a conformed clang protocol, we
1530+
// should ignore this member to reduce redundancy.
1531+
if (Parent &&
1532+
!isa<swift::ProtocolDecl>(Parent) &&
1533+
isa<clang::ObjCProtocolDecl>(ClangD->getDeclContext()))
1534+
return true;
15211535
}
15221536
return false;
15231537
}
@@ -1558,7 +1572,7 @@ static SDKNode *constructTypeAliasNode(SDKContext &Ctx,TypeAliasDecl *TAD) {
15581572
static void addMembersToRoot(SDKContext &Ctx, SDKNode *Root,
15591573
IterableDeclContext *Context) {
15601574
for (auto *Member : Context->getMembers()) {
1561-
if (shouldIgnore(Member))
1575+
if (shouldIgnore(Member, Context->getDecl()))
15621576
continue;
15631577
if (auto Func = dyn_cast<FuncDecl>(Member)) {
15641578
Root->addChild(constructFunctionNode(Ctx, Func, SDKNodeKind::DeclFunction));
@@ -1648,7 +1662,7 @@ class SwiftDeclCollector : public VisibleDeclConsumer {
16481662
}
16491663

16501664
void processDecl(ValueDecl *VD) {
1651-
if (shouldIgnore(VD))
1665+
if (shouldIgnore(VD, nullptr))
16521666
return;
16531667

16541668
if (auto FD = dyn_cast<FuncDecl>(VD)) {

0 commit comments

Comments
 (0)