Skip to content

Commit cd53207

Browse files
authored
Merge pull request #37877 from rintaro/5.5-ide-completion-rdar78798718
[5.5][CodeCompletion] Don't offer completion names for closure argument names
2 parents 50c9826 + 5eb0f74 commit cd53207

File tree

3 files changed

+68
-15
lines changed

3 files changed

+68
-15
lines changed

lib/Parse/ParseExpr.cpp

Lines changed: 31 additions & 12 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
}
@@ -2575,7 +2575,7 @@ ParserStatus Parser::parseClosureSignatureIfPresent(
25752575
if (!consumeIf(tok::r_paren, ownershipLocEnd))
25762576
diagnose(Tok, diag::attr_unowned_expected_rparen);
25772577
}
2578-
} else if (Tok.isAny(tok::identifier, tok::kw_self) &&
2578+
} else if (Tok.isAny(tok::identifier, tok::kw_self, tok::code_complete) &&
25792579
peekToken().isAny(tok::equal, tok::comma, tok::r_square)) {
25802580
// "x = 42", "x," and "x]" are all strong captures of x.
25812581
} else {
@@ -2584,7 +2584,7 @@ ParserStatus Parser::parseClosureSignatureIfPresent(
25842584
continue;
25852585
}
25862586

2587-
if (Tok.isNot(tok::identifier, tok::kw_self)) {
2587+
if (Tok.isNot(tok::identifier, tok::kw_self, tok::code_complete)) {
25882588
diagnose(Tok, diag::expected_capture_specifier_name);
25892589
skipUntil(tok::comma, tok::r_square);
25902590
continue;
@@ -2602,10 +2602,20 @@ ParserStatus Parser::parseClosureSignatureIfPresent(
26022602
if (peekToken().isNot(tok::equal)) {
26032603
// If this is the simple case, then the identifier is both the name and
26042604
// the expression to capture.
2605-
name = Context.getIdentifier(Tok.getText());
2606-
auto initializerResult = parseExprIdentifier();
2607-
status |= initializerResult;
2608-
initializer = initializerResult.get();
2605+
if (!Tok.is(tok::code_complete)) {
2606+
name = Context.getIdentifier(Tok.getText());
2607+
auto initializerResult = parseExprIdentifier();
2608+
status |= initializerResult;
2609+
initializer = initializerResult.get();
2610+
} else {
2611+
auto CCE = new (Context) CodeCompletionExpr(Tok.getLoc());
2612+
if (CodeCompletion)
2613+
CodeCompletion->completePostfixExprBeginning(CCE);
2614+
name = Identifier();
2615+
initializer = CCE;
2616+
consumeToken();
2617+
status.setHasCodeCompletion();
2618+
}
26092619

26102620
// It is a common error to try to capture a nested field instead of just
26112621
// a local name, reject it with a specific error message.
@@ -2617,7 +2627,13 @@ ParserStatus Parser::parseClosureSignatureIfPresent(
26172627

26182628
} else {
26192629
// Otherwise, the name is a new declaration.
2620-
consumeIdentifier(name, /*diagnoseDollarPrefix=*/true);
2630+
if (!Tok.is(tok::code_complete)) {
2631+
consumeIdentifier(name, /*diagnoseDollarPrefix=*/true);
2632+
} else {
2633+
// Ignore completion token because it's a new declaration.
2634+
name = Identifier();
2635+
consumeToken(tok::code_complete);
2636+
}
26212637
equalLoc = consumeToken(tok::equal);
26222638

26232639
auto ExprResult = parseExpr(diag::expected_init_capture_specifier);
@@ -2687,7 +2703,7 @@ ParserStatus Parser::parseClosureSignatureIfPresent(
26872703
bool HasNext;
26882704
do {
26892705
SyntaxParsingContext ClParamCtx(SyntaxContext, SyntaxKind::ClosureParam);
2690-
if (Tok.isNot(tok::identifier, tok::kw__)) {
2706+
if (Tok.isNot(tok::identifier, tok::kw__, tok::code_complete)) {
26912707
diagnose(Tok, diag::expected_closure_parameter_name);
26922708
status.setIsParseError();
26932709
break;
@@ -2698,7 +2714,10 @@ ParserStatus Parser::parseClosureSignatureIfPresent(
26982714
if (Tok.is(tok::identifier)) {
26992715
nameLoc = consumeIdentifier(name, /*diagnoseDollarPrefix=*/false);
27002716
} else {
2701-
nameLoc = consumeToken(tok::kw__);
2717+
assert(Tok.isAny(tok::kw__ , tok::code_complete));
2718+
// Consume and ignore code_completion token so that completion don't
2719+
// suggest anything for the parameter name declaration.
2720+
nameLoc = consumeToken();
27022721
}
27032722
auto var = new (Context)
27042723
ParamDecl(SourceLoc(), SourceLoc(),

test/IDE/complete_concurrency_specifier.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,12 @@ _ = { () #^CLOSURE_WITHARROW?check=SPECIFIER^# -> Void in }
4343
_ = { () async #^CLOSURE_WITHASYNCARROW?check=SPECIFIER_WITHASYNC^# -> Void in }
4444
_ = { () throws #^CLOSURE_WITHTHROWSARROW?check=SPECIFIER_WITHTHROWS^# -> Void in }
4545
_ = { () async throws #^CLOSURE_WITHASYNCTHROWSARROW?check=SPECIFIER_WITHASYNCTHROWS^# -> Void in }
46+
47+
_ = { arg #^CLOSURE2?check=SPECIFIER^# in }
48+
_ = { arg async #^CLOSURE2_WITHASYNC?check=SPECIFIER_WITHASYNC^# in }
49+
_ = { arg throws #^CLOSURE2_WITHTHROWS?check=SPECIFIER_WITHTHROWS^# in }
50+
_ = { arg async throws #^CLOSURE2_WITHAASYNCTHROWS?check=SPECIFIER_WITHASYNCTHROWS^# in }
51+
_ = { arg #^CLOSURE2_WITHARROW?check=SPECIFIER^# -> Void in }
52+
_ = { arg async #^CLOSURE2_WITHASYNCARROW?check=SPECIFIER_WITHASYNC^# -> Void in }
53+
_ = { arg throws #^CLOSURE2_WITHTHROWSARROW?check=SPECIFIER_WITHTHROWS^# -> Void in }
54+
_ = { arg async throws #^CLOSURE2_WITHASYNCTHROWSARROW?check=SPECIFIER_WITHASYNCTHROWS^# -> Void in }

test/IDE/complete_in_closures.swift

Lines changed: 28 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,28 @@ 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+
389+
accept { [#^CAPTURE_1?check=WITH_GLOBAL_DECLS^#] in }
390+
accept { [weak #^CAPTURE_2?check=WITH_GLOBAL_DECLS^#] in }
391+
accept { [#^CAPTURE_3?check=EMPTY^# = capture] in }
392+
accept { [weak #^CAPTURE_4?check=EMPTY^# = capture] in }
393+
394+
accept { () -> #^RESULTTYPE_1?check=WITH_GLOBAL_DECLS^# in }
395+
accept { arg1, arg2 -> #^RESULTTYPE_2?check=WITH_GLOBAL_DECLS^# in }
396+
397+
// NOTE: For effects specifiers completion (e.g. '() <HERE> -> Void') see test/IDE/complete_concurrency_specifier.swift
398+
}

0 commit comments

Comments
 (0)