Skip to content

Commit 5cf87d3

Browse files
committed
[CodeCompletion] Don't offer completion names for closure argument names
Parse a completion token as an empty parameter name (just like `_`) to prevent the parser to parse it as an expression and offer completions for it. rdar://78798718
1 parent 3602f1a commit 5cf87d3

File tree

2 files changed

+26
-8
lines changed

2 files changed

+26
-8
lines changed

lib/Parse/ParseExpr.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2460,7 +2460,7 @@ ParserStatus Parser::parseClosureSignatureIfPresent(
24602460
// speculative parse to validate it and look for 'in'.
24612461
if (Tok.isAny(
24622462
tok::at_sign, tok::l_paren, tok::l_square, tok::identifier,
2463-
tok::kw__)) {
2463+
tok::kw__, tok::code_complete)) {
24642464
BacktrackingScope backtrack(*this);
24652465

24662466
// Consume attributes.
@@ -2496,11 +2496,11 @@ ParserStatus Parser::parseClosureSignatureIfPresent(
24962496
}
24972497

24982498
// Okay, we have a closure signature.
2499-
} else if (Tok.isIdentifierOrUnderscore()) {
2499+
} else if (Tok.isIdentifierOrUnderscore() || Tok.is(tok::code_complete)) {
25002500
// Parse identifier (',' identifier)*
25012501
consumeToken();
25022502
while (consumeIf(tok::comma)) {
2503-
if (Tok.isIdentifierOrUnderscore()) {
2503+
if (Tok.isIdentifierOrUnderscore() || Tok.is(tok::code_complete)) {
25042504
consumeToken();
25052505
continue;
25062506
}
@@ -2687,7 +2687,7 @@ ParserStatus Parser::parseClosureSignatureIfPresent(
26872687
bool HasNext;
26882688
do {
26892689
SyntaxParsingContext ClParamCtx(SyntaxContext, SyntaxKind::ClosureParam);
2690-
if (Tok.isNot(tok::identifier, tok::kw__)) {
2690+
if (Tok.isNot(tok::identifier, tok::kw__, tok::code_complete)) {
26912691
diagnose(Tok, diag::expected_closure_parameter_name);
26922692
status.setIsParseError();
26932693
break;
@@ -2698,7 +2698,10 @@ ParserStatus Parser::parseClosureSignatureIfPresent(
26982698
if (Tok.is(tok::identifier)) {
26992699
nameLoc = consumeIdentifier(name, /*diagnoseDollarPrefix=*/false);
27002700
} else {
2701-
nameLoc = consumeToken(tok::kw__);
2701+
assert(Tok.isAny(tok::kw__ , tok::code_complete));
2702+
// Consume and ignore code_completion token so that completion don't
2703+
// suggest anything for the parameter name declaration.
2704+
nameLoc = consumeToken();
27022705
}
27032706
auto var = new (Context)
27042707
ParamDecl(SourceLoc(), SourceLoc(),

test/IDE/complete_in_closures.swift

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// RUN: %empty-directory(%t)
22
// RUN: %target-swift-ide-test -batch-code-completion -source-filename %s -filecheck %raw-FileCheck -completion-output-dir %t
33

4-
// ERROR_COMMON: found code completion token
5-
// ERROR_COMMON-NOT: Begin completions
4+
// EMTPY: Token
5+
// EMPTY-NOT: Begin completions
66

77
//===--- Helper types that are used in this test
88

@@ -194,7 +194,7 @@ acceptsListAndTrailingClosureTVoid(
194194

195195
func getInt() -> Int? { return 0 }
196196
func testAcceptsTrailingClosureInt1() {
197-
acceptsTrailingClosureFooVoid { #^IN_TRAILING_CLOSURE_16?check=WITH_GLOBAL_DECLS^# in
197+
acceptsTrailingClosureFooVoid { #^IN_TRAILING_CLOSURE_16?check=EMPTY^# in
198198
if let myvar = getInt() {
199199
}
200200
}
@@ -371,3 +371,18 @@ func testInsideTernaryClosureReturn(test: Bool) -> [String] {
371371
// SINGLE_TERNARY_EXPR_CLOSURE_CONTEXT: End completions
372372
}
373373
}
374+
375+
func testSignature() {
376+
func accept<T>(_: () -> T) {}
377+
378+
accept { #^PARAM_BARE_1?check=EMPTY^# in }
379+
accept { #^PARAM_BARE_2?check=EMPTY^#, arg2 in }
380+
accept { arg1, #^PARAM_BARE_3?check=EMPTY^# in }
381+
382+
accept { (#^PARAM_PAREN_1?check=EMPTY^#) in }
383+
accept { (#^PARAM_PAREN_2?check=EMPTY^#, arg2) in }
384+
accept { (arg1, #^PARAM_PAREN_3?check=EMPTY^#) in }
385+
386+
accept { (arg1: #^PARAMTYPE_1?check=WITH_GLOBAL_DECLS^#) in }
387+
accept { (arg1: Int, arg2: #^PARAMTYPE_2?check=WITH_GLOBAL_DECLS^#) in }
388+
}

0 commit comments

Comments
 (0)