Skip to content

Commit a9870ac

Browse files
authored
Merge pull request swiftlang#29741 from hamishknight/moving-states
Move PersistentParserState onto SourceFile
2 parents b5cb81b + d77cae6 commit a9870ac

File tree

18 files changed

+170
-111
lines changed

18 files changed

+170
-111
lines changed

include/swift/AST/SourceFile.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
namespace swift {
2020

21+
class PersistentParserState;
22+
2123
/// A file containing Swift source code.
2224
///
2325
/// This is a .swift or .sil file (or a virtual file, such as the contents of
@@ -154,6 +156,16 @@ class SourceFile final : public FileUnit {
154156
/// mechanism which is not SourceFile-dependent.)
155157
SeparatelyImportedOverlayMap separatelyImportedOverlays;
156158

159+
/// A pointer to PersistentParserState with a function reference to its
160+
/// deleter to handle the fact that it's forward declared.
161+
using ParserStatePtr =
162+
std::unique_ptr<PersistentParserState, void (*)(PersistentParserState *)>;
163+
164+
/// Stores delayed parser state that code completion needs to be able to
165+
/// resume parsing at the code completion token in the file.
166+
ParserStatePtr DelayedParserState =
167+
ParserStatePtr(/*ptr*/ nullptr, /*deleter*/ nullptr);
168+
157169
friend ASTContext;
158170
friend Impl;
159171

@@ -405,6 +417,20 @@ class SourceFile final : public FileUnit {
405417
/// Retrieve the scope that describes this source file.
406418
ASTScope &getScope();
407419

420+
/// Retrieves the previously set delayed parser state, asserting that it
421+
/// exists.
422+
PersistentParserState *getDelayedParserState() {
423+
auto *state = DelayedParserState.get();
424+
assert(state && "Didn't set any delayed parser state!");
425+
return state;
426+
}
427+
428+
/// Record delayed parser state for the source file. This is needed for code
429+
/// completion's second pass.
430+
void setDelayedParserState(ParserStatePtr &&state) {
431+
DelayedParserState = std::move(state);
432+
}
433+
408434
SWIFT_DEBUG_DUMP;
409435
void dump(raw_ostream &os) const;
410436

include/swift/Frontend/Frontend.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -400,8 +400,6 @@ class CompilerInstance {
400400
std::unique_ptr<Lowering::TypeConverter> TheSILTypes;
401401
std::unique_ptr<SILModule> TheSILModule;
402402

403-
std::unique_ptr<PersistentParserState> PersistentState;
404-
405403
/// Null if no tracker.
406404
std::unique_ptr<DependencyTracker> DepTracker;
407405
/// If there is no stats output directory by the time the
@@ -431,6 +429,9 @@ class CompilerInstance {
431429
/// buffer will also have its buffer ID in PrimaryBufferIDs.
432430
std::vector<SourceFile *> PrimarySourceFiles;
433431

432+
/// The file that has been registered for code completion.
433+
NullablePtr<SourceFile> CodeCompletionFile;
434+
434435
/// Return whether there is an entry in PrimaryInputs for buffer \p BufID.
435436
bool isPrimaryInput(unsigned BufID) const {
436437
return PrimaryBufferIDs.count(BufID) != 0;
@@ -550,12 +551,13 @@ class CompilerInstance {
550551
return Invocation;
551552
}
552553

553-
bool hasPersistentParserState() const {
554-
return bool(PersistentState);
555-
}
554+
/// If a code completion buffer has been set, returns the corresponding source
555+
/// file.
556+
NullablePtr<SourceFile> getCodeCompletionFile() { return CodeCompletionFile; }
556557

557-
PersistentParserState &getPersistentParserState() {
558-
return *PersistentState.get();
558+
/// Set a new file that we're performing code completion on.
559+
void setCodeCompletionFile(SourceFile *file) {
560+
CodeCompletionFile = file;
559561
}
560562

561563
private:

include/swift/Parse/Parser.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,13 @@ class Parser {
223223
/// lazily parsed and type checked.
224224
bool DelayBodyParsing;
225225

226+
/// Whether to evaluate the conditions of #if decls, meaning that the bodies
227+
/// of any active clauses are hoisted such that they become sibling nodes with
228+
/// the #if decl.
229+
// FIXME: When condition evaluation moves to a later phase, remove this bit
230+
// and adjust the client call 'performParseOnly'.
231+
bool EvaluateConditionals;
232+
226233
/// The receiver to collect all consumed tokens.
227234
ConsumeTokenReceiver *TokReceiver;
228235

@@ -401,16 +408,16 @@ class Parser {
401408
SILParserTUStateBase *SIL,
402409
PersistentParserState *PersistentState,
403410
std::shared_ptr<SyntaxParseActions> SPActions = nullptr,
404-
bool DelayBodyParsing = true);
411+
bool DelayBodyParsing = true, bool EvaluateConditionals = true);
405412
Parser(unsigned BufferID, SourceFile &SF, SILParserTUStateBase *SIL,
406413
PersistentParserState *PersistentState = nullptr,
407414
std::shared_ptr<SyntaxParseActions> SPActions = nullptr,
408-
bool DelayBodyParsing = true);
415+
bool DelayBodyParsing = true, bool EvaluateConditionals = true);
409416
Parser(std::unique_ptr<Lexer> Lex, SourceFile &SF,
410417
SILParserTUStateBase *SIL = nullptr,
411418
PersistentParserState *PersistentState = nullptr,
412419
std::shared_ptr<SyntaxParseActions> SPActions = nullptr,
413-
bool DelayBodyParsing = true);
420+
bool DelayBodyParsing = true, bool EvaluateConditionals = true);
414421
~Parser();
415422

416423
/// Returns true if the buffer being parsed is allowed to contain SIL.

include/swift/Parse/PersistentParserState.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
#include "swift/Basic/SourceLoc.h"
2121
#include "swift/Parse/LocalContext.h"
22-
#include "swift/Parse/ParserPosition.h"
2322
#include "swift/Parse/Scope.h"
2423
#include "llvm/ADT/DenseMap.h"
2524

@@ -58,11 +57,6 @@ class CodeCompletionDelayedDeclState {
5857

5958
/// Parser state persistent across multiple parses.
6059
class PersistentParserState {
61-
public:
62-
// FIXME: When condition evaluation moves to a later phase, remove this bit
63-
// and adjust the client call 'performParseOnly'.
64-
bool PerformConditionEvaluation = true;
65-
private:
6660
swift::ScopeInfo ScopeInfo;
6761

6862
std::unique_ptr<CodeCompletionDelayedDeclState> CodeCompletionDelayedDeclStat;
@@ -85,13 +79,17 @@ class PersistentParserState {
8579
void restoreCodeCompletionDelayedDeclState(
8680
const CodeCompletionDelayedDeclState &other);
8781

88-
bool hasCodeCompletionDelayedDeclState() {
82+
bool hasCodeCompletionDelayedDeclState() const {
8983
return CodeCompletionDelayedDeclStat.get() != nullptr;
9084
}
9185

9286
CodeCompletionDelayedDeclState &getCodeCompletionDelayedDeclState() {
9387
return *CodeCompletionDelayedDeclStat.get();
9488
}
89+
const CodeCompletionDelayedDeclState &
90+
getCodeCompletionDelayedDeclState() const {
91+
return *CodeCompletionDelayedDeclStat.get();
92+
}
9593

9694
std::unique_ptr<CodeCompletionDelayedDeclState>
9795
takeCodeCompletionDelayedDeclState() {

include/swift/Subsystems.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ namespace swift {
5555
class ModuleDecl;
5656
typedef void *OpaqueSyntaxNode;
5757
class Parser;
58-
class PersistentParserState;
5958
class SerializationOptions;
6059
class SILOptions;
6160
class SILModule;
@@ -110,20 +109,17 @@ namespace swift {
110109
///
111110
/// \param BufferID The buffer to parse from.
112111
///
113-
/// \param PersistentState If non-null the same PersistentState object can be
114-
/// used to save parser state for code completion.
115-
///
116112
/// \param DelayBodyParsing Whether parsing of type and function bodies can be
117113
/// delayed.
118114
void parseIntoSourceFile(SourceFile &SF, unsigned BufferID,
119-
PersistentParserState *PersistentState = nullptr,
120-
bool DelayBodyParsing = true);
115+
bool DelayBodyParsing = true,
116+
bool EvaluateConditionals = true);
121117

122118
/// Parse a source file's SIL declarations into a given SIL module.
123119
void parseSourceFileSIL(SourceFile &SF, SILParserState *sil);
124120

125121
/// Finish the code completion.
126-
void performCodeCompletionSecondPass(PersistentParserState &PersistentState,
122+
void performCodeCompletionSecondPass(SourceFile &SF,
127123
CodeCompletionCallbacksFactory &Factory);
128124

129125
/// Lex and return a vector of tokens for the given buffer.

lib/Frontend/Frontend.cpp

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -906,8 +906,6 @@ void CompilerInstance::parseAndCheckTypesUpTo(
906906
const ImplicitImports &implicitImports, SourceFile::ASTStage_t limitStage) {
907907
FrontendStatsTracer tracer(getStatsReporter(), "parse-and-check-types");
908908

909-
PersistentState = std::make_unique<PersistentParserState>();
910-
911909
bool hadLoadError = parsePartialModulesAndLibraryFiles(implicitImports);
912910
if (Invocation.isCodeCompletion()) {
913911
// When we are doing code completion, make sure to emit at least one
@@ -978,8 +976,7 @@ void CompilerInstance::parseLibraryFile(
978976
auto DidSuppressWarnings = Diags.getSuppressWarnings();
979977
Diags.setSuppressWarnings(DidSuppressWarnings || !IsPrimary);
980978

981-
parseIntoSourceFile(*NextInput, BufferID, PersistentState.get(),
982-
/*DelayedBodyParsing=*/!IsPrimary);
979+
parseIntoSourceFile(*NextInput, BufferID, /*DelayedBodyParsing=*/!IsPrimary);
983980

984981
Diags.setSuppressWarnings(DidSuppressWarnings);
985982

@@ -1026,7 +1023,7 @@ void CompilerInstance::parseAndTypeCheckMainFileUpTo(
10261023
Diags.setSuppressWarnings(DidSuppressWarnings || !mainIsPrimary);
10271024

10281025
// Parse the Swift decls into the source file.
1029-
parseIntoSourceFile(MainFile, MainBufferID, PersistentState.get(),
1026+
parseIntoSourceFile(MainFile, MainBufferID,
10301027
/*delayBodyParsing*/ !mainIsPrimary);
10311028

10321029
// For a primary, also perform type checking if needed. Otherwise, just do
@@ -1096,6 +1093,11 @@ SourceFile *CompilerInstance::createSourceFileForMainModule(
10961093
recordPrimarySourceFile(inputFile);
10971094
}
10981095

1096+
if (bufferID == SourceMgr.getCodeCompletionBufferID()) {
1097+
assert(!CodeCompletionFile && "Multiple code completion files?");
1098+
CodeCompletionFile = inputFile;
1099+
}
1100+
10991101
return inputFile;
11001102
}
11011103

@@ -1121,9 +1123,6 @@ void CompilerInstance::performParseOnly(bool EvaluateConditionals,
11211123
MainBufferID);
11221124
}
11231125

1124-
PersistentState = std::make_unique<PersistentParserState>();
1125-
PersistentState->PerformConditionEvaluation = EvaluateConditionals;
1126-
11271126
auto shouldDelayBodies = [&](unsigned bufferID) -> bool {
11281127
if (!CanDelayBodies)
11291128
return false;
@@ -1141,8 +1140,8 @@ void CompilerInstance::performParseOnly(bool EvaluateConditionals,
11411140
SourceFileKind::Library, SourceFile::ImplicitModuleImportKind::None,
11421141
BufferID);
11431142

1144-
parseIntoSourceFile(*NextInput, BufferID, PersistentState.get(),
1145-
shouldDelayBodies(BufferID));
1143+
parseIntoSourceFile(*NextInput, BufferID, shouldDelayBodies(BufferID),
1144+
EvaluateConditionals);
11461145
}
11471146

11481147
// Now parse the main file.
@@ -1152,16 +1151,15 @@ void CompilerInstance::performParseOnly(bool EvaluateConditionals,
11521151
MainFile.SyntaxParsingCache = Invocation.getMainFileSyntaxParsingCache();
11531152
assert(MainBufferID == MainFile.getBufferID());
11541153

1155-
parseIntoSourceFile(MainFile, MainBufferID, PersistentState.get(),
1156-
shouldDelayBodies(MainBufferID));
1154+
parseIntoSourceFile(MainFile, MainBufferID, shouldDelayBodies(MainBufferID),
1155+
EvaluateConditionals);
11571156
}
11581157

11591158
assert(Context->LoadedModules.size() == 1 &&
11601159
"Loaded a module during parse-only");
11611160
}
11621161

11631162
void CompilerInstance::freeASTContext() {
1164-
PersistentState.reset();
11651163
TheSILTypes.reset();
11661164
Context.reset();
11671165
MainModule = nullptr;

0 commit comments

Comments
 (0)