Skip to content

Commit 8ef504a

Browse files
authored
Merge pull request swiftlang#35050 from rintaro/ide-completion-rdar72198530
[CodeCompletion] Annotate 'async' functions/initializers in results
2 parents c326194 + 4286c44 commit 8ef504a

File tree

11 files changed

+109
-39
lines changed

11 files changed

+109
-39
lines changed

include/swift/IDE/CodeCompletion.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,8 @@ class CodeCompletionStringChunk {
8989
/// The "override" keyword.
9090
OverrideKeyword,
9191

92-
/// The "throws" keyword.
93-
ThrowsKeyword,
94-
95-
/// The "rethrows" keyword.
96-
RethrowsKeyword,
92+
/// The "throws", "rethrows" and "async" keyword.
93+
EffectsSpecifierKeyword,
9794

9895
/// The keyword part of a declaration before the name, like "func".
9996
DeclIntroducer,
@@ -220,8 +217,7 @@ class CodeCompletionStringChunk {
220217
static bool chunkHasText(ChunkKind Kind) {
221218
return Kind == ChunkKind::AccessControlKeyword ||
222219
Kind == ChunkKind::OverrideKeyword ||
223-
Kind == ChunkKind::ThrowsKeyword ||
224-
Kind == ChunkKind::RethrowsKeyword ||
220+
Kind == ChunkKind::EffectsSpecifierKeyword ||
225221
Kind == ChunkKind::DeclAttrKeyword ||
226222
Kind == ChunkKind::DeclIntroducer ||
227223
Kind == ChunkKind::Keyword ||

lib/IDE/CodeCompletion.cpp

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -385,8 +385,7 @@ void CodeCompletionString::print(raw_ostream &OS) const {
385385
case ChunkKind::DeclAttrKeyword:
386386
case ChunkKind::DeclAttrParamKeyword:
387387
case ChunkKind::OverrideKeyword:
388-
case ChunkKind::ThrowsKeyword:
389-
case ChunkKind::RethrowsKeyword:
388+
case ChunkKind::EffectsSpecifierKeyword:
390389
case ChunkKind::DeclIntroducer:
391390
case ChunkKind::Text:
392391
case ChunkKind::LeftParen:
@@ -1376,8 +1375,7 @@ Optional<unsigned> CodeCompletionString::getFirstTextChunkIndex(
13761375
case ChunkKind::Whitespace:
13771376
case ChunkKind::AccessControlKeyword:
13781377
case ChunkKind::OverrideKeyword:
1379-
case ChunkKind::ThrowsKeyword:
1380-
case ChunkKind::RethrowsKeyword:
1378+
case ChunkKind::EffectsSpecifierKeyword:
13811379
case ChunkKind::DeclIntroducer:
13821380
case ChunkKind::CallParameterColon:
13831381
case ChunkKind::CallParameterTypeBegin:
@@ -1431,8 +1429,7 @@ void CodeCompletionString::getName(raw_ostream &OS) const {
14311429
--i;
14321430
continue;
14331431
}
1434-
case ChunkKind::ThrowsKeyword:
1435-
case ChunkKind::RethrowsKeyword:
1432+
case ChunkKind::EffectsSpecifierKeyword:
14361433
shouldPrint = true; // Even when they're annotations.
14371434
break;
14381435
default:
@@ -2640,9 +2637,16 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
26402637
genericSig, includeDefaultArgs);
26412638
}
26422639

2643-
static void addThrows(CodeCompletionResultBuilder &Builder,
2644-
const AnyFunctionType *AFT,
2645-
const AbstractFunctionDecl *AFD) {
2640+
static void addEffectsSpecifiers(CodeCompletionResultBuilder &Builder,
2641+
const AnyFunctionType *AFT,
2642+
const AbstractFunctionDecl *AFD) {
2643+
assert(AFT != nullptr);
2644+
2645+
// 'async'.
2646+
if ((AFD && AFD->hasAsync()) || AFT->isAsync())
2647+
Builder.addAnnotatedAsync();
2648+
2649+
// 'throws' or 'rethrows'.
26462650
if (AFD && AFD->getAttrs().hasAttribute<RethrowsAttr>())
26472651
Builder.addAnnotatedRethrows();
26482652
else if (AFT->isThrowing())
@@ -2800,7 +2804,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
28002804
else
28012805
Builder.addAnnotatedRightParen();
28022806

2803-
addThrows(Builder, AFT, AFD);
2807+
addEffectsSpecifiers(Builder, AFT, AFD);
28042808

28052809
if (AFD &&
28062810
AFD->isImplicitlyUnwrappedOptional())
@@ -2947,14 +2951,14 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
29472951
Builder.addRightParen();
29482952
} else if (trivialTrailingClosure) {
29492953
Builder.addBraceStmtWithCursor(" { code }");
2950-
addThrows(Builder, AFT, FD);
2954+
addEffectsSpecifiers(Builder, AFT, FD);
29512955
} else {
29522956
Builder.addLeftParen();
29532957
addCallArgumentPatterns(Builder, AFT, FD->getParameters(),
29542958
FD->getGenericSignatureOfContext(),
29552959
includeDefaultArgs);
29562960
Builder.addRightParen();
2957-
addThrows(Builder, AFT, FD);
2961+
addEffectsSpecifiers(Builder, AFT, FD);
29582962
}
29592963

29602964
// Build type annotation.
@@ -3095,7 +3099,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
30953099
else
30963100
Builder.addAnnotatedRightParen();
30973101

3098-
addThrows(Builder, ConstructorType, CD);
3102+
addEffectsSpecifiers(Builder, ConstructorType, CD);
30993103

31003104
if (!Result.hasValue())
31013105
Result = ConstructorType->getResult();

lib/IDE/CodeCompletionResultBuilder.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,10 +226,21 @@ class CodeCompletionResultBuilder {
226226

227227
void addThrows() {
228228
addChunkWithTextNoCopy(
229-
CodeCompletionString::Chunk::ChunkKind::ThrowsKeyword,
229+
CodeCompletionString::Chunk::ChunkKind::EffectsSpecifierKeyword,
230230
" throws");
231231
}
232232

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

243254
void addRethrows() {
244255
addChunkWithTextNoCopy(
245-
CodeCompletionString::Chunk::ChunkKind::RethrowsKeyword, " rethrows");
256+
CodeCompletionString::Chunk::ChunkKind::EffectsSpecifierKeyword,
257+
" rethrows");
246258
}
247259

248260
void addAnnotatedLeftParen() {

lib/IDE/CodeCompletionResultPrinter.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,7 @@ class AnnotatingResultPrinter {
100100
case ChunkKind::Keyword:
101101
case ChunkKind::OverrideKeyword:
102102
case ChunkKind::AccessControlKeyword:
103-
case ChunkKind::ThrowsKeyword:
104-
case ChunkKind::RethrowsKeyword:
103+
case ChunkKind::EffectsSpecifierKeyword:
105104
case ChunkKind::DeclIntroducer:
106105
printWithTag("keyword", C.getText());
107106
break;

lib/IDE/REPLCodeCompletion.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@ static std::string toInsertableString(CodeCompletionResult *Result) {
3838
switch (C.getKind()) {
3939
case CodeCompletionString::Chunk::ChunkKind::AccessControlKeyword:
4040
case CodeCompletionString::Chunk::ChunkKind::OverrideKeyword:
41-
case CodeCompletionString::Chunk::ChunkKind::ThrowsKeyword:
42-
case CodeCompletionString::Chunk::ChunkKind::RethrowsKeyword:
41+
case CodeCompletionString::Chunk::ChunkKind::EffectsSpecifierKeyword:
4342
case CodeCompletionString::Chunk::ChunkKind::DeclAttrKeyword:
4443
case CodeCompletionString::Chunk::ChunkKind::DeclIntroducer:
4544
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+
}

test/SourceKit/CodeComplete/complete_structure.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ func test1(_ x: S1) {
4040
// S1_DOT: {name:method4}({params:{t:Int}, {t:Int}})
4141
// S1_DOT: {name:method5}({params:{t:&Int}, {n:b:}{t: &Int}})
4242
// FIXME: put throws in a range!
43-
// S1_DOT: {name:method6}({params:{l:c:}{t: Int}}){throws: throws}
44-
// S1_DOT: {name:method7}({params:{l:callback:}{t: () throws -> ()}}){throws: rethrows}
43+
// S1_DOT: {name:method6}({params:{l:c:}{t: Int}}) throws
44+
// S1_DOT: {name:method7}({params:{l:callback:}{t: () throws -> ()}}) rethrows
4545
// S1_DOT: {name:method8}({params:{l:d:}{t: (T, U) -> T}, {n:e:}{t: (T) -> U}})
4646
// S1_DOT: {name:v1}
4747
// S1_DOT: {name:v2}

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,6 @@ struct CodeCompletionInfo {
120120
struct DescriptionStructure {
121121
IndexRange baseName;
122122
IndexRange parameterRange;
123-
IndexRange throwsRange;
124123
};
125124

126125
Optional<DescriptionStructure> descriptionStructure;

tools/SourceKit/lib/SwiftLang/SwiftCompletion.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -271,12 +271,6 @@ static void getResultStructure(
271271
if (C.is(ChunkKind::BraceStmtWithCursor))
272272
break;
273273

274-
if (C.is(ChunkKind::ThrowsKeyword) ||
275-
C.is(ChunkKind::RethrowsKeyword)) {
276-
structure.throwsRange.begin = textSize;
277-
structure.throwsRange.end = textSize + C.getText().size();
278-
}
279-
280274
if (C.is(ChunkKind::CallParameterBegin)) {
281275
CodeCompletionInfo::ParameterStructure param;
282276

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2263,8 +2263,6 @@ bool SKGroupedCodeCompletionConsumer::handleResult(const CodeCompletionInfo &R)
22632263
R.descriptionStructure->baseName);
22642264
addRange(structure, KeyBodyOffset, KeyBodyLength,
22652265
R.descriptionStructure->parameterRange);
2266-
addRange(structure, KeyThrowOffset, KeyThrowLength,
2267-
R.descriptionStructure->throwsRange);
22682266

22692267
if (R.parametersStructure) {
22702268
auto params = structure.setArray(KeySubStructure);

0 commit comments

Comments
 (0)