Skip to content

Commit 63c1f84

Browse files
authored
Merge pull request #28182 from rintaro/ide-completion-rdar56926367
[Parse/CodeCompletion] Cleanup code completion facilities in Parse
2 parents 316b045 + cd8ebe4 commit 63c1f84

File tree

6 files changed

+156
-230
lines changed

6 files changed

+156
-230
lines changed

include/swift/Parse/Parser.h

Lines changed: 11 additions & 7 deletions
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

@@ -895,8 +894,6 @@ class Parser {
895894
/// Options that control the parsing of declarations.
896895
using ParseDeclOptions = OptionSet<ParseDeclFlags>;
897896

898-
void delayParseFromBeginningToHere(ParserPosition BeginParserPosition,
899-
ParseDeclOptions Flags);
900897
void consumeDecl(ParserPosition BeginParserPosition, ParseDeclOptions Flags,
901898
bool IsTopLevel);
902899

@@ -921,8 +918,6 @@ class Parser {
921918
bool IsAtStartOfLineOrPreviousHadSemi,
922919
llvm::function_ref<void(Decl*)> Handler);
923920

924-
void parseDeclDelayed();
925-
926921
std::vector<Decl *> parseDeclListDelayed(IterableDeclContext *IDC);
927922

928923
bool parseMemberDeclList(SourceLoc LBLoc, SourceLoc &RBLoc,
@@ -1091,7 +1086,6 @@ class Parser {
10911086
bool HasFuncKeyword = true);
10921087
void parseAbstractFunctionBody(AbstractFunctionDecl *AFD);
10931088
BraceStmt *parseAbstractFunctionBodyDelayed(AbstractFunctionDecl *AFD);
1094-
void parseAbstractFunctionBodyDelayed();
10951089
ParserResult<ProtocolDecl> parseDeclProtocol(ParseDeclOptions Flags,
10961090
DeclAttributes &Attributes);
10971091

@@ -1585,6 +1579,16 @@ class Parser {
15851579
parsePlatformVersionConstraintSpec();
15861580
ParserResult<PlatformAgnosticVersionConstraintAvailabilitySpec>
15871581
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);
15881592
};
15891593

15901594
/// Describes a parsed declaration name.

include/swift/Parse/PersistentParserState.h

Lines changed: 29 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,17 @@
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"
2423
#include "swift/Parse/Scope.h"
2524
#include "llvm/ADT/DenseMap.h"
2625

2726
namespace swift {
28-
class AbstractFunctionDecl;
27+
28+
class SourceFile;
29+
class DeclContext;
30+
class IterableDeclContext;
2931

3032
/// Parser state persistent across multiple parses.
3133
class PersistentParserState {
@@ -37,32 +39,16 @@ class PersistentParserState {
3739
bool isValid() const { return Loc.isValid(); }
3840
};
3941

40-
class FunctionBodyState {
41-
ParserPos BodyPos;
42-
SavedScope Scope;
43-
friend class Parser;
44-
45-
SavedScope takeScope() {
46-
return std::move(Scope);
47-
}
48-
49-
public:
50-
FunctionBodyState(SourceRange BodyRange, SourceLoc PreviousLoc,
51-
SavedScope &&Scope)
52-
: BodyPos{BodyRange.Start, PreviousLoc}, Scope(std::move(Scope))
53-
{}
54-
};
55-
56-
enum class DelayedDeclKind {
42+
enum class CodeCompletionDelayedDeclKind {
5743
TopLevelCodeDecl,
5844
Decl,
5945
FunctionBody,
6046
};
6147

62-
class DelayedDeclState {
48+
class CodeCompletionDelayedDeclState {
6349
friend class PersistentParserState;
6450
friend class Parser;
65-
DelayedDeclKind Kind;
51+
CodeCompletionDelayedDeclKind Kind;
6652
unsigned Flags;
6753
DeclContext *ParentContext;
6854
ParserPos BodyPos;
@@ -74,13 +60,13 @@ class PersistentParserState {
7460
}
7561

7662
public:
77-
DelayedDeclState(DelayedDeclKind Kind, unsigned Flags,
78-
DeclContext *ParentContext, SourceRange BodyRange,
79-
SourceLoc PreviousLoc, SavedScope &&Scope)
80-
: Kind(Kind), Flags(Flags), ParentContext(ParentContext),
81-
BodyPos{BodyRange.Start, PreviousLoc},
82-
BodyEnd(BodyRange.End), Scope(std::move(Scope))
83-
{}
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)) {}
8470
};
8571

8672
bool InPoundLineEnvironment = false;
@@ -89,15 +75,11 @@ class PersistentParserState {
8975
bool PerformConditionEvaluation = true;
9076
private:
9177
ScopeInfo ScopeInfo;
92-
using DelayedFunctionBodiesTy =
93-
llvm::DenseMap<AbstractFunctionDecl *,
94-
std::unique_ptr<FunctionBodyState>>;
95-
DelayedFunctionBodiesTy DelayedFunctionBodies;
9678

9779
/// Parser sets this if it stopped parsing before the buffer ended.
9880
ParserPosition MarkedPos;
9981

100-
std::unique_ptr<DelayedDeclState> CodeCompletionDelayedDeclState;
82+
std::unique_ptr<CodeCompletionDelayedDeclState> CodeCompletionDelayedDeclStat;
10183

10284
std::vector<IterableDeclContext *> DelayedDeclLists;
10385

@@ -110,31 +92,24 @@ class PersistentParserState {
11092
PersistentParserState(ASTContext &ctx) : PersistentParserState() { }
11193
~PersistentParserState();
11294

113-
void delayDecl(DelayedDeclKind Kind, unsigned Flags,
114-
DeclContext *ParentContext,
115-
SourceRange BodyRange, SourceLoc PreviousLoc);
116-
117-
void delayDeclList(IterableDeclContext *D);
95+
void setCodeCompletionDelayedDeclState(CodeCompletionDelayedDeclKind Kind,
96+
unsigned Flags,
97+
DeclContext *ParentContext,
98+
SourceRange BodyRange,
99+
SourceLoc PreviousLoc);
118100

119-
void delayTopLevel(TopLevelCodeDecl *TLCD, SourceRange BodyRange,
120-
SourceLoc PreviousLoc);
121-
122-
bool hasDelayedDecl() {
123-
return CodeCompletionDelayedDeclState.get() != nullptr;
124-
}
125-
DelayedDeclKind getDelayedDeclKind() {
126-
return CodeCompletionDelayedDeclState->Kind;
101+
bool hasCodeCompletionDelayedDeclState() {
102+
return CodeCompletionDelayedDeclStat.get() != nullptr;
127103
}
128-
SourceLoc getDelayedDeclLoc() {
129-
return CodeCompletionDelayedDeclState->BodyPos.Loc;
130-
}
131-
DeclContext *getDelayedDeclContext() {
132-
return CodeCompletionDelayedDeclState->ParentContext;
133-
}
134-
std::unique_ptr<DelayedDeclState> takeDelayedDeclState() {
135-
return std::move(CodeCompletionDelayedDeclState);
104+
105+
std::unique_ptr<CodeCompletionDelayedDeclState>
106+
takeCodeCompletionDelayedDeclState() {
107+
assert(hasCodeCompletionDelayedDeclState());
108+
return std::move(CodeCompletionDelayedDeclStat);
136109
}
137110

111+
void delayDeclList(IterableDeclContext *D);
112+
138113
void parseAllDelayedDeclLists();
139114

140115
TopLevelContext &getTopLevelContext() {

lib/Parse/ParseDecl.cpp

Lines changed: 19 additions & 92 deletions
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();
@@ -3045,21 +3046,6 @@ void Parser::setLocalDiscriminatorToParamList(ParameterList *PL) {
30453046
}
30463047
}
30473048

3048-
void Parser::delayParseFromBeginningToHere(ParserPosition BeginParserPosition,
3049-
ParseDeclOptions Flags) {
3050-
auto CurLoc = Tok.getLoc();
3051-
backtrackToPosition(BeginParserPosition);
3052-
SourceLoc BeginLoc = Tok.getLoc();
3053-
SourceLoc EndLoc = CurLoc;
3054-
State->delayDecl(PersistentParserState::DelayedDeclKind::Decl,
3055-
Flags.toRaw(),
3056-
CurDeclContext, {BeginLoc, EndLoc},
3057-
BeginParserPosition.PreviousLoc);
3058-
3059-
while (Tok.isNot(tok::eof))
3060-
consumeToken();
3061-
}
3062-
30633049
/// Parse a single syntactic declaration and return a list of decl
30643050
/// ASTs. This can return multiple results for var decls that bind to multiple
30653051
/// values, structs that define a struct decl and a constructor, etc.
@@ -3429,26 +3415,23 @@ Parser::parseDecl(ParseDeclOptions Flags,
34293415
consumeToken(tok::code_complete);
34303416
}
34313417

3432-
if (AttrStatus.hasCodeCompletion()) {
3433-
if (CodeCompletion) {
3418+
if (AttrStatus.hasCodeCompletion() || DeclResult.hasCodeCompletion()) {
3419+
if (isCodeCompletionFirstPass() &&
3420+
!CurDeclContext->isModuleScopeContext() &&
3421+
!isa<TopLevelCodeDecl>(CurDeclContext) &&
3422+
!isa<AbstractClosureExpr>(CurDeclContext)) {
3423+
// Only consume non-toplevel decls.
3424+
consumeDecl(BeginParserPosition, Flags, /*IsTopLevel=*/false);
3425+
3426+
return makeParserError();
3427+
}
3428+
if (AttrStatus.hasCodeCompletion() && CodeCompletion) {
34343429
Optional<DeclKind> DK;
34353430
if (DeclResult.isNonNull())
34363431
DK = DeclResult.get()->getKind();
34373432
CodeCompletion->setAttrTargetDeclKind(DK);
3438-
} else {
3439-
delayParseFromBeginningToHere(BeginParserPosition, Flags);
3440-
return makeParserError();
34413433
}
3442-
}
3443-
3444-
if (DeclResult.hasCodeCompletion() && isCodeCompletionFirstPass() &&
3445-
!CurDeclContext->isModuleScopeContext() &&
3446-
!isa<TopLevelCodeDecl>(CurDeclContext) &&
3447-
!isa<AbstractClosureExpr>(CurDeclContext)) {
3448-
// Only consume non-toplevel decls.
3449-
consumeDecl(BeginParserPosition, Flags, /*IsTopLevel=*/false);
3450-
3451-
return makeParserError();
3434+
DeclResult.setHasCodeCompletion();
34523435
}
34533436

34543437
if (auto SF = CurDeclContext->getParentSourceFile()) {
@@ -3593,48 +3576,6 @@ std::vector<Decl *> Parser::parseDeclListDelayed(IterableDeclContext *IDC) {
35933576
return parseDeclList(LBLoc, RBLoc, Id, Options, IDC, hadError);
35943577
}
35953578

3596-
void Parser::parseDeclDelayed() {
3597-
auto DelayedState = State->takeDelayedDeclState();
3598-
assert(DelayedState.get() && "should have delayed state");
3599-
3600-
auto BeginParserPosition = getParserPosition(DelayedState->BodyPos);
3601-
auto EndLexerState = L->getStateForEndOfTokenLoc(DelayedState->BodyEnd);
3602-
3603-
// ParserPositionRAII needs a primed parser to restore to.
3604-
if (Tok.is(tok::NUM_TOKENS))
3605-
consumeTokenWithoutFeedingReceiver();
3606-
3607-
// Ensure that we restore the parser state at exit.
3608-
ParserPositionRAII PPR(*this);
3609-
3610-
// Create a lexer that cannot go past the end state.
3611-
Lexer LocalLex(*L, BeginParserPosition.LS, EndLexerState);
3612-
3613-
// Temporarily swap out the parser's current lexer with our new one.
3614-
llvm::SaveAndRestore<Lexer *> T(L, &LocalLex);
3615-
3616-
// Rewind to the beginning of the decl.
3617-
restoreParserPosition(BeginParserPosition);
3618-
3619-
// Re-enter the lexical scope.
3620-
Scope S(this, DelayedState->takeScope());
3621-
ContextChange CC(*this, DelayedState->ParentContext);
3622-
3623-
parseDecl(ParseDeclOptions(DelayedState->Flags),
3624-
/*IsAtStartOfLineOrPreviousHadSemi=*/true,
3625-
[&](Decl *D) {
3626-
if (auto *parent = DelayedState->ParentContext) {
3627-
if (auto *NTD = dyn_cast<NominalTypeDecl>(parent)) {
3628-
NTD->addMember(D);
3629-
} else if (auto *ED = dyn_cast<ExtensionDecl>(parent)) {
3630-
ED->addMember(D);
3631-
} else if (auto *SF = dyn_cast<SourceFile>(parent)) {
3632-
SF->Decls.push_back(D);
3633-
}
3634-
}
3635-
});
3636-
}
3637-
36383579
/// Parse an 'import' declaration, doing no token skipping on error.
36393580
///
36403581
/// \verbatim
@@ -5658,9 +5599,9 @@ void Parser::consumeAbstractFunctionBody(AbstractFunctionDecl *AFD,
56585599

56595600
if (isCodeCompletionFirstPass()) {
56605601
if (SourceMgr.rangeContainsCodeCompletionLoc(BodyRange)) {
5661-
State->delayDecl(PersistentParserState::DelayedDeclKind::FunctionBody,
5662-
PD_Default, AFD, BodyRange,
5663-
BeginParserPosition.PreviousLoc);
5602+
State->setCodeCompletionDelayedDeclState(
5603+
PersistentParserState::CodeCompletionDelayedDeclKind::FunctionBody,
5604+
PD_Default, AFD, BodyRange, BeginParserPosition.PreviousLoc);
56645605
} else {
56655606
AFD->setBodySkipped(BodyRange);
56665607
}
@@ -5975,20 +5916,6 @@ BraceStmt *Parser::parseAbstractFunctionBodyDelayed(AbstractFunctionDecl *AFD) {
59755916
return parseBraceItemList(diag::func_decl_without_brace).getPtrOrNull();
59765917
}
59775918

5978-
/// Parse a delayed function body from the 'PersistentParserState'.
5979-
void Parser::parseAbstractFunctionBodyDelayed() {
5980-
auto DelayedState = State->takeDelayedDeclState();
5981-
assert(DelayedState.get() && "should have delayed state");
5982-
auto CD = DelayedState->ParentContext->getAsDecl();
5983-
auto AFD = cast<AbstractFunctionDecl>(CD);
5984-
5985-
// Eagarly parse local decls or nested function bodies inside the body.
5986-
llvm::SaveAndRestore<bool> DisableDelayedBody(DelayBodyParsing, false);
5987-
5988-
auto body = parseAbstractFunctionBodyDelayed(AFD);
5989-
AFD->setBodyParsed(body);
5990-
}
5991-
59925919
/// Parse a 'enum' declaration, returning true (and doing no token
59935920
/// skipping) on error.
59945921
///

0 commit comments

Comments
 (0)