Skip to content

Commit 6f14171

Browse files
committed
[SourceKit] Fix handling of @abi in AnnotatingPrinter
Make sure we avoid adding these to the entity stack entirely, which avoids hitting the assertion that a top-level entity isn't encountered with a non-empty stack.
1 parent c621295 commit 6f14171

File tree

2 files changed

+60
-8
lines changed

2 files changed

+60
-8
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
// RUN: %target-swift-frontend -emit-module -module-name Mod %t/mod.swift -o %t/Mod.swiftmodule
4+
// RUN: %sourcekitd-test -req=doc-info -print-raw-response -module Mod -- -I %t -target %target-triple > %t/output.response
5+
// RUN: %diff -u %t/expected.response %t/output.response
6+
7+
// Make sure we don't crash here, we should exclude the @abi decl from the
8+
// list of entities.
9+
10+
//--- mod.swift
11+
@abi(func bar())
12+
public func foo() {}
13+
14+
//--- expected.response
15+
{
16+
key.annotations: [
17+
{
18+
key.kind: source.lang.swift.syntaxtype.attribute.builtin,
19+
key.offset: 0,
20+
key.length: 16
21+
},
22+
{
23+
key.kind: source.lang.swift.syntaxtype.keyword,
24+
key.offset: 17,
25+
key.length: 4
26+
},
27+
{
28+
key.kind: source.lang.swift.syntaxtype.identifier,
29+
key.offset: 22,
30+
key.length: 3
31+
}
32+
],
33+
key.entities: [
34+
{
35+
key.kind: source.lang.swift.decl.function.free,
36+
key.name: "foo()",
37+
key.usr: "s:3Mod3baryyF",
38+
key.offset: 0,
39+
key.length: 27,
40+
key.fully_annotated_decl: "<decl.function.free><syntaxtype.attribute.builtin>@abi(<decl.function.free><syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>bar</decl.name>()</decl.function.free>)</syntaxtype.attribute.builtin> <syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>foo</decl.name>()</decl.function.free>"
41+
}
42+
],
43+
key.sourcetext: "@abi(func bar())\nfunc foo()\n\n"
44+
}

tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,22 @@ class AnnotatingPrinter : public StreamPrinter {
186186
TopEntities.push_back(std::move(Entity));
187187
}
188188

189+
bool shouldIgnoreDecl(const Decl *D) {
190+
// Parameters are handled specially in addParameters().
191+
if (isa<ParamDecl>(D))
192+
return true;
193+
194+
// We only care about API for documentation purposes.
195+
if (!ABIRoleInfo(D).providesAPI())
196+
return true;
197+
198+
return false;
199+
}
200+
189201
void printDeclPre(const Decl *D,
190202
std::optional<BracketOptions> Bracket) override {
191-
if (isa<ParamDecl>(D))
192-
return; // Parameters are handled specially in addParameters().
203+
if (shouldIgnoreDecl(D))
204+
return;
193205
if (!shouldContinuePre(D, Bracket))
194206
return;
195207
unsigned StartOffset = OS.tell();
@@ -212,18 +224,14 @@ class AnnotatingPrinter : public StreamPrinter {
212224

213225
void printDeclPost(const Decl *D,
214226
std::optional<BracketOptions> Bracket) override {
215-
if (isa<ParamDecl>(D))
216-
return; // Parameters are handled specially in addParameters().
227+
if (shouldIgnoreDecl(D))
228+
return;
217229
if (!shouldContinuePost(D, Bracket))
218230
return;
219231
assert(!EntitiesStack.empty());
220232
TextEntity Entity = std::move(EntitiesStack.back());
221233
EntitiesStack.pop_back();
222234

223-
// We only care about API for documentation purposes.
224-
if (!ABIRoleInfo(D).providesAPI())
225-
return;
226-
227235
unsigned EndOffset = OS.tell();
228236
Entity.Range.Length = EndOffset - Entity.Range.Offset;
229237
if (EntitiesStack.empty()) {

0 commit comments

Comments
 (0)