Skip to content

Commit 9aafadd

Browse files
author
Nathan Hawes
committed
[SourceKit/DocSupport] Report the required bystander modules on symbols from cross-import overlays.
Resolves rdar://problem/59446044
1 parent 7811f53 commit 9aafadd

File tree

6 files changed

+274
-2
lines changed

6 files changed

+274
-2
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// Check the interface shows the decls from each of A's cross-import overlays.
4+
//
5+
// RUN: %sourcekitd-test -req=doc-info -module A -- -I %S/../Inputs/CrossImport > %t.response
6+
// RUN: diff --strip-trailing-cr -u %s.response %t.response
7+
Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
import SwiftOnoneSupport
2+
3+
func fromA()
4+
5+
6+
// MARK: - B Additions
7+
8+
import B
9+
10+
// Available when B is imported with A
11+
struct From_ABAdditionsType {
12+
}
13+
14+
// Available when B is imported with A
15+
func from_ABAdditions()
16+
17+
18+
// MARK: - B and C Additions
19+
20+
import C
21+
22+
// Available when B and C are imported with A
23+
func from__ABAdditionsCAdditions()
24+
25+
// Available when B and C are imported with A
26+
func other(x x: A.From_ABAdditionsType)
27+
28+
29+
[
30+
{
31+
key.kind: source.lang.swift.syntaxtype.keyword,
32+
key.offset: 0,
33+
key.length: 6
34+
},
35+
{
36+
key.kind: source.lang.swift.syntaxtype.identifier,
37+
key.offset: 7,
38+
key.length: 17
39+
},
40+
{
41+
key.kind: source.lang.swift.syntaxtype.keyword,
42+
key.offset: 26,
43+
key.length: 4
44+
},
45+
{
46+
key.kind: source.lang.swift.syntaxtype.identifier,
47+
key.offset: 31,
48+
key.length: 5
49+
},
50+
{
51+
key.kind: source.lang.swift.syntaxtype.comment,
52+
key.offset: 41,
53+
key.length: 23
54+
},
55+
{
56+
key.kind: source.lang.swift.syntaxtype.comment.mark,
57+
key.offset: 44,
58+
key.length: 19
59+
},
60+
{
61+
key.kind: source.lang.swift.syntaxtype.keyword,
62+
key.offset: 65,
63+
key.length: 6
64+
},
65+
{
66+
key.kind: source.lang.swift.syntaxtype.identifier,
67+
key.offset: 72,
68+
key.length: 1
69+
},
70+
{
71+
key.kind: source.lang.swift.syntaxtype.comment,
72+
key.offset: 75,
73+
key.length: 39
74+
},
75+
{
76+
key.kind: source.lang.swift.syntaxtype.keyword,
77+
key.offset: 114,
78+
key.length: 6
79+
},
80+
{
81+
key.kind: source.lang.swift.syntaxtype.identifier,
82+
key.offset: 121,
83+
key.length: 20
84+
},
85+
{
86+
key.kind: source.lang.swift.syntaxtype.comment,
87+
key.offset: 147,
88+
key.length: 39
89+
},
90+
{
91+
key.kind: source.lang.swift.syntaxtype.keyword,
92+
key.offset: 186,
93+
key.length: 4
94+
},
95+
{
96+
key.kind: source.lang.swift.syntaxtype.identifier,
97+
key.offset: 191,
98+
key.length: 16
99+
},
100+
{
101+
key.kind: source.lang.swift.syntaxtype.comment,
102+
key.offset: 212,
103+
key.length: 29
104+
},
105+
{
106+
key.kind: source.lang.swift.syntaxtype.comment.mark,
107+
key.offset: 215,
108+
key.length: 25
109+
},
110+
{
111+
key.kind: source.lang.swift.syntaxtype.keyword,
112+
key.offset: 242,
113+
key.length: 6
114+
},
115+
{
116+
key.kind: source.lang.swift.syntaxtype.identifier,
117+
key.offset: 249,
118+
key.length: 1
119+
},
120+
{
121+
key.kind: source.lang.swift.syntaxtype.comment,
122+
key.offset: 252,
123+
key.length: 46
124+
},
125+
{
126+
key.kind: source.lang.swift.syntaxtype.keyword,
127+
key.offset: 298,
128+
key.length: 4
129+
},
130+
{
131+
key.kind: source.lang.swift.syntaxtype.identifier,
132+
key.offset: 303,
133+
key.length: 27
134+
},
135+
{
136+
key.kind: source.lang.swift.syntaxtype.comment,
137+
key.offset: 334,
138+
key.length: 46
139+
},
140+
{
141+
key.kind: source.lang.swift.syntaxtype.keyword,
142+
key.offset: 380,
143+
key.length: 4
144+
},
145+
{
146+
key.kind: source.lang.swift.syntaxtype.identifier,
147+
key.offset: 385,
148+
key.length: 5
149+
},
150+
{
151+
key.kind: source.lang.swift.syntaxtype.argument,
152+
key.offset: 391,
153+
key.length: 1
154+
},
155+
{
156+
key.kind: source.lang.swift.syntaxtype.parameter,
157+
key.offset: 393,
158+
key.length: 1
159+
},
160+
{
161+
key.kind: source.lang.swift.syntaxtype.typeidentifier,
162+
key.offset: 396,
163+
key.length: 1
164+
},
165+
{
166+
key.kind: source.lang.swift.ref.struct,
167+
key.name: "From_ABAdditionsType",
168+
key.usr: "s:12_ABAdditions05From_A4TypeV",
169+
key.offset: 398,
170+
key.length: 20
171+
}
172+
]
173+
[
174+
{
175+
key.kind: source.lang.swift.decl.function.free,
176+
key.name: "fromA()",
177+
key.usr: "s:1A5fromAyyF",
178+
key.offset: 26,
179+
key.length: 12,
180+
key.fully_annotated_decl: "<decl.function.free><syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>fromA</decl.name>()</decl.function.free>"
181+
},
182+
{
183+
key.kind: source.lang.swift.decl.struct,
184+
key.name: "From_ABAdditionsType",
185+
key.usr: "s:12_ABAdditions05From_A4TypeV",
186+
key.offset: 114,
187+
key.length: 31,
188+
key.fully_annotated_decl: "<decl.struct><syntaxtype.keyword>struct</syntaxtype.keyword> <decl.name>From_ABAdditionsType</decl.name></decl.struct>",
189+
key.required_bystanders: [
190+
"B"
191+
]
192+
},
193+
{
194+
key.kind: source.lang.swift.decl.function.free,
195+
key.name: "from_ABAdditions()",
196+
key.usr: "s:12_ABAdditions05from_A0yyF",
197+
key.offset: 186,
198+
key.length: 23,
199+
key.fully_annotated_decl: "<decl.function.free><syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>from_ABAdditions</decl.name>()</decl.function.free>",
200+
key.required_bystanders: [
201+
"B"
202+
]
203+
},
204+
{
205+
key.kind: source.lang.swift.decl.function.free,
206+
key.name: "from__ABAdditionsCAdditions()",
207+
key.usr: "s:23__ABAdditionsCAdditions06from__aB0yyF",
208+
key.offset: 298,
209+
key.length: 34,
210+
key.fully_annotated_decl: "<decl.function.free><syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>from__ABAdditionsCAdditions</decl.name>()</decl.function.free>",
211+
key.required_bystanders: [
212+
"C",
213+
"B"
214+
]
215+
},
216+
{
217+
key.kind: source.lang.swift.decl.function.free,
218+
key.name: "other(x:)",
219+
key.usr: "s:23__ABAdditionsCAdditions5other1xy01_A005From_A4TypeV_tF",
220+
key.offset: 380,
221+
key.length: 39,
222+
key.fully_annotated_decl: "<decl.function.free><syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>other</decl.name>(<decl.var.parameter><decl.var.parameter.argument_label>x</decl.var.parameter.argument_label>: <decl.var.parameter.type><ref.struct usr=\"s:12_ABAdditions05From_A4TypeV\">From_ABAdditionsType</ref.struct></decl.var.parameter.type></decl.var.parameter>)</decl.function.free>",
223+
key.entities: [
224+
{
225+
key.kind: source.lang.swift.decl.var.local,
226+
key.keyword: "x",
227+
key.name: "x",
228+
key.offset: 396,
229+
key.length: 22
230+
}
231+
],
232+
key.required_bystanders: [
233+
"C",
234+
"B"
235+
]
236+
}
237+
]

tools/SourceKit/include/SourceKit/Core/LangSupport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,7 @@ struct DocEntityInfo {
485485
llvm::SmallString<64> LocalizationKey;
486486
std::vector<DocGenericParam> GenericParams;
487487
std::vector<std::string> GenericRequirements;
488+
std::vector<std::string> RequiredBystanders;
488489
unsigned Offset = 0;
489490
unsigned Length = 0;
490491
bool IsUnavailable = false;

tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ struct TextEntity {
6565
const Decl *Dcl = nullptr;
6666
TypeOrExtensionDecl SynthesizeTarget;
6767
const Decl *DefaultImplementationOf = nullptr;
68+
ModuleDecl *UnderlyingModIfFromOverlay = nullptr;
6869
StringRef Argument;
6970
TextRange Range;
7071
unsigned LocOffset = 0;
@@ -303,7 +304,8 @@ static bool initDocEntityInfo(const Decl *D,
303304
TypeOrExtensionDecl SynthesizedTarget,
304305
const Decl *DefaultImplementationOf, bool IsRef,
305306
bool IsSynthesizedExtension, DocEntityInfo &Info,
306-
StringRef Arg = StringRef()) {
307+
StringRef Arg = StringRef(),
308+
ModuleDecl *ModIfFromOverlay = nullptr){
307309
if (!IsRef && D->isImplicit())
308310
return true;
309311
if (!D || isa<ParamDecl>(D) ||
@@ -409,6 +411,15 @@ static bool initDocEntityInfo(const Decl *D,
409411
SwiftLangSupport::printFullyAnnotatedGenericReq(Sig, OS);
410412
}
411413
}
414+
415+
if (ModIfFromOverlay) {
416+
ModuleDecl *MD = D->getModuleContext();
417+
SmallVector<Identifier, 1> Bystanders;
418+
ModIfFromOverlay->getAllBystandersForCrossImportOverlay(MD, Bystanders);
419+
std::transform(Bystanders.begin(), Bystanders.end(),
420+
std::back_inserter(Info.RequiredBystanders),
421+
[](Identifier Bystander){ return Bystander.str().str(); });
422+
}
412423
}
413424

414425
switch(D->getDeclContext()->getContextKind()) {
@@ -446,7 +457,8 @@ static bool initDocEntityInfo(const TextEntity &Entity,
446457
if (initDocEntityInfo(Entity.Dcl, Entity.SynthesizeTarget,
447458
Entity.DefaultImplementationOf,
448459
/*IsRef=*/false, Entity.IsSynthesizedExtension,
449-
Info, Entity.Argument))
460+
Info, Entity.Argument,
461+
Entity.UnderlyingModIfFromOverlay))
450462
return true;
451463
Info.Offset = Entity.Range.Offset;
452464
Info.Length = Entity.Range.Length;
@@ -962,6 +974,16 @@ static bool getModuleInterfaceInfo(ASTContext &Ctx, StringRef ModuleName,
962974
Info.Text = std::string(OS.str());
963975
Info.TopEntities = std::move(Printer.TopEntities);
964976
Info.References = std::move(Printer.References);
977+
978+
// Add a reference to the main module on any entities from cross-import
979+
// overlay modules (used to determine their bystanders later).
980+
for (auto &Entity: Info.TopEntities) {
981+
auto *EntityMod = Entity.Dcl->getModuleContext();
982+
if (!EntityMod || EntityMod == M)
983+
continue;
984+
if (M->isUnderlyingModuleOfCrossImportOverlay(EntityMod))
985+
Entity.UnderlyingModIfFromOverlay = M;
986+
}
965987
return false;
966988
}
967989

tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1573,11 +1573,15 @@ void SKDocConsumer::addDocEntityInfoToDict(const DocEntityInfo &Info,
15731573
// while GenericParams is empty.
15741574
if (!Info.GenericRequirements.empty()) {
15751575
auto ReqArray = Elem.setArray(KeyGenericRequirements);
1576+
15761577
for (auto &Req : Info.GenericRequirements) {
15771578
auto ReqElem = ReqArray.appendDictionary();
15781579
ReqElem.set(KeyDescription, Req);
15791580
}
15801581
}
1582+
1583+
if (!Info.RequiredBystanders.empty())
1584+
Elem.set(KeyRequiredBystanders, Info.RequiredBystanders);
15811585
}
15821586

15831587
void SKDocConsumer::failed(StringRef ErrDescription) {

utils/gyb_sourcekit_support/UIDs.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ def __init__(self, internal_name, external_name):
177177
KEY('VFSOptions', 'key.vfs.options'),
178178
KEY('Files', 'key.files'),
179179
KEY('OptimizeForIDE', 'key.optimize_for_ide'),
180+
KEY('RequiredBystanders', 'key.required_bystanders'),
180181
]
181182

182183

0 commit comments

Comments
 (0)