@@ -5488,35 +5488,18 @@ ParserStatus Parser::parseGetSet(ParseDeclOptions Flags,
54885488 AccessorCtx.reset ();
54895489
54905490 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) {
55135496 CodeCompletion->setParsedDecl (storage);
5497+ CodeCompletion->completeAccessorBeginning (nullptr );
55145498 }
5515- CodeCompletion->completeAccessorBeginning (CCE);
5499+ consumeToken (tok::code_complete);
5500+ accessorHasCodeCompletion = true ;
5501+ break ;
55165502 }
5517- consumeToken (tok::code_complete);
5518- accessorHasCodeCompletion = true ;
5519- break ;
55205503 }
55215504
55225505 // parsingLimitedSyntax mode cannot have a body.
@@ -6359,7 +6342,47 @@ ParserResult<FuncDecl> Parser::parseDeclFunc(SourceLoc StaticLoc,
63596342 return DCC.fixupParserResult (FD);
63606343}
63616344
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.
63636386void Parser::parseAbstractFunctionBody (AbstractFunctionDecl *AFD) {
63646387 if (!Tok.is (tok::l_brace)) {
63656388 checkForInputIncomplete ();
@@ -6379,21 +6402,7 @@ void Parser::parseAbstractFunctionBody(AbstractFunctionDecl *AFD) {
63796402
63806403 Scope S (this , ScopeKind::FunctionBody);
63816404
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);
63976406 if (!Body.isNull ()) {
63986407 BraceStmt * BS = Body.get ();
63996408 AFD->setBodyParsed (BS);
@@ -6476,13 +6485,8 @@ BraceStmt *Parser::parseAbstractFunctionBodyDelayed(AbstractFunctionDecl *AFD) {
64766485 // Re-enter the lexical scope.
64776486 Scope TopLevelScope (this , ScopeKind::TopLevel);
64786487 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 ());
64846488
6485- return parseBraceItemList (diag::func_decl_without_brace ).getPtrOrNull ();
6489+ return parseAbstractFunctionBodyImpl (AFD ).getPtrOrNull ();
64866490}
64876491
64886492// / Parse a 'enum' declaration, returning true (and doing no token
0 commit comments