Skip to content

Commit 9e84948

Browse files
committed
[CodeCompletion] Fallback to nominal member completion after trailing closure
After trailing closure, we perform "Labeled trailing closure" completion and fall back to other completion depending on the position. If the completion happens at a newline position, it used to fallback to global expression completion, but in type context, we should do override completion instead. Also, we didn't use to propagate 'hasCodeCompletion()' status properly. rdar://problem/64650782 (cherry picked from commit f50b666)
1 parent a890d8b commit 9e84948

File tree

3 files changed

+50
-9
lines changed

3 files changed

+50
-9
lines changed

lib/IDE/CodeCompletion.cpp

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6158,15 +6158,29 @@ void CodeCompletionCallbacksImpl::doneParsing() {
61586158
if (IsAtStartOfLine) {
61596159
// foo() {}
61606160
// <HERE>
6161-
// Global completion.
6161+
61626162
auto &Sink = CompletionContext.getResultSink();
6163-
addDeclKeywords(Sink);
6164-
addStmtKeywords(Sink, MaybeFuncBody);
6165-
addSuperKeyword(Sink);
6166-
addLetVarKeywords(Sink);
6167-
addExprKeywords(Sink);
6168-
addAnyTypeKeyword(Sink, CurDeclContext->getASTContext().TheAnyType);
6169-
DoPostfixExprBeginning();
6163+
if (isa<Initializer>(CurDeclContext))
6164+
CurDeclContext = CurDeclContext->getParent();
6165+
6166+
if (CurDeclContext->isTypeContext()) {
6167+
// Override completion (CompletionKind::NominalMemberBeginning).
6168+
addDeclKeywords(Sink);
6169+
addLetVarKeywords(Sink);
6170+
SmallVector<StringRef, 0> ParsedKeywords;
6171+
CompletionOverrideLookup OverrideLookup(Sink, Context, CurDeclContext,
6172+
ParsedKeywords, SourceLoc());
6173+
OverrideLookup.getOverrideCompletions(SourceLoc());
6174+
} else {
6175+
// Global completion (CompletionKind::PostfixExprBeginning).
6176+
addDeclKeywords(Sink);
6177+
addStmtKeywords(Sink, MaybeFuncBody);
6178+
addSuperKeyword(Sink);
6179+
addLetVarKeywords(Sink);
6180+
addExprKeywords(Sink);
6181+
addAnyTypeKeyword(Sink, Context.TheAnyType);
6182+
DoPostfixExprBeginning();
6183+
}
61706184
} else {
61716185
// foo() {} <HERE>
61726186
// Member completion.

lib/Parse/ParseExpr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3228,7 +3228,7 @@ Parser::parseTrailingClosures(bool isExprBasic, SourceRange calleeRange,
32283228
if (CodeCompletion)
32293229
CodeCompletion->completeLabeledTrailingClosure(CCExpr, Tok.isAtStartOfLine());
32303230
consumeToken(tok::code_complete);
3231-
result.hasCodeCompletion();
3231+
result.setHasCodeCompletion();
32323232
closures.push_back({Identifier(), SourceLoc(), CCExpr});
32333233
continue;
32343234
}

test/IDE/complete_multiple_trailingclosure.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=INIT_REQUIRED_NEWLINE_3 | %FileCheck %s -check-prefix=INIT_REQUIRED_NEWLINE_3
1616
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=INIT_FALLBACK_1 | %FileCheck %s -check-prefix=INIT_FALLBACK
1717
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=INIT_FALLBACK_2 | %FileCheck %s -check-prefix=INIT_FALLBACK
18+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=MEMBERDECL_SAMELINE | %FileCheck %s -check-prefix=MEMBERDECL_SAMELINE
19+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=MEMBERDECL_NEWLINE | %FileCheck %s -check-prefix=MEMBERDECL_NEWLINE
1820

1921
func globalFunc1(fn1: () -> Int, fn2: () -> String) {}
2022
func testGlobalFunc() {
@@ -207,3 +209,28 @@ func testFallbackPostfix() {
207209
1
208210
} #^INIT_FALLBACK_2^#
209211
}
212+
213+
protocol P {
214+
func foo()
215+
}
216+
struct TestNominalMember: P {
217+
var value = MyStruct().method1 { 1 } #^MEMBERDECL_SAMELINE^#
218+
#^MEMBERDECL_NEWLINE^#
219+
220+
// MEMBERDECL_SAMELINE: Begin completions, 4 items
221+
// MEMBERDECL_SAMELINE-DAG: Pattern/ExprSpecific: {#fn2: (() -> String)? {() -> String in|}#}[#(() -> String)?#]; name=fn2: (() -> String)?
222+
// MEMBERDECL_SAMELINE-DAG: Decl[InstanceMethod]/CurrNominal: .enumFunc()[#Void#]; name=enumFunc()
223+
// MEMBERDECL_SAMELINE-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]/IsSystem: [' ']+ {#SimpleEnum#}[#SimpleEnum#]; name=+ SimpleEnum
224+
// MEMBERDECL_SAMELINE-DAG: Keyword[self]/CurrNominal: .self[#SimpleEnum#]; name=self
225+
// MEMBERDECL_SAMELINE: End completions
226+
227+
// MEMBERDECL_NEWLINE: Begin completions
228+
// MEMBERDECL_NEWLINE-DAG: Pattern/ExprSpecific: {#fn2: (() -> String)? {() -> String in|}#}[#(() -> String)?#]; name=fn2: (() -> String)?
229+
// MEMBERDECL_NEWLINE-DAG: Keyword[enum]/None: enum; name=enum
230+
// MEMBERDECL_NEWLINE-DAG: Keyword[func]/None: func; name=func
231+
// MEMBERDECL_NEWLINE-DAG: Keyword[private]/None: private; name=private
232+
// MEMBERDECL_NEWLINE-DAG: Keyword/None: lazy; name=lazy
233+
// MEMBERDECL_NEWLINE-DAG: Keyword[var]/None: var; name=var
234+
// MEMBERDECL_NEWLINE-DAG: Decl[InstanceMethod]/Super: func foo() {|}; name=foo()
235+
// MEMBERDECL_NEWLINE: End completions
236+
}

0 commit comments

Comments
 (0)