Skip to content

Commit ed82d18

Browse files
committed
[CodeCompletion] Complete effects specifiers in closure signature position
1 parent 4284a51 commit ed82d18

File tree

3 files changed

+50
-37
lines changed

3 files changed

+50
-37
lines changed

include/swift/Parse/Parser.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1563,8 +1563,9 @@ class Parser {
15631563
/// \param explicitResultType The explicit result type, if specified.
15641564
/// \param inLoc The location of the 'in' keyword, if present.
15651565
///
1566-
/// \returns true if an error occurred, false otherwise.
1567-
bool parseClosureSignatureIfPresent(
1566+
/// \returns ParserStatus error if an error occurred. Success if no signature
1567+
/// is present or succssfully parsed.
1568+
ParserStatus parseClosureSignatureIfPresent(
15681569
SourceRange &bracketRange,
15691570
SmallVectorImpl<CaptureListEntry> &captureList,
15701571
VarDecl *&capturedSelfParamDecl,

lib/Parse/ParseExpr.cpp

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2323,14 +2323,14 @@ static void printTupleNames(const TypeRepr *typeRepr, llvm::raw_ostream &OS) {
23232323
OS << ")";
23242324
}
23252325

2326-
bool Parser::
2327-
parseClosureSignatureIfPresent(SourceRange &bracketRange,
2328-
SmallVectorImpl<CaptureListEntry> &captureList,
2329-
VarDecl *&capturedSelfDecl,
2330-
ParameterList *&params,
2331-
SourceLoc &asyncLoc, SourceLoc &throwsLoc,
2332-
SourceLoc &arrowLoc,
2333-
TypeExpr *&explicitResultType, SourceLoc &inLoc){
2326+
ParserStatus Parser::parseClosureSignatureIfPresent(
2327+
SourceRange &bracketRange,
2328+
SmallVectorImpl<CaptureListEntry> &captureList,
2329+
VarDecl *&capturedSelfDecl,
2330+
ParameterList *&params,
2331+
SourceLoc &asyncLoc, SourceLoc &throwsLoc,
2332+
SourceLoc &arrowLoc,
2333+
TypeExpr *&explicitResultType, SourceLoc &inLoc) {
23342334
// Clear out result parameters.
23352335
bracketRange = SourceRange();
23362336
capturedSelfDecl = nullptr;
@@ -2342,19 +2342,21 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
23422342

23432343
// Consume 'async', 'throws', and 'rethrows', but in any order.
23442344
auto consumeAsyncThrows = [&] {
2345-
bool hadAsync = false;
2346-
if (shouldParseExperimentalConcurrency() &&
2347-
Tok.isContextualKeyword("async")) {
2348-
consumeToken();
2349-
hadAsync = true;
2350-
}
2345+
while (true) {
2346+
if (shouldParseExperimentalConcurrency() &&
2347+
Tok.isContextualKeyword("async")) {
2348+
consumeToken();
2349+
continue;
2350+
}
2351+
if (consumeIf(tok::kw_throws) || consumeIf(tok::kw_rethrows))
2352+
continue;
23512353

2352-
if (!consumeIf(tok::kw_throws) && !consumeIf(tok::kw_rethrows))
2353-
return;
2354+
if (Tok.is(tok::code_complete) && !Tok.isAtStartOfLine()) {
2355+
consumeToken();
2356+
continue;
2357+
}
23542358

2355-
if (shouldParseExperimentalConcurrency() && !hadAsync &&
2356-
Tok.isContextualKeyword("async")) {
2357-
consumeToken();
2359+
break;
23582360
}
23592361
};
23602362

@@ -2367,7 +2369,7 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
23672369
if (consumeIf(tok::l_square)) {
23682370
skipUntil(tok::r_square);
23692371
if (!consumeIf(tok::r_square))
2370-
return false;
2372+
return makeParserSuccess();
23712373
}
23722374

23732375
// Parse pattern-tuple func-signature-result? 'in'.
@@ -2384,7 +2386,7 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
23842386
// Parse the func-signature-result, if present.
23852387
if (consumeIf(tok::arrow)) {
23862388
if (!canParseType())
2387-
return false;
2389+
return makeParserSuccess();
23882390
}
23892391
}
23902392

@@ -2398,27 +2400,28 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
23982400
continue;
23992401
}
24002402

2401-
return false;
2403+
return makeParserSuccess();
24022404
}
24032405

24042406
consumeAsyncThrows();
24052407

24062408
// Parse the func-signature-result, if present.
24072409
if (consumeIf(tok::arrow)) {
24082410
if (!canParseType())
2409-
return false;
2411+
return makeParserSuccess();
24102412
}
24112413
}
24122414

24132415
// Parse the 'in' at the end.
24142416
if (Tok.isNot(tok::kw_in))
2415-
return false;
2417+
return makeParserSuccess();
24162418

24172419
// Okay, we have a closure signature.
24182420
} else {
24192421
// No closure signature.
2420-
return false;
2422+
return makeParserSuccess();
24212423
}
2424+
ParserStatus status;
24222425
SyntaxParsingContext ClosureSigCtx(SyntaxContext, SyntaxKind::ClosureSignature);
24232426
if (Tok.is(tok::l_square) && peekToken().is(tok::r_square)) {
24242427

@@ -2563,7 +2566,7 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
25632566
if (pattern.isNonNull())
25642567
params = pattern.get();
25652568
else
2566-
invalid = true;
2569+
status.setIsParseError();
25672570
} else {
25682571
SyntaxParsingContext ClParamListCtx(SyntaxContext,
25692572
SyntaxKind::ClosureParamList);
@@ -2574,7 +2577,7 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
25742577
SyntaxParsingContext ClParamCtx(SyntaxContext, SyntaxKind::ClosureParam);
25752578
if (Tok.isNot(tok::identifier, tok::kw__)) {
25762579
diagnose(Tok, diag::expected_closure_parameter_name);
2577-
invalid = true;
2580+
status.setIsParseError();
25782581
break;
25792582
}
25802583

@@ -2598,8 +2601,8 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
25982601
params = ParameterList::create(Context, elements);
25992602
}
26002603

2601-
parseEffectsSpecifiers(SourceLoc(), asyncLoc, throwsLoc,
2602-
/*rethrows*/nullptr);
2604+
status |= parseEffectsSpecifiers(SourceLoc(), asyncLoc, throwsLoc,
2605+
/*rethrows*/nullptr);
26032606

26042607
// Parse the optional explicit return type.
26052608
if (Tok.is(tok::arrow)) {
@@ -2613,7 +2616,7 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
26132616
if (!explicitResultTypeRepr) {
26142617
// If we couldn't parse the result type, clear out the arrow location.
26152618
arrowLoc = SourceLoc();
2616-
invalid = true;
2619+
status.setIsParseError();
26172620
} else {
26182621
explicitResultType = new (Context) TypeExpr(explicitResultTypeRepr);
26192622
}
@@ -2653,7 +2656,7 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
26532656
}
26542657

26552658
if (!params)
2656-
return invalid;
2659+
return status;
26572660

26582661
// If this was a closure declaration (maybe even trailing)
26592662
// tuple parameter destructuring is one of the common
@@ -2691,14 +2694,15 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
26912694
.fixItReplace(param->getSourceRange(), argName)
26922695
.fixItInsert(Tok.getLoc(), OS.str());
26932696

2694-
invalid = true;
2697+
status.setIsParseError();
26952698
}
26962699

2697-
return invalid;
2700+
return status;
26982701
}
26992702

27002703
ParserResult<Expr> Parser::parseExprClosure() {
27012704
assert(Tok.is(tok::l_brace) && "Not at a left brace?");
2705+
ParserStatus Status;
27022706
SyntaxParsingContext ClosureContext(SyntaxContext, SyntaxKind::ClosureExpr);
27032707
// We may be parsing this closure expr in a matching pattern context. If so,
27042708
// reset our state to not be in a pattern for any recursive pattern parses.
@@ -2718,7 +2722,7 @@ ParserResult<Expr> Parser::parseExprClosure() {
27182722
SourceLoc arrowLoc;
27192723
TypeExpr *explicitResultType;
27202724
SourceLoc inLoc;
2721-
parseClosureSignatureIfPresent(
2725+
Status |= parseClosureSignatureIfPresent(
27222726
bracketRange, captureList, capturedSelfDecl, params, asyncLoc, throwsLoc,
27232727
arrowLoc, explicitResultType, inLoc);
27242728

@@ -2753,7 +2757,6 @@ ParserResult<Expr> Parser::parseExprClosure() {
27532757

27542758
// Parse the body.
27552759
SmallVector<ASTNode, 4> bodyElements;
2756-
ParserStatus Status;
27572760
Status |= parseBraceItems(bodyElements, BraceItemListKind::Brace);
27582761

27592762
if (SourceMgr.rangeContainsCodeCompletionLoc({leftBrace, PreviousLoc})) {

test/IDE/complete_concurrency_specifier.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,12 @@ func testTypeSpecifierWithArrow(_: () #^TYPE_SPECIFICER_WITHARROW?check=SPECIFIE
3232
func testTypeSpecifierWithAsyncArrow(_: () async #^TYPE_SPECIFICER_WITHASYNCARROW?check=SPECIFIER_WITHASYNC^# -> Void) {}
3333
func testTypeSpecifierWithThrowsArrow(_: () throws #^TYPE_SPECIFICER_WITHTHROWSARROW?check=SPECIFIER_WITHTHROWS^# -> Void
3434
func testTypeSpecifierWithAsyncThrowsArrow(_: () async throws #^TYPE_SPECIFICER_WITHASYNCTHROWSARROW?check=SPECIFIER_WITHASYNCTHROWS^# -> Void) {}
35+
36+
_ = { () #^CLOSURE?check=SPECIFIER^# in }
37+
_ = { () async #^CLOSURE_WITHASYNC?check=SPECIFIER_WITHASYNC^# in }
38+
_ = { () throws #^CLOSURE_WITHTHROWS?check=SPECIFIER_WITHTHROWS^# in }
39+
_ = { () async throws #^CLOSURE_WITHAASYNCTHROWS?check=SPECIFIER_WITHASYNCTHROWS^# in }
40+
_ = { () #^CLOSURE_WITHARROW?check=SPECIFIER^# -> Void in }
41+
_ = { () async #^CLOSURE_WITHASYNCARROW?check=SPECIFIER_WITHASYNC^# -> Void in }
42+
_ = { () throws #^CLOSURE_WITHTHROWSARROW?check=SPECIFIER_WITHTHROWS^# -> Void in }
43+
_ = { () async throws #^CLOSURE_WITHASYNCTHROWSARROW?check=SPECIFIER_WITHASYNCTHROWS^# -> Void in }

0 commit comments

Comments
 (0)