Skip to content

Commit cd8ebe4

Browse files
committed
[Parse/CodeCompletion] Cleanup code completion facilities in Parse
- Rename code completion related names in 'PersistentParserState' so it's clear when you are using. - Refactor 'performCodeCompletionSecondPass()': Inline and consolidate 'parse*Delayed()' because they used to share many code. rdar://problem/56926367
1 parent 4e50237 commit cd8ebe4

File tree

6 files changed

+144
-168
lines changed

6 files changed

+144
-168
lines changed

Diff for: include/swift/Parse/Parser.h

+11-5
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ namespace llvm {
4343

4444
namespace swift {
4545
class CodeCompletionCallbacks;
46+
class CodeCompletionCallbacksFactory;
4647
class DefaultArgumentInitializer;
4748
class DiagnosticEngine;
4849
class Expr;
@@ -867,8 +868,6 @@ class Parser {
867868
BraceItemListKind::Brace);
868869
ParserResult<BraceStmt> parseBraceItemList(Diag<> ID);
869870

870-
void parseTopLevelCodeDeclDelayed();
871-
872871
//===--------------------------------------------------------------------===//
873872
// Decl Parsing
874873

@@ -919,8 +918,6 @@ class Parser {
919918
bool IsAtStartOfLineOrPreviousHadSemi,
920919
llvm::function_ref<void(Decl*)> Handler);
921920

922-
void parseDeclDelayed();
923-
924921
std::vector<Decl *> parseDeclListDelayed(IterableDeclContext *IDC);
925922

926923
bool parseMemberDeclList(SourceLoc LBLoc, SourceLoc &RBLoc,
@@ -1089,7 +1086,6 @@ class Parser {
10891086
bool HasFuncKeyword = true);
10901087
void parseAbstractFunctionBody(AbstractFunctionDecl *AFD);
10911088
BraceStmt *parseAbstractFunctionBodyDelayed(AbstractFunctionDecl *AFD);
1092-
void parseAbstractFunctionBodyDelayed();
10931089
ParserResult<ProtocolDecl> parseDeclProtocol(ParseDeclOptions Flags,
10941090
DeclAttributes &Attributes);
10951091

@@ -1583,6 +1579,16 @@ class Parser {
15831579
parsePlatformVersionConstraintSpec();
15841580
ParserResult<PlatformAgnosticVersionConstraintAvailabilitySpec>
15851581
parsePlatformAgnosticVersionConstraintSpec();
1582+
1583+
//===--------------------------------------------------------------------===//
1584+
// Code completion second pass.
1585+
1586+
static void
1587+
performCodeCompletionSecondPass(PersistentParserState &ParserState,
1588+
CodeCompletionCallbacksFactory &Factory);
1589+
1590+
void performCodeCompletionSecondPassImpl(
1591+
PersistentParserState::CodeCompletionDelayedDeclState &info);
15861592
};
15871593

15881594
/// Describes a parsed declaration name.

Diff for: include/swift/Parse/PersistentParserState.h

+29-30
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#ifndef SWIFT_PARSE_PERSISTENTPARSERSTATE_H
1818
#define SWIFT_PARSE_PERSISTENTPARSERSTATE_H
1919

20-
#include "swift/AST/LazyResolver.h"
2120
#include "swift/Basic/SourceLoc.h"
2221
#include "swift/Parse/LocalContext.h"
2322
#include "swift/Parse/ParserPosition.h"
@@ -26,6 +25,10 @@
2625

2726
namespace swift {
2827

28+
class SourceFile;
29+
class DeclContext;
30+
class IterableDeclContext;
31+
2932
/// Parser state persistent across multiple parses.
3033
class PersistentParserState {
3134
public:
@@ -36,16 +39,16 @@ class PersistentParserState {
3639
bool isValid() const { return Loc.isValid(); }
3740
};
3841

39-
enum class DelayedDeclKind {
42+
enum class CodeCompletionDelayedDeclKind {
4043
TopLevelCodeDecl,
4144
Decl,
4245
FunctionBody,
4346
};
4447

45-
class DelayedDeclState {
48+
class CodeCompletionDelayedDeclState {
4649
friend class PersistentParserState;
4750
friend class Parser;
48-
DelayedDeclKind Kind;
51+
CodeCompletionDelayedDeclKind Kind;
4952
unsigned Flags;
5053
DeclContext *ParentContext;
5154
ParserPos BodyPos;
@@ -57,13 +60,13 @@ class PersistentParserState {
5760
}
5861

5962
public:
60-
DelayedDeclState(DelayedDeclKind Kind, unsigned Flags,
61-
DeclContext *ParentContext, SourceRange BodyRange,
62-
SourceLoc PreviousLoc, SavedScope &&Scope)
63-
: Kind(Kind), Flags(Flags), ParentContext(ParentContext),
64-
BodyPos{BodyRange.Start, PreviousLoc},
65-
BodyEnd(BodyRange.End), Scope(std::move(Scope))
66-
{}
63+
CodeCompletionDelayedDeclState(CodeCompletionDelayedDeclKind Kind,
64+
unsigned Flags, DeclContext *ParentContext,
65+
SourceRange BodyRange, SourceLoc PreviousLoc,
66+
SavedScope &&Scope)
67+
: Kind(Kind), Flags(Flags),
68+
ParentContext(ParentContext), BodyPos{BodyRange.Start, PreviousLoc},
69+
BodyEnd(BodyRange.End), Scope(std::move(Scope)) {}
6770
};
6871

6972
bool InPoundLineEnvironment = false;
@@ -76,7 +79,7 @@ class PersistentParserState {
7679
/// Parser sets this if it stopped parsing before the buffer ended.
7780
ParserPosition MarkedPos;
7881

79-
std::unique_ptr<DelayedDeclState> CodeCompletionDelayedDeclState;
82+
std::unique_ptr<CodeCompletionDelayedDeclState> CodeCompletionDelayedDeclStat;
8083

8184
std::vector<IterableDeclContext *> DelayedDeclLists;
8285

@@ -89,28 +92,24 @@ class PersistentParserState {
8992
PersistentParserState(ASTContext &ctx) : PersistentParserState() { }
9093
~PersistentParserState();
9194

92-
void delayDecl(DelayedDeclKind Kind, unsigned Flags,
93-
DeclContext *ParentContext,
94-
SourceRange BodyRange, SourceLoc PreviousLoc);
95-
96-
void delayDeclList(IterableDeclContext *D);
95+
void setCodeCompletionDelayedDeclState(CodeCompletionDelayedDeclKind Kind,
96+
unsigned Flags,
97+
DeclContext *ParentContext,
98+
SourceRange BodyRange,
99+
SourceLoc PreviousLoc);
97100

98-
bool hasDelayedDecl() {
99-
return CodeCompletionDelayedDeclState.get() != nullptr;
100-
}
101-
DelayedDeclKind getDelayedDeclKind() {
102-
return CodeCompletionDelayedDeclState->Kind;
103-
}
104-
SourceLoc getDelayedDeclLoc() {
105-
return CodeCompletionDelayedDeclState->BodyPos.Loc;
101+
bool hasCodeCompletionDelayedDeclState() {
102+
return CodeCompletionDelayedDeclStat.get() != nullptr;
106103
}
107-
DeclContext *getDelayedDeclContext() {
108-
return CodeCompletionDelayedDeclState->ParentContext;
109-
}
110-
std::unique_ptr<DelayedDeclState> takeDelayedDeclState() {
111-
return std::move(CodeCompletionDelayedDeclState);
104+
105+
std::unique_ptr<CodeCompletionDelayedDeclState>
106+
takeCodeCompletionDelayedDeclState() {
107+
assert(hasCodeCompletionDelayedDeclState());
108+
return std::move(CodeCompletionDelayedDeclStat);
112109
}
113110

111+
void delayDeclList(IterableDeclContext *D);
112+
114113
void parseAllDelayedDeclLists();
115114

116115
TopLevelContext &getTopLevelContext() {

Diff for: lib/Parse/ParseDecl.cpp

+7-62
Original file line numberDiff line numberDiff line change
@@ -3008,9 +3008,10 @@ void Parser::consumeDecl(ParserPosition BeginParserPosition,
30083008
backtrackToPosition(BeginParserPosition);
30093009
SourceLoc BeginLoc = Tok.getLoc();
30103010

3011-
State->delayDecl(PersistentParserState::DelayedDeclKind::Decl, Flags.toRaw(),
3012-
CurDeclContext, {BeginLoc, EndLoc},
3013-
BeginParserPosition.PreviousLoc);
3011+
State->setCodeCompletionDelayedDeclState(
3012+
PersistentParserState::CodeCompletionDelayedDeclKind::Decl,
3013+
Flags.toRaw(), CurDeclContext, {BeginLoc, EndLoc},
3014+
BeginParserPosition.PreviousLoc);
30143015

30153016
while (SourceMgr.isBeforeInBuffer(Tok.getLoc(), CurrentLoc))
30163017
consumeToken();
@@ -3575,48 +3576,6 @@ std::vector<Decl *> Parser::parseDeclListDelayed(IterableDeclContext *IDC) {
35753576
return parseDeclList(LBLoc, RBLoc, Id, Options, IDC, hadError);
35763577
}
35773578

3578-
void Parser::parseDeclDelayed() {
3579-
auto DelayedState = State->takeDelayedDeclState();
3580-
assert(DelayedState.get() && "should have delayed state");
3581-
3582-
auto BeginParserPosition = getParserPosition(DelayedState->BodyPos);
3583-
auto EndLexerState = L->getStateForEndOfTokenLoc(DelayedState->BodyEnd);
3584-
3585-
// ParserPositionRAII needs a primed parser to restore to.
3586-
if (Tok.is(tok::NUM_TOKENS))
3587-
consumeTokenWithoutFeedingReceiver();
3588-
3589-
// Ensure that we restore the parser state at exit.
3590-
ParserPositionRAII PPR(*this);
3591-
3592-
// Create a lexer that cannot go past the end state.
3593-
Lexer LocalLex(*L, BeginParserPosition.LS, EndLexerState);
3594-
3595-
// Temporarily swap out the parser's current lexer with our new one.
3596-
llvm::SaveAndRestore<Lexer *> T(L, &LocalLex);
3597-
3598-
// Rewind to the beginning of the decl.
3599-
restoreParserPosition(BeginParserPosition);
3600-
3601-
// Re-enter the lexical scope.
3602-
Scope S(this, DelayedState->takeScope());
3603-
ContextChange CC(*this, DelayedState->ParentContext);
3604-
3605-
parseDecl(ParseDeclOptions(DelayedState->Flags),
3606-
/*IsAtStartOfLineOrPreviousHadSemi=*/true,
3607-
[&](Decl *D) {
3608-
if (auto *parent = DelayedState->ParentContext) {
3609-
if (auto *NTD = dyn_cast<NominalTypeDecl>(parent)) {
3610-
NTD->addMember(D);
3611-
} else if (auto *ED = dyn_cast<ExtensionDecl>(parent)) {
3612-
ED->addMember(D);
3613-
} else if (auto *SF = dyn_cast<SourceFile>(parent)) {
3614-
SF->Decls.push_back(D);
3615-
}
3616-
}
3617-
});
3618-
}
3619-
36203579
/// Parse an 'import' declaration, doing no token skipping on error.
36213580
///
36223581
/// \verbatim
@@ -5640,9 +5599,9 @@ void Parser::consumeAbstractFunctionBody(AbstractFunctionDecl *AFD,
56405599

56415600
if (isCodeCompletionFirstPass()) {
56425601
if (SourceMgr.rangeContainsCodeCompletionLoc(BodyRange)) {
5643-
State->delayDecl(PersistentParserState::DelayedDeclKind::FunctionBody,
5644-
PD_Default, AFD, BodyRange,
5645-
BeginParserPosition.PreviousLoc);
5602+
State->setCodeCompletionDelayedDeclState(
5603+
PersistentParserState::CodeCompletionDelayedDeclKind::FunctionBody,
5604+
PD_Default, AFD, BodyRange, BeginParserPosition.PreviousLoc);
56465605
} else {
56475606
AFD->setBodySkipped(BodyRange);
56485607
}
@@ -5957,20 +5916,6 @@ BraceStmt *Parser::parseAbstractFunctionBodyDelayed(AbstractFunctionDecl *AFD) {
59575916
return parseBraceItemList(diag::func_decl_without_brace).getPtrOrNull();
59585917
}
59595918

5960-
/// Parse a delayed function body from the 'PersistentParserState'.
5961-
void Parser::parseAbstractFunctionBodyDelayed() {
5962-
auto DelayedState = State->takeDelayedDeclState();
5963-
assert(DelayedState.get() && "should have delayed state");
5964-
auto CD = DelayedState->ParentContext->getAsDecl();
5965-
auto AFD = cast<AbstractFunctionDecl>(CD);
5966-
5967-
// Eagarly parse local decls or nested function bodies inside the body.
5968-
llvm::SaveAndRestore<bool> DisableDelayedBody(DelayBodyParsing, false);
5969-
5970-
auto body = parseAbstractFunctionBodyDelayed(AFD);
5971-
AFD->setBodyParsed(body);
5972-
}
5973-
59745919
/// Parse a 'enum' declaration, returning true (and doing no token
59755920
/// skipping) on error.
59765921
///

Diff for: lib/Parse/ParseStmt.cpp

+3-50
Original file line numberDiff line numberDiff line change
@@ -256,9 +256,9 @@ void Parser::consumeTopLevelDecl(ParserPosition BeginParserPosition,
256256
SourceLoc EndLoc = PreviousLoc;
257257
backtrackToPosition(BeginParserPosition);
258258
SourceLoc BeginLoc = Tok.getLoc();
259-
State->delayDecl(PersistentParserState::DelayedDeclKind::TopLevelCodeDecl,
260-
PD_Default, TLCD, {BeginLoc, EndLoc},
261-
BeginParserPosition.PreviousLoc);
259+
State->setCodeCompletionDelayedDeclState(
260+
PersistentParserState::CodeCompletionDelayedDeclKind::TopLevelCodeDecl,
261+
PD_Default, TLCD, {BeginLoc, EndLoc}, BeginParserPosition.PreviousLoc);
262262

263263
// Skip the rest of the file to prevent the parser from constructing the AST
264264
// for it. Forward references are not allowed at the top level.
@@ -520,53 +520,6 @@ ParserStatus Parser::parseBraceItems(SmallVectorImpl<ASTNode> &Entries,
520520
return BraceItemsStatus;
521521
}
522522

523-
void Parser::parseTopLevelCodeDeclDelayed() {
524-
auto DelayedState = State->takeDelayedDeclState();
525-
assert(DelayedState.get() && "should have delayed state");
526-
527-
auto BeginParserPosition = getParserPosition(DelayedState->BodyPos);
528-
auto EndLexerState = L->getStateForEndOfTokenLoc(DelayedState->BodyEnd);
529-
530-
// ParserPositionRAII needs a primed parser to restore to.
531-
if (Tok.is(tok::NUM_TOKENS))
532-
consumeTokenWithoutFeedingReceiver();
533-
534-
// Ensure that we restore the parser state at exit.
535-
ParserPositionRAII PPR(*this);
536-
537-
// Create a lexer that cannot go past the end state.
538-
Lexer LocalLex(*L, BeginParserPosition.LS, EndLexerState);
539-
540-
// Temporarily swap out the parser's current lexer with our new one.
541-
llvm::SaveAndRestore<Lexer *> T(L, &LocalLex);
542-
543-
// Rewind to the beginning of the top-level code.
544-
restoreParserPosition(BeginParserPosition);
545-
546-
// Re-enter the lexical scope.
547-
Scope S(this, DelayedState->takeScope());
548-
549-
// Re-enter the top-level decl context.
550-
// FIXME: this can issue discriminators out-of-order?
551-
auto *TLCD = cast<TopLevelCodeDecl>(DelayedState->ParentContext);
552-
ContextChange CC(*this, TLCD, &State->getTopLevelContext());
553-
554-
SourceLoc StartLoc = Tok.getLoc();
555-
ASTNode Result;
556-
557-
// Expressions can't begin with a closure literal at statement position. This
558-
// prevents potential ambiguities with trailing closure syntax.
559-
if (Tok.is(tok::l_brace)) {
560-
diagnose(Tok, diag::statement_begins_with_closure);
561-
}
562-
563-
parseExprOrStmt(Result);
564-
if (!Result.isNull()) {
565-
auto Brace = BraceStmt::create(Context, StartLoc, Result, Tok.getLoc());
566-
TLCD->setBody(Brace);
567-
}
568-
}
569-
570523
/// Recover from a 'case' or 'default' outside of a 'switch' by consuming up to
571524
/// the next ':'.
572525
static ParserResult<Stmt> recoverFromInvalidCase(Parser &P) {

0 commit comments

Comments
 (0)