Skip to content

Commit be7466e

Browse files
committed
[CodeCompletion] Annotate 'async' functions/initializers in results
Similar to how it shows "throws" today. Introduced CodeCompletionStringChunk::ChunkKind::AsyncKeyword rdar://problem/72198530
1 parent c65a206 commit be7466e

File tree

6 files changed

+105
-7
lines changed

6 files changed

+105
-7
lines changed

include/swift/IDE/CodeCompletion.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ class CodeCompletionStringChunk {
9595
/// The "rethrows" keyword.
9696
RethrowsKeyword,
9797

98+
/// The "async" keyword.
99+
AsyncKeyword,
100+
98101
/// The keyword part of a declaration before the name, like "func".
99102
DeclIntroducer,
100103

@@ -222,6 +225,7 @@ class CodeCompletionStringChunk {
222225
Kind == ChunkKind::OverrideKeyword ||
223226
Kind == ChunkKind::ThrowsKeyword ||
224227
Kind == ChunkKind::RethrowsKeyword ||
228+
Kind == ChunkKind::AsyncKeyword ||
225229
Kind == ChunkKind::DeclAttrKeyword ||
226230
Kind == ChunkKind::DeclIntroducer ||
227231
Kind == ChunkKind::Keyword ||

lib/IDE/CodeCompletion.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,7 @@ void CodeCompletionString::print(raw_ostream &OS) const {
387387
case ChunkKind::OverrideKeyword:
388388
case ChunkKind::ThrowsKeyword:
389389
case ChunkKind::RethrowsKeyword:
390+
case ChunkKind::AsyncKeyword:
390391
case ChunkKind::DeclIntroducer:
391392
case ChunkKind::Text:
392393
case ChunkKind::LeftParen:
@@ -1378,6 +1379,7 @@ Optional<unsigned> CodeCompletionString::getFirstTextChunkIndex(
13781379
case ChunkKind::OverrideKeyword:
13791380
case ChunkKind::ThrowsKeyword:
13801381
case ChunkKind::RethrowsKeyword:
1382+
case ChunkKind::AsyncKeyword:
13811383
case ChunkKind::DeclIntroducer:
13821384
case ChunkKind::CallParameterColon:
13831385
case ChunkKind::CallParameterTypeBegin:
@@ -1433,6 +1435,7 @@ void CodeCompletionString::getName(raw_ostream &OS) const {
14331435
}
14341436
case ChunkKind::ThrowsKeyword:
14351437
case ChunkKind::RethrowsKeyword:
1438+
case ChunkKind::AsyncKeyword:
14361439
shouldPrint = true; // Even when they're annotations.
14371440
break;
14381441
default:
@@ -2639,9 +2642,16 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
26392642
genericSig, includeDefaultArgs);
26402643
}
26412644

2642-
static void addThrows(CodeCompletionResultBuilder &Builder,
2643-
const AnyFunctionType *AFT,
2644-
const AbstractFunctionDecl *AFD) {
2645+
static void addAsyncThrows(CodeCompletionResultBuilder &Builder,
2646+
const AnyFunctionType *AFT,
2647+
const AbstractFunctionDecl *AFD) {
2648+
assert(AFT != nullptr);
2649+
2650+
// 'async'.
2651+
if ((AFD && AFD->hasAsync()) || AFT->isAsync())
2652+
Builder.addAnnotatedAsync();
2653+
2654+
// 'throws' or 'rethrows'.
26452655
if (AFD && AFD->getAttrs().hasAttribute<RethrowsAttr>())
26462656
Builder.addAnnotatedRethrows();
26472657
else if (AFT->isThrowing())
@@ -2799,7 +2809,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
27992809
else
28002810
Builder.addAnnotatedRightParen();
28012811

2802-
addThrows(Builder, AFT, AFD);
2812+
addAsyncThrows(Builder, AFT, AFD);
28032813

28042814
if (AFD &&
28052815
AFD->isImplicitlyUnwrappedOptional())
@@ -2946,14 +2956,14 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
29462956
Builder.addRightParen();
29472957
} else if (trivialTrailingClosure) {
29482958
Builder.addBraceStmtWithCursor(" { code }");
2949-
addThrows(Builder, AFT, FD);
2959+
addAsyncThrows(Builder, AFT, FD);
29502960
} else {
29512961
Builder.addLeftParen();
29522962
addCallArgumentPatterns(Builder, AFT, FD->getParameters(),
29532963
FD->getGenericSignatureOfContext(),
29542964
includeDefaultArgs);
29552965
Builder.addRightParen();
2956-
addThrows(Builder, AFT, FD);
2966+
addAsyncThrows(Builder, AFT, FD);
29572967
}
29582968

29592969
// Build type annotation.
@@ -3094,7 +3104,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
30943104
else
30953105
Builder.addAnnotatedRightParen();
30963106

3097-
addThrows(Builder, ConstructorType, CD);
3107+
addAsyncThrows(Builder, ConstructorType, CD);
30983108

30993109
if (!Result.hasValue())
31003110
Result = ConstructorType->getResult();

lib/IDE/CodeCompletionResultBuilder.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,17 @@ class CodeCompletionResultBuilder {
230230
" throws");
231231
}
232232

233+
void addAnnotatedAsync() {
234+
addAsync();
235+
getLastChunk().setIsAnnotation();
236+
}
237+
238+
void addAsync() {
239+
addChunkWithTextNoCopy(
240+
CodeCompletionString::Chunk::ChunkKind::AsyncKeyword,
241+
" async");
242+
}
243+
233244
void addDeclDocCommentWords(ArrayRef<std::pair<StringRef, StringRef>> Pairs) {
234245
assert(Kind == CodeCompletionResult::ResultKind::Declaration);
235246
CommentWords = Pairs;

lib/IDE/CodeCompletionResultPrinter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ class AnnotatingResultPrinter {
102102
case ChunkKind::AccessControlKeyword:
103103
case ChunkKind::ThrowsKeyword:
104104
case ChunkKind::RethrowsKeyword:
105+
case ChunkKind::AsyncKeyword:
105106
case ChunkKind::DeclIntroducer:
106107
printWithTag("keyword", C.getText());
107108
break;

lib/IDE/REPLCodeCompletion.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ static std::string toInsertableString(CodeCompletionResult *Result) {
4040
case CodeCompletionString::Chunk::ChunkKind::OverrideKeyword:
4141
case CodeCompletionString::Chunk::ChunkKind::ThrowsKeyword:
4242
case CodeCompletionString::Chunk::ChunkKind::RethrowsKeyword:
43+
case CodeCompletionString::Chunk::ChunkKind::AsyncKeyword:
4344
case CodeCompletionString::Chunk::ChunkKind::DeclAttrKeyword:
4445
case CodeCompletionString::Chunk::ChunkKind::DeclIntroducer:
4546
case CodeCompletionString::Chunk::ChunkKind::Keyword:
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// RUN: %target-swift-ide-test -batch-code-completion -source-filename %s -filecheck %raw-FileCheck -completion-output-dir %t -enable-experimental-concurrency
2+
3+
func globalFuncAsync() async {}
4+
func globalFuncAsyncThrows() async throws {}
5+
func globalFuncAsyncRethrows(_ x: () async throws -> ()) async rethrows {}
6+
struct HasAsyncMembers {
7+
func memberAsync() async {}
8+
func memberAsyncThrows() async throws {}
9+
func memberAsyncRethrows(_ x: () async throws -> ()) async rethrows {}
10+
11+
init() async {}
12+
init(withAsync: Int) async {}
13+
init(withAsyncThrows: Int) async throws {}
14+
init(withAsyncRethrows: () async throws -> Void) async rethrows {}
15+
}
16+
17+
func testGlobalFuncAsync() {
18+
globalFuncAsync#^CHECK_globalFuncAsync^#
19+
// CHECK_globalFuncAsync: Begin completions
20+
// CHECK_globalFuncAsync-DAG: Decl[FreeFunction]/CurrModule: ()[' async'][#Void#]; name=() async
21+
// CHECK_globalFuncAsync: End completions
22+
}
23+
func testGlobalFuncAsyncThrows() {
24+
globalFuncAsyncThrows#^CHECK_globalFuncAsyncThrows^#
25+
// CHECK_globalFuncAsyncThrows: Begin completions
26+
// CHECK_globalFuncAsyncThrows-DAG: Decl[FreeFunction]/CurrModule: ()[' async'][' throws'][#Void#]; name=() async throws
27+
// CHECK_globalFuncAsyncThrows: End completions
28+
}
29+
func testGlobalFuncAsyncRethrows() {
30+
globalFuncAsyncRethrows#^CHECK_globalFuncAsyncRethrows^#
31+
// CHECK_globalFuncAsyncRethrows: Begin completions
32+
// CHECK_globalFuncAsyncRethrows-DAG: Decl[FreeFunction]/CurrModule: ({#(x): () async throws -> ()##() async throws -> ()#})[' async'][' rethrows'][#Void#]; name=(x: () async throws -> ()) async rethrows
33+
// CHECK_globalFuncAsyncRethrows: End completions
34+
}
35+
func testAsyncMembers(_ x: HasAsyncMembers) {
36+
x.#^CHECK_members^#
37+
// CHECK_members: Begin completions
38+
// CHECK_members-DAG: Decl[InstanceMethod]/CurrNominal: memberAsync()[' async'][#Void#]; name=memberAsync() async
39+
// CHECK_members-DAG: Decl[InstanceMethod]/CurrNominal: memberAsyncThrows()[' async'][' throws'][#Void#]; name=memberAsyncThrows() async throws
40+
// CHECK_members-DAG: Decl[InstanceMethod]/CurrNominal: memberAsyncRethrows {|}[' async'][' rethrows'][#Void#]; name=memberAsyncRethrows { code } async rethrows
41+
// CHECK_members-DAG: Decl[InstanceMethod]/CurrNominal: memberAsyncRethrows({#(x): () async throws -> ()##() async throws -> ()#})[' async'][' rethrows'][#Void#]; name=memberAsyncRethrows(x: () async throws -> ()) async rethrows
42+
// CHECK_members: End completions
43+
}
44+
func testMemberAsync(_ x: HasAsyncMembers) {
45+
x.memberAsync#^CHECK_memberAsync^#
46+
// CHECK_memberAsync: Begin completions
47+
// CHECK_memberAsync-DAG: Decl[InstanceMethod]/CurrNominal: ()[' async'][#Void#]; name=() async
48+
// CHECK_memberAsync: End completions
49+
}
50+
func testMemberAsyncThrows(_ x: HasAsyncMembers) {
51+
x.memberAsyncThrows#^CHECK_memberAsyncThrows^#
52+
// CHECK_memberAsyncThrows: Begin completions
53+
// CHECK_memberAsyncThrows-DAG: Decl[InstanceMethod]/CurrNominal: ()[' async'][' throws'][#Void#]; name=() async throws
54+
// CHECK_memberAsyncThrows: End completions
55+
}
56+
func testMemberAsyncRethrows(_ x: HasAsyncMembers) {
57+
x.memberAsyncRethrows#^CHECK_memberAsyncRethrows^#
58+
// CHECK_memberAsyncRethrows: Begin completions
59+
// CHECK_memberAsyncRethrows-DAG: Decl[InstanceMethod]/CurrNominal: ({#(x): () async throws -> ()##() async throws -> ()#})[' async'][' rethrows'][#Void#]; name=(x: () async throws -> ()) async rethrows
60+
// CHECK_memberAsyncRethrows: End completions
61+
}
62+
63+
func testAsyncIntiializers() {
64+
HasAsyncMembers(#^CHECK_initializers^#
65+
// CHECK_initializers: Begin completions
66+
// CHECK_initializers-DAG: Decl[Constructor]/CurrNominal: ['('][')'][#HasAsyncMembers#]; name=
67+
// CHECK_initializers-DAG: Decl[Constructor]/CurrNominal: ['(']{#withAsync: Int#}[')'][#HasAsyncMembers#]; name=withAsync: Int
68+
// CHECK_initializers-DAG: Decl[Constructor]/CurrNominal: ['(']{#withAsyncThrows: Int#}[')'][' throws'][#HasAsyncMembers#]; name=withAsyncThrows: Int throws
69+
// CHECK_initializers-DAG: Decl[Constructor]/CurrNominal: ['(']{#withAsyncRethrows: () async throws -> Void##() async throws -> Void#}[')'][' rethrows'][#HasAsyncMembers#]; name=withAsyncRethrows: () async throws -> Void rethrows
70+
// CHECK_initializers: End completions
71+
}

0 commit comments

Comments
 (0)