Skip to content

Commit f08c2b0

Browse files
authored
Merge pull request #19709 from rintaro/ide-completion-trailingclosurelocal-rdar41869885
[CodeCompletion] Fix completion for local decls in trailing closure
2 parents 1dcb06b + 3d80635 commit f08c2b0

File tree

4 files changed

+42
-47
lines changed

4 files changed

+42
-47
lines changed

include/swift/Parse/CodeCompletionCallbacks.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ class CodeCompletionCallbacks {
196196

197197
virtual void completeAssignmentRHS(AssignExpr *E) = 0;
198198

199-
virtual void completeCallArg(CallExpr *E) = 0;
199+
virtual void completeCallArg(CodeCompletionExpr *E) = 0;
200200

201201
virtual void completeReturnStmt(CodeCompletionExpr *E) = 0;
202202

lib/IDE/CodeCompletion.cpp

Lines changed: 16 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,7 +1296,6 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks {
12961296
CodeCompletionConsumer &Consumer;
12971297
CodeCompletionExpr *CodeCompleteTokenExpr = nullptr;
12981298
AssignExpr *AssignmentExpr;
1299-
CallExpr *FuncCallExpr;
13001299
CompletionKind Kind = CompletionKind::None;
13011300
Expr *ParsedExpr = nullptr;
13021301
SourceLoc DotLoc;
@@ -1462,7 +1461,7 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks {
14621461
void completeUnresolvedMember(CodeCompletionExpr *E,
14631462
SourceLoc DotLoc) override;
14641463
void completeAssignmentRHS(AssignExpr *E) override;
1465-
void completeCallArg(CallExpr *E) override;
1464+
void completeCallArg(CodeCompletionExpr *E) override;
14661465
void completeReturnStmt(CodeCompletionExpr *E) override;
14671466
void completeYieldStmt(CodeCompletionExpr *E,
14681467
Optional<unsigned> yieldIndex) override;
@@ -3952,22 +3951,6 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
39523951
return !ExpectedTypes.empty() || !ExpectedNames.empty();
39533952
}
39543953

3955-
bool getCallArgCompletions(DeclContext &DC, CallExpr *CallE, Expr *CCExpr) {
3956-
std::vector<Type> ExpectedTypes;
3957-
std::vector<StringRef> ExpectedNames;
3958-
if (!collectArgumentExpectation(DC, CallE, CCExpr, ExpectedTypes,
3959-
ExpectedNames))
3960-
return false;
3961-
3962-
addArgNameCompletionResults(ExpectedNames);
3963-
if (!ExpectedTypes.empty()) {
3964-
setExpectedTypes(ExpectedTypes);
3965-
getValueCompletionsInDeclContext(CCExpr->getStartLoc(), DefaultFilter);
3966-
}
3967-
3968-
return true;
3969-
}
3970-
39713954
void getTypeContextEnumElementCompletions(SourceLoc Loc) {
39723955
llvm::SaveAndRestore<LookupKind> ChangeLookupKind(
39733956
Kind, LookupKind::EnumElement);
@@ -4654,14 +4637,10 @@ void CodeCompletionCallbacksImpl::completeAssignmentRHS(AssignExpr *E) {
46544637
Kind = CompletionKind::AssignmentRHS;
46554638
}
46564639

4657-
void CodeCompletionCallbacksImpl::completeCallArg(CallExpr *E) {
4658-
if (Kind == CompletionKind::PostfixExprBeginning ||
4659-
Kind == CompletionKind::None) {
4660-
CurDeclContext = P.CurDeclContext;
4661-
Kind = CompletionKind::CallArg;
4662-
FuncCallExpr = E;
4663-
ParsedExpr = E;
4664-
}
4640+
void CodeCompletionCallbacksImpl::completeCallArg(CodeCompletionExpr *E) {
4641+
CurDeclContext = P.CurDeclContext;
4642+
CodeCompleteTokenExpr = E;
4643+
Kind = CompletionKind::CallArg;
46654644
}
46664645

46674646
void CodeCompletionCallbacksImpl::completeReturnStmt(CodeCompletionExpr *E) {
@@ -5586,10 +5565,17 @@ void CodeCompletionCallbacksImpl::doneParsing() {
55865565
break;
55875566
}
55885567
case CompletionKind::CallArg : {
5589-
if (!CodeCompleteTokenExpr || !Lookup.getCallArgCompletions(*CurDeclContext,
5590-
FuncCallExpr,
5591-
CodeCompleteTokenExpr))
5592-
DoPostfixExprBeginning();
5568+
::CodeCompletionTypeContextAnalyzer Analyzer(CurDeclContext,
5569+
CodeCompleteTokenExpr);
5570+
SmallVector<Type, 2> PossibleTypes;
5571+
SmallVector<StringRef, 2> PossibleNames;
5572+
Analyzer.Analyze(PossibleTypes, PossibleNames);
5573+
if (!PossibleNames.empty()) {
5574+
Lookup.addArgNameCompletionResults(PossibleNames);
5575+
break;
5576+
}
5577+
Lookup.setExpectedTypes(PossibleTypes);
5578+
DoPostfixExprBeginning();
55935579
break;
55945580
}
55955581

lib/Parse/ParseExpr.cpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2921,6 +2921,15 @@ ParserStatus Parser::parseExprList(tok leftTok, tok rightTok,
29212921
SubExpr = new(Context) UnresolvedDeclRefExpr(OperName,
29222922
DeclRefKind::Ordinary,
29232923
DeclNameLoc(Loc));
2924+
} else if (Kind == SyntaxKind::FunctionCallArgumentList &&
2925+
Tok.is(tok::code_complete)) {
2926+
// Handle call arguments specially because it may need argument labels.
2927+
auto CCExpr = new (Context) CodeCompletionExpr(Tok.getLoc());
2928+
if (CodeCompletion)
2929+
CodeCompletion->completeCallArg(CCExpr);
2930+
consumeIf(tok::code_complete);
2931+
SubExpr = CCExpr;
2932+
Status.setHasCodeCompletion();
29242933
} else {
29252934
auto ParsedSubExpr = parseExpr(diag::expected_expr_in_expr_list);
29262935
SubExpr = ParsedSubExpr.getPtrOrNull();
@@ -3188,20 +3197,10 @@ Parser::parseExprCallSuffix(ParserResult<Expr> fn, bool isExprBasic) {
31883197
SyntaxKind::FunctionCallArgumentList);
31893198

31903199
// Form the call.
3191-
auto Result = makeParserResult(status | fn,
3192-
CallExpr::create(Context, fn.get(), lParenLoc,
3193-
args, argLabels, argLabelLocs,
3194-
rParenLoc, trailingClosure,
3195-
/*implicit=*/false));
3196-
3197-
if (status.hasCodeCompletion()) {
3198-
if (CodeCompletion) {
3199-
CodeCompletion->completeCallArg(Result.get());
3200-
}
3201-
Result.setHasCodeCompletion();
3202-
}
3203-
3204-
return Result;
3200+
return makeParserResult(
3201+
status | fn, CallExpr::create(Context, fn.get(), lParenLoc, args,
3202+
argLabels, argLabelLocs, rParenLoc,
3203+
trailingClosure, /*implicit=*/false));
32053204
}
32063205

32073206
/// parseExprCollection - Parse a collection literal expression.

test/IDE/complete_call_arg.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99

1010
// RUN-FIXME: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=OVERLOAD1 | %FileCheck %s -check-prefix=OVERLOAD1
1111
// RUN-FIXME: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=OVERLOAD2 | %FileCheck %s -check-prefix=OVERLOAD2
12-
// RUN-FIXME: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=OVERLOAD3 | %FileCheck %s -check-prefix=OVERLOAD3
13-
// RUN-FIXME: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=OVERLOAD4 | %FileCheck %s -check-prefix=OVERLOAD4
12+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=OVERLOAD3 | %FileCheck %s -check-prefix=OVERLOAD3
13+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=OVERLOAD4 | %FileCheck %s -check-prefix=OVERLOAD4
1414

1515
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=MEMBER1 | %FileCheck %s -check-prefix=MEMBER1
1616
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=MEMBER2 | %FileCheck %s -check-prefix=MEMBER2
@@ -425,3 +425,13 @@ func curry<T1, T2, R>(_ f: @escaping (T1, T2) -> R) -> (T1) -> (T2) -> R {
425425
// NESTED_CLOSURE: Decl[LocalVar]/Local: t2; name=t2
426426
// NESTED_CLOSURE: Decl[LocalVar]/Local: t1[#T1#]; name=t1
427427
}
428+
429+
func trailingClosureLocal(x: Int, fn: (Int) -> Void) {
430+
trailingClosureLocal(x: 1) { localArg in
431+
var localVar = 1
432+
if #^TRAILING_CLOSURE_LOCAL^#
433+
}
434+
// TRAILING_CLOSURE_LOCAL: Begin completions
435+
// TRAILING_CLOSURE_LOCAL: Decl[LocalVar]/Local: localArg[#Int#]; name=localArg
436+
// TRAILING_CLOSURE_LOCAL: Decl[LocalVar]/Local: localVar[#Int#]; name=localVar
437+
}

0 commit comments

Comments
 (0)