@@ -5488,35 +5488,18 @@ ParserStatus Parser::parseGetSet(ParseDeclOptions Flags,
5488
5488
AccessorCtx.reset ();
5489
5489
5490
5490
if (Tok.is (tok::code_complete)) {
5491
- if (CodeCompletion) {
5492
- CodeCompletionExpr *CCE = nullptr ;
5493
- if (IsFirstAccessor && !parsingLimitedSyntax) {
5494
- // If CC token is the first token after '{', it might be implicit
5495
- // getter. Set up dummy accessor as the decl context to populate
5496
- // 'self' decl.
5497
-
5498
- // FIXME: if there is already code inside the body, we should fall
5499
- // through to parseImplicitGetter and handle the completion there so
5500
- // that we can differentiate a single-expression body from the first
5501
- // expression in a multi-statement body.
5502
- auto getter = createAccessorFunc (
5503
- accessors.LBLoc , /* ValueNamePattern*/ nullptr , GenericParams,
5504
- Indices, StaticLoc, Flags, AccessorKind::Get,
5505
- storage, this , /* AccessorKeywordLoc*/ SourceLoc ());
5506
- CCE = new (Context) CodeCompletionExpr (Tok.getLoc ());
5507
- getter->setBodyParsed (BraceStmt::create (Context, Tok.getLoc (),
5508
- ASTNode (CCE), Tok.getLoc (),
5509
- /* implicit*/ true ));
5510
- accessors.add (getter);
5511
- CodeCompletion->setParsedDecl (getter);
5512
- } else {
5491
+ // Handle code completion here only if it's not the first accessor.
5492
+ // If it's the first accessor, it's handled in function body parsing
5493
+ // because it might be an implicit getter.
5494
+ if (!IsFirstAccessor || parsingLimitedSyntax) {
5495
+ if (CodeCompletion) {
5513
5496
CodeCompletion->setParsedDecl (storage);
5497
+ CodeCompletion->completeAccessorBeginning (nullptr );
5514
5498
}
5515
- CodeCompletion->completeAccessorBeginning (CCE);
5499
+ consumeToken (tok::code_complete);
5500
+ accessorHasCodeCompletion = true ;
5501
+ break ;
5516
5502
}
5517
- consumeToken (tok::code_complete);
5518
- accessorHasCodeCompletion = true ;
5519
- break ;
5520
5503
}
5521
5504
5522
5505
// parsingLimitedSyntax mode cannot have a body.
@@ -6359,7 +6342,47 @@ ParserResult<FuncDecl> Parser::parseDeclFunc(SourceLoc StaticLoc,
6359
6342
return DCC.fixupParserResult (FD);
6360
6343
}
6361
6344
6362
- // / Parse function body into \p AFD.
6345
+ // / Parse a function body for \p AFD and returns it without setting the body
6346
+ // / to \p AFD .
6347
+ ParserResult<BraceStmt>
6348
+ Parser::parseAbstractFunctionBodyImpl (AbstractFunctionDecl *AFD) {
6349
+ assert (Tok.is (tok::l_brace));
6350
+
6351
+ // Enter the arguments for the function into a new function-body scope. We
6352
+ // need this even if there is no function body to detect argument name
6353
+ // duplication.
6354
+ if (auto *P = AFD->getImplicitSelfDecl ())
6355
+ addToScope (P);
6356
+ addParametersToScope (AFD->getParameters ());
6357
+
6358
+ // Establish the new context.
6359
+ ParseFunctionBody CC (*this , AFD);
6360
+ setLocalDiscriminatorToParamList (AFD->getParameters ());
6361
+
6362
+ if (Context.Stats )
6363
+ Context.Stats ->getFrontendCounters ().NumFunctionsParsed ++;
6364
+
6365
+ // In implicit getter, if a CC token is the first token after '{', it might
6366
+ // be a start of an accessor block. Perform special completion for that.
6367
+ if (auto accessor = dyn_cast<AccessorDecl>(AFD)) {
6368
+ if (peekToken ().is (tok::code_complete) && accessor->isImplicitGetter ()) {
6369
+ SourceLoc LBraceLoc, RBraceLoc;
6370
+ LBraceLoc = consumeToken (tok::l_brace);
6371
+ auto *CCE = new (Context) CodeCompletionExpr (Tok.getLoc ());
6372
+ CodeCompletion->setParsedDecl (accessor);
6373
+ CodeCompletion->completeAccessorBeginning (CCE);
6374
+ RBraceLoc = Tok.getLoc ();
6375
+ consumeToken (tok::code_complete);
6376
+ return makeParserCodeCompletionResult (
6377
+ BraceStmt::create (Context, LBraceLoc, ASTNode (CCE), RBraceLoc,
6378
+ /* implicit*/ true ));
6379
+ }
6380
+ }
6381
+
6382
+ return parseBraceItemList (diag::invalid_diagnostic);
6383
+ }
6384
+
6385
+ // / Parse function body into \p AFD or skip it for delayed parsing.
6363
6386
void Parser::parseAbstractFunctionBody (AbstractFunctionDecl *AFD) {
6364
6387
if (!Tok.is (tok::l_brace)) {
6365
6388
checkForInputIncomplete ();
@@ -6379,21 +6402,7 @@ void Parser::parseAbstractFunctionBody(AbstractFunctionDecl *AFD) {
6379
6402
6380
6403
Scope S (this , ScopeKind::FunctionBody);
6381
6404
6382
- // Enter the arguments for the function into a new function-body scope. We
6383
- // need this even if there is no function body to detect argument name
6384
- // duplication.
6385
- if (auto *P = AFD->getImplicitSelfDecl ())
6386
- addToScope (P);
6387
- addParametersToScope (AFD->getParameters ());
6388
-
6389
- // Establish the new context.
6390
- ParseFunctionBody CC (*this , AFD);
6391
- setLocalDiscriminatorToParamList (AFD->getParameters ());
6392
-
6393
- if (Context.Stats )
6394
- Context.Stats ->getFrontendCounters ().NumFunctionsParsed ++;
6395
-
6396
- ParserResult<BraceStmt> Body = parseBraceItemList (diag::invalid_diagnostic);
6405
+ ParserResult<BraceStmt> Body = parseAbstractFunctionBodyImpl (AFD);
6397
6406
if (!Body.isNull ()) {
6398
6407
BraceStmt * BS = Body.get ();
6399
6408
AFD->setBodyParsed (BS);
@@ -6476,13 +6485,8 @@ BraceStmt *Parser::parseAbstractFunctionBodyDelayed(AbstractFunctionDecl *AFD) {
6476
6485
// Re-enter the lexical scope.
6477
6486
Scope TopLevelScope (this , ScopeKind::TopLevel);
6478
6487
Scope S (this , ScopeKind::FunctionBody);
6479
- if (auto *P = AFD->getImplicitSelfDecl ())
6480
- addToScope (P);
6481
- addParametersToScope (AFD->getParameters ());
6482
- ParseFunctionBody CC (*this , AFD);
6483
- setLocalDiscriminatorToParamList (AFD->getParameters ());
6484
6488
6485
- return parseBraceItemList (diag::func_decl_without_brace ).getPtrOrNull ();
6489
+ return parseAbstractFunctionBodyImpl (AFD ).getPtrOrNull ();
6486
6490
}
6487
6491
6488
6492
// / Parse a 'enum' declaration, returning true (and doing no token
0 commit comments