Merge pull request #29741 from hamishknight/moving-states

Move PersistentParserState onto SourceFile
This commit is contained in:
Hamish Knight
2020-03-02 14:11:06 -08:00
committed by GitHub
18 changed files with 170 additions and 111 deletions

View File

@@ -18,6 +18,8 @@
namespace swift {
class PersistentParserState;
/// A file containing Swift source code.
///
/// This is a .swift or .sil file (or a virtual file, such as the contents of
@@ -154,6 +156,16 @@ private:
/// mechanism which is not SourceFile-dependent.)
SeparatelyImportedOverlayMap separatelyImportedOverlays;
/// A pointer to PersistentParserState with a function reference to its
/// deleter to handle the fact that it's forward declared.
using ParserStatePtr =
std::unique_ptr<PersistentParserState, void (*)(PersistentParserState *)>;
/// Stores delayed parser state that code completion needs to be able to
/// resume parsing at the code completion token in the file.
ParserStatePtr DelayedParserState =
ParserStatePtr(/*ptr*/ nullptr, /*deleter*/ nullptr);
friend ASTContext;
friend Impl;
@@ -405,6 +417,20 @@ public:
/// Retrieve the scope that describes this source file.
ASTScope &getScope();
/// Retrieves the previously set delayed parser state, asserting that it
/// exists.
PersistentParserState *getDelayedParserState() {
auto *state = DelayedParserState.get();
assert(state && "Didn't set any delayed parser state!");
return state;
}
/// Record delayed parser state for the source file. This is needed for code
/// completion's second pass.
void setDelayedParserState(ParserStatePtr &&state) {
DelayedParserState = std::move(state);
}
SWIFT_DEBUG_DUMP;
void dump(raw_ostream &os) const;

View File

@@ -400,8 +400,6 @@ class CompilerInstance {
std::unique_ptr<Lowering::TypeConverter> TheSILTypes;
std::unique_ptr<SILModule> TheSILModule;
std::unique_ptr<PersistentParserState> PersistentState;
/// Null if no tracker.
std::unique_ptr<DependencyTracker> DepTracker;
/// If there is no stats output directory by the time the
@@ -431,6 +429,9 @@ class CompilerInstance {
/// buffer will also have its buffer ID in PrimaryBufferIDs.
std::vector<SourceFile *> PrimarySourceFiles;
/// The file that has been registered for code completion.
NullablePtr<SourceFile> CodeCompletionFile;
/// Return whether there is an entry in PrimaryInputs for buffer \p BufID.
bool isPrimaryInput(unsigned BufID) const {
return PrimaryBufferIDs.count(BufID) != 0;
@@ -550,12 +551,13 @@ public:
return Invocation;
}
bool hasPersistentParserState() const {
return bool(PersistentState);
}
/// If a code completion buffer has been set, returns the corresponding source
/// file.
NullablePtr<SourceFile> getCodeCompletionFile() { return CodeCompletionFile; }
PersistentParserState &getPersistentParserState() {
return *PersistentState.get();
/// Set a new file that we're performing code completion on.
void setCodeCompletionFile(SourceFile *file) {
CodeCompletionFile = file;
}
private:

View File

@@ -223,6 +223,13 @@ public:
/// lazily parsed and type checked.
bool DelayBodyParsing;
/// Whether to evaluate the conditions of #if decls, meaning that the bodies
/// of any active clauses are hoisted such that they become sibling nodes with
/// the #if decl.
// FIXME: When condition evaluation moves to a later phase, remove this bit
// and adjust the client call 'performParseOnly'.
bool EvaluateConditionals;
/// The receiver to collect all consumed tokens.
ConsumeTokenReceiver *TokReceiver;
@@ -401,16 +408,16 @@ public:
SILParserTUStateBase *SIL,
PersistentParserState *PersistentState,
std::shared_ptr<SyntaxParseActions> SPActions = nullptr,
bool DelayBodyParsing = true);
bool DelayBodyParsing = true, bool EvaluateConditionals = true);
Parser(unsigned BufferID, SourceFile &SF, SILParserTUStateBase *SIL,
PersistentParserState *PersistentState = nullptr,
std::shared_ptr<SyntaxParseActions> SPActions = nullptr,
bool DelayBodyParsing = true);
bool DelayBodyParsing = true, bool EvaluateConditionals = true);
Parser(std::unique_ptr<Lexer> Lex, SourceFile &SF,
SILParserTUStateBase *SIL = nullptr,
PersistentParserState *PersistentState = nullptr,
std::shared_ptr<SyntaxParseActions> SPActions = nullptr,
bool DelayBodyParsing = true);
bool DelayBodyParsing = true, bool EvaluateConditionals = true);
~Parser();
/// Returns true if the buffer being parsed is allowed to contain SIL.

View File

@@ -19,7 +19,6 @@
#include "swift/Basic/SourceLoc.h"
#include "swift/Parse/LocalContext.h"
#include "swift/Parse/ParserPosition.h"
#include "swift/Parse/Scope.h"
#include "llvm/ADT/DenseMap.h"
@@ -58,11 +57,6 @@ public:
/// Parser state persistent across multiple parses.
class PersistentParserState {
public:
// FIXME: When condition evaluation moves to a later phase, remove this bit
// and adjust the client call 'performParseOnly'.
bool PerformConditionEvaluation = true;
private:
swift::ScopeInfo ScopeInfo;
std::unique_ptr<CodeCompletionDelayedDeclState> CodeCompletionDelayedDeclStat;
@@ -85,13 +79,17 @@ public:
void restoreCodeCompletionDelayedDeclState(
const CodeCompletionDelayedDeclState &other);
bool hasCodeCompletionDelayedDeclState() {
bool hasCodeCompletionDelayedDeclState() const {
return CodeCompletionDelayedDeclStat.get() != nullptr;
}
CodeCompletionDelayedDeclState &getCodeCompletionDelayedDeclState() {
return *CodeCompletionDelayedDeclStat.get();
}
const CodeCompletionDelayedDeclState &
getCodeCompletionDelayedDeclState() const {
return *CodeCompletionDelayedDeclStat.get();
}
std::unique_ptr<CodeCompletionDelayedDeclState>
takeCodeCompletionDelayedDeclState() {

View File

@@ -55,7 +55,6 @@ namespace swift {
class ModuleDecl;
typedef void *OpaqueSyntaxNode;
class Parser;
class PersistentParserState;
class SerializationOptions;
class SILOptions;
class SILModule;
@@ -110,20 +109,17 @@ namespace swift {
///
/// \param BufferID The buffer to parse from.
///
/// \param PersistentState If non-null the same PersistentState object can be
/// used to save parser state for code completion.
///
/// \param DelayBodyParsing Whether parsing of type and function bodies can be
/// delayed.
void parseIntoSourceFile(SourceFile &SF, unsigned BufferID,
PersistentParserState *PersistentState = nullptr,
bool DelayBodyParsing = true);
bool DelayBodyParsing = true,
bool EvaluateConditionals = true);
/// Parse a source file's SIL declarations into a given SIL module.
void parseSourceFileSIL(SourceFile &SF, SILParserState *sil);
/// Finish the code completion.
void performCodeCompletionSecondPass(PersistentParserState &PersistentState,
void performCodeCompletionSecondPass(SourceFile &SF,
CodeCompletionCallbacksFactory &Factory);
/// Lex and return a vector of tokens for the given buffer.

View File

@@ -906,8 +906,6 @@ void CompilerInstance::parseAndCheckTypesUpTo(
const ImplicitImports &implicitImports, SourceFile::ASTStage_t limitStage) {
FrontendStatsTracer tracer(getStatsReporter(), "parse-and-check-types");
PersistentState = std::make_unique<PersistentParserState>();
bool hadLoadError = parsePartialModulesAndLibraryFiles(implicitImports);
if (Invocation.isCodeCompletion()) {
// When we are doing code completion, make sure to emit at least one
@@ -978,8 +976,7 @@ void CompilerInstance::parseLibraryFile(
auto DidSuppressWarnings = Diags.getSuppressWarnings();
Diags.setSuppressWarnings(DidSuppressWarnings || !IsPrimary);
parseIntoSourceFile(*NextInput, BufferID, PersistentState.get(),
/*DelayedBodyParsing=*/!IsPrimary);
parseIntoSourceFile(*NextInput, BufferID, /*DelayedBodyParsing=*/!IsPrimary);
Diags.setSuppressWarnings(DidSuppressWarnings);
@@ -1026,7 +1023,7 @@ void CompilerInstance::parseAndTypeCheckMainFileUpTo(
Diags.setSuppressWarnings(DidSuppressWarnings || !mainIsPrimary);
// Parse the Swift decls into the source file.
parseIntoSourceFile(MainFile, MainBufferID, PersistentState.get(),
parseIntoSourceFile(MainFile, MainBufferID,
/*delayBodyParsing*/ !mainIsPrimary);
// For a primary, also perform type checking if needed. Otherwise, just do
@@ -1096,6 +1093,11 @@ SourceFile *CompilerInstance::createSourceFileForMainModule(
recordPrimarySourceFile(inputFile);
}
if (bufferID == SourceMgr.getCodeCompletionBufferID()) {
assert(!CodeCompletionFile && "Multiple code completion files?");
CodeCompletionFile = inputFile;
}
return inputFile;
}
@@ -1121,9 +1123,6 @@ void CompilerInstance::performParseOnly(bool EvaluateConditionals,
MainBufferID);
}
PersistentState = std::make_unique<PersistentParserState>();
PersistentState->PerformConditionEvaluation = EvaluateConditionals;
auto shouldDelayBodies = [&](unsigned bufferID) -> bool {
if (!CanDelayBodies)
return false;
@@ -1141,8 +1140,8 @@ void CompilerInstance::performParseOnly(bool EvaluateConditionals,
SourceFileKind::Library, SourceFile::ImplicitModuleImportKind::None,
BufferID);
parseIntoSourceFile(*NextInput, BufferID, PersistentState.get(),
shouldDelayBodies(BufferID));
parseIntoSourceFile(*NextInput, BufferID, shouldDelayBodies(BufferID),
EvaluateConditionals);
}
// Now parse the main file.
@@ -1152,8 +1151,8 @@ void CompilerInstance::performParseOnly(bool EvaluateConditionals,
MainFile.SyntaxParsingCache = Invocation.getMainFileSyntaxParsingCache();
assert(MainBufferID == MainFile.getBufferID());
parseIntoSourceFile(MainFile, MainBufferID, PersistentState.get(),
shouldDelayBodies(MainBufferID));
parseIntoSourceFile(MainFile, MainBufferID, shouldDelayBodies(MainBufferID),
EvaluateConditionals);
}
assert(Context->LoadedModules.size() == 1 &&
@@ -1161,7 +1160,6 @@ void CompilerInstance::performParseOnly(bool EvaluateConditionals,
}
void CompilerInstance::freeASTContext() {
PersistentState.reset();
TheSILTypes.reset();
Context.reset();
MainModule = nullptr;

View File

@@ -176,21 +176,17 @@ bool CompletionInstance::performCachedOperaitonIfPossible(
return false;
auto &CI = *CachedCI;
auto *oldSF = CI.getCodeCompletionFile().get();
if (!CI.hasPersistentParserState())
return false;
auto &oldState = CI.getPersistentParserState();
if (!oldState.hasCodeCompletionDelayedDeclState())
return false;
auto *oldState = oldSF->getDelayedParserState();
assert(oldState->hasCodeCompletionDelayedDeclState());
auto &oldInfo = oldState->getCodeCompletionDelayedDeclState();
auto &SM = CI.getSourceMgr();
if (SM.getIdentifierForBuffer(SM.getCodeCompletionBufferID()) !=
completionBuffer->getBufferIdentifier())
return false;
auto &oldInfo = oldState.getCodeCompletionDelayedDeclState();
auto *oldSF = oldInfo.ParentContext->getParentSourceFile();
// Parse the new buffer into temporary SourceFile.
SourceManager tmpSM;
auto tmpBufferID = tmpSM.addMemBufferCopy(completionBuffer);
@@ -207,19 +203,20 @@ bool CompletionInstance::performCachedOperaitonIfPossible(
registerTypeCheckerRequestFunctions(tmpCtx->evaluator);
registerSILGenRequestFunctions(tmpCtx->evaluator);
ModuleDecl *tmpM = ModuleDecl::create(Identifier(), *tmpCtx);
PersistentParserState newState;
SourceFile *tmpSF =
new (*tmpCtx) SourceFile(*tmpM, oldSF->Kind, tmpBufferID,
SourceFile::ImplicitModuleImportKind::None);
tmpSF->enableInterfaceHash();
// Ensure all non-function-body tokens are hashed into the interface hash
tmpCtx->LangOpts.EnableTypeFingerprints = false;
parseIntoSourceFile(*tmpSF, tmpBufferID, &newState);
parseIntoSourceFile(*tmpSF, tmpBufferID);
// Couldn't find any completion token?
if (!newState.hasCodeCompletionDelayedDeclState())
auto *newState = tmpSF->getDelayedParserState();
if (!newState->hasCodeCompletionDelayedDeclState())
return false;
auto &newInfo = newState.getCodeCompletionDelayedDeclState();
auto &newInfo = newState->getCodeCompletionDelayedDeclState();
unsigned newBufferID;
switch (newInfo.Kind) {
@@ -273,7 +270,7 @@ bool CompletionInstance::performCachedOperaitonIfPossible(
// Construct dummy scopes. We don't need to restore the original scope
// because they are probably not 'isResolvable()' anyway.
auto &SI = oldState.getScopeInfo();
auto &SI = oldState->getScopeInfo();
assert(SI.getCurrentScope() == nullptr);
Scope Top(SI, ScopeKind::TopLevel);
Scope Body(SI, ScopeKind::FunctionBody);
@@ -282,7 +279,7 @@ bool CompletionInstance::performCachedOperaitonIfPossible(
oldInfo.StartOffset = newInfo.StartOffset;
oldInfo.EndOffset = newInfo.EndOffset;
oldInfo.PrevOffset = newInfo.PrevOffset;
oldState.restoreCodeCompletionDelayedDeclState(oldInfo);
oldState->restoreCodeCompletionDelayedDeclState(oldInfo);
auto *AFD = cast<AbstractFunctionDecl>(DC);
if (AFD->isBodySkipped())
@@ -324,14 +321,22 @@ bool CompletionInstance::performCachedOperaitonIfPossible(
CompilerInstance::addAdditionalInitialImportsTo(newSF, implicitImport);
newSF->enableInterfaceHash();
// Tell the compiler instance we've replaced the code completion file.
CI.setCodeCompletionFile(newSF);
// Re-parse the whole file. Still re-use imported modules.
(void)oldState.takeCodeCompletionDelayedDeclState();
parseIntoSourceFile(*newSF, newBufferID, &oldState);
parseIntoSourceFile(*newSF, newBufferID);
performNameBinding(*newSF);
bindExtensions(*newSF);
assert(oldState.hasCodeCompletionDelayedDeclState() &&
oldState.getCodeCompletionDelayedDeclState().Kind == newInfo.Kind);
#ifndef NDEBUG
const auto *reparsedState = newSF->getDelayedParserState();
assert(reparsedState->hasCodeCompletionDelayedDeclState() &&
"Didn't find completion token?");
auto &reparsedInfo = reparsedState->getCodeCompletionDelayedDeclState();
assert(reparsedInfo.Kind == newInfo.Kind);
#endif
break;
}
}
@@ -360,10 +365,16 @@ bool CompletionInstance::performNewOperation(
llvm::function_ref<void(CompilerInstance &)> Callback) {
auto TheInstance = std::make_unique<CompilerInstance>();
{
auto &CI = *TheInstance;
if (DiagC)
CI.addDiagnosticConsumer(DiagC);
SWIFT_DEFER {
if (DiagC)
CI.removeDiagnosticConsumer(DiagC);
};
if (FileSystem != llvm::vfs::getRealFileSystem())
CI.getSourceMgr().setFileSystem(FileSystem);
@@ -376,11 +387,20 @@ bool CompletionInstance::performNewOperation(
registerIDERequestFunctions(CI.getASTContext().evaluator);
CI.performParseAndResolveImportsOnly();
if (CI.hasPersistentParserState())
Callback(CI);
if (DiagC)
CI.removeDiagnosticConsumer(DiagC);
// If we didn't create a source file for completion, bail. This can happen
// if for example we fail to load the stdlib.
auto completionFile = CI.getCodeCompletionFile();
if (!completionFile)
return true;
// If we didn't find a code completion token, bail.
auto *state = completionFile.get()->getDelayedParserState();
if (!state->hasCodeCompletionDelayedDeclState())
return true;
Callback(CI);
}
if (ArgsHash.hasValue()) {
CachedCI = std::move(TheInstance);

View File

@@ -232,11 +232,10 @@ doCodeCompletion(SourceFile &SF, StringRef EnteredCode, unsigned *BufferID,
newSF.addImports(importsWithOptions);
}
PersistentParserState PersistentState;
parseIntoSourceFile(newSF, *BufferID, &PersistentState);
parseIntoSourceFile(newSF, *BufferID);
performTypeChecking(newSF);
performCodeCompletionSecondPass(PersistentState, *CompletionCallbacksFactory);
performCodeCompletionSecondPass(newSF, *CompletionCallbacksFactory);
// Reset the error state because it's only relevant to the code that we just
// processed, which now gets thrown away.

View File

@@ -25,7 +25,6 @@
#include "swift/Frontend/Frontend.h"
#include "swift/IDE/REPLCodeCompletion.h"
#include "swift/IDE/Utils.h"
#include "swift/Parse/PersistentParserState.h"
#include "swift/SIL/SILModule.h"
#include "swift/SILOptimizer/PassManager/Passes.h"
#include "llvm/ExecutionEngine/MCJIT.h"
@@ -157,7 +156,6 @@ static void convertToUTF8(llvm::ArrayRef<wchar_t> wide,
static ModuleDecl *
typeCheckREPLInput(ModuleDecl *MostRecentModule, StringRef Name,
PersistentParserState &PersistentState,
std::unique_ptr<llvm::MemoryBuffer> Buffer) {
using ImplicitModuleImportKind = SourceFile::ImplicitModuleImportKind;
assert(MostRecentModule);
@@ -187,7 +185,7 @@ typeCheckREPLInput(ModuleDecl *MostRecentModule, StringRef Name,
REPLInputFile.addImports(ImportsWithOptions);
}
parseIntoSourceFile(REPLInputFile, BufferID, &PersistentState);
parseIntoSourceFile(REPLInputFile, BufferID);
performTypeChecking(REPLInputFile);
return REPLModule;
}
@@ -753,7 +751,6 @@ class REPLEnvironment {
const SILOptions SILOpts;
REPLInput Input;
PersistentParserState PersistentState;
unsigned NextLineNumber = 0;
private:
@@ -858,7 +855,7 @@ private:
SmallString<8> Name{"REPL_"};
llvm::raw_svector_ostream(Name) << NextLineNumber;
++NextLineNumber;
ModuleDecl *M = typeCheckREPLInput(MostRecentModule, Name, PersistentState,
ModuleDecl *M = typeCheckREPLInput(MostRecentModule, Name,
std::move(InputBuf));
// SILGen the module and produce SIL diagnostics.
@@ -957,8 +954,7 @@ public:
DumpModule("REPL", LLVMContext),
IRGenOpts(),
SILOpts(),
Input(*this),
PersistentState()
Input(*this)
{
ASTContext &Ctx = CI.getASTContext();
Ctx.LangOpts.EnableAccessControl = false;
@@ -1005,8 +1001,7 @@ public:
auto Buffer =
llvm::MemoryBuffer::getMemBufferCopy(WarmUpStmt,
"<REPL Initialization>");
(void)typeCheckREPLInput(MostRecentModule, "__Warmup", PersistentState,
std::move(Buffer));
(void)typeCheckREPLInput(MostRecentModule, "__Warmup", std::move(Buffer));
if (Ctx.hadError())
return;

View File

@@ -609,7 +609,7 @@ ParserResult<IfConfigDecl> Parser::parseIfConfig(
bool shouldEvaluate =
// Don't evaluate if it's in '-parse' mode, etc.
State->PerformConditionEvaluation &&
EvaluateConditionals &&
// If it's in inactive #if ... #endif block, there's no point to do it.
!getScopeInfo().isInactiveConfigBlock();

View File

@@ -112,20 +112,20 @@ using namespace swift::syntax;
void SILParserTUStateBase::anchor() { }
void swift::performCodeCompletionSecondPass(
PersistentParserState &ParserState,
CodeCompletionCallbacksFactory &Factory) {
if (!ParserState.hasCodeCompletionDelayedDeclState())
SourceFile &SF, CodeCompletionCallbacksFactory &Factory) {
// If we didn't find the code completion token, bail.
auto *parserState = SF.getDelayedParserState();
if (!parserState->hasCodeCompletionDelayedDeclState())
return;
auto state = ParserState.takeCodeCompletionDelayedDeclState();
auto &SF = *state->ParentContext->getParentSourceFile();
auto state = parserState->takeCodeCompletionDelayedDeclState();
auto &Ctx = SF.getASTContext();
FrontendStatsTracer tracer(Ctx.Stats,
"CodeCompletionSecondPass");
auto BufferID = Ctx.SourceMgr.getCodeCompletionBufferID();
Parser TheParser(BufferID, SF, nullptr, &ParserState, nullptr);
Parser TheParser(BufferID, SF, nullptr, parserState, nullptr);
std::unique_ptr<CodeCompletionCallbacks> CodeCompletion(
Factory.createCodeCompletionCallbacks(TheParser));
@@ -366,15 +366,15 @@ static LexerMode sourceFileKindToLexerMode(SourceFileKind kind) {
Parser::Parser(unsigned BufferID, SourceFile &SF, SILParserTUStateBase *SIL,
PersistentParserState *PersistentState,
std::shared_ptr<SyntaxParseActions> SPActions,
bool DelayBodyParsing)
bool DelayBodyParsing, bool EvaluateConditionals)
: Parser(BufferID, SF, &SF.getASTContext().Diags, SIL, PersistentState,
std::move(SPActions), DelayBodyParsing) {}
std::move(SPActions), DelayBodyParsing, EvaluateConditionals) {}
Parser::Parser(unsigned BufferID, SourceFile &SF, DiagnosticEngine* LexerDiags,
SILParserTUStateBase *SIL,
PersistentParserState *PersistentState,
std::shared_ptr<SyntaxParseActions> SPActions,
bool DelayBodyParsing)
bool DelayBodyParsing, bool EvaluateConditionals)
: Parser(
std::unique_ptr<Lexer>(new Lexer(
SF.getASTContext().LangOpts, SF.getASTContext().SourceMgr,
@@ -389,7 +389,8 @@ Parser::Parser(unsigned BufferID, SourceFile &SF, DiagnosticEngine* LexerDiags,
SF.shouldBuildSyntaxTree()
? TriviaRetentionMode::WithTrivia
: TriviaRetentionMode::WithoutTrivia)),
SF, SIL, PersistentState, std::move(SPActions), DelayBodyParsing) {}
SF, SIL, PersistentState, std::move(SPActions), DelayBodyParsing,
EvaluateConditionals) {}
namespace {
@@ -510,7 +511,7 @@ Parser::Parser(std::unique_ptr<Lexer> Lex, SourceFile &SF,
SILParserTUStateBase *SIL,
PersistentParserState *PersistentState,
std::shared_ptr<SyntaxParseActions> SPActions,
bool DelayBodyParsing)
bool DelayBodyParsing, bool EvaluateConditionals)
: SourceMgr(SF.getASTContext().SourceMgr),
Diags(SF.getASTContext().Diags),
SF(SF),
@@ -520,6 +521,7 @@ Parser::Parser(std::unique_ptr<Lexer> Lex, SourceFile &SF,
Context(SF.getASTContext()),
CurrentTokenHash(SF.getInterfaceHashPtr()),
DelayBodyParsing(DelayBodyParsing),
EvaluateConditionals(EvaluateConditionals),
TokReceiver(SF.shouldCollectToken() ?
new TokenRecorder(SF, L->getBufferID()) :
new ConsumeTokenReceiver()),

View File

@@ -113,9 +113,16 @@ void PrettyStackTraceParser::print(llvm::raw_ostream &out) const {
out << '\n';
}
/// A thunk that deletes an allocated PersistentParserState. This is needed for
/// us to be able to forward declare a unique_ptr to the state in the AST.
static void deletePersistentParserState(PersistentParserState *state) {
delete state;
}
void swift::parseIntoSourceFile(SourceFile &SF, unsigned int BufferID,
PersistentParserState *PersistentState,
bool DelayBodyParsing) {
bool DelayBodyParsing,
bool EvaluateConditionals) {
auto &ctx = SF.getASTContext();
std::shared_ptr<SyntaxTreeCreator> STreeCreator;
if (SF.shouldBuildSyntaxTree()) {
STreeCreator = std::make_shared<SyntaxTreeCreator>(
@@ -133,10 +140,18 @@ void swift::parseIntoSourceFile(SourceFile &SF, unsigned int BufferID,
if (SF.shouldBuildSyntaxTree())
DelayBodyParsing = false;
// If this buffer is for code completion, hook up the state needed by its
// second pass.
PersistentParserState *state = nullptr;
if (ctx.SourceMgr.getCodeCompletionBufferID() == BufferID) {
state = new PersistentParserState();
SF.setDelayedParserState({state, &deletePersistentParserState});
}
FrontendStatsTracer tracer(SF.getASTContext().Stats,
"Parsing");
Parser P(BufferID, SF, /*SIL*/ nullptr, PersistentState, STreeCreator,
DelayBodyParsing);
Parser P(BufferID, SF, /*SIL*/ nullptr, state, STreeCreator, DelayBodyParsing,
EvaluateConditionals);
PrettyStackTraceParser StackTrace(P);
llvm::SaveAndRestore<NullablePtr<llvm::MD5>> S(P.CurrentTokenHash,

View File

@@ -137,8 +137,9 @@ static bool swiftCodeCompleteImpl(
SwiftConsumer.setContext(&CI.getASTContext(), &CI.getInvocation(),
&CompletionContext);
performCodeCompletionSecondPass(CI.getPersistentParserState(),
*callbacksFactory);
auto SF = CI.getCodeCompletionFile();
performCodeCompletionSecondPass(*SF.get(), *callbacksFactory);
SwiftConsumer.clearContext();
});
}

View File

@@ -42,8 +42,8 @@ static bool swiftConformingMethodListImpl(
ide::makeConformingMethodListCallbacksFactory(ExpectedTypeNames,
Consumer));
performCodeCompletionSecondPass(CI.getPersistentParserState(),
*callbacksFactory);
auto SF = CI.getCodeCompletionFile();
performCodeCompletionSecondPass(*SF.get(), *callbacksFactory);
});
}

View File

@@ -715,7 +715,7 @@ public:
Parser->getDiagnosticEngine().addConsumer(DiagConsumer);
// Collecting syntactic information shouldn't evaluate # conditions.
Parser->getParser().State->PerformConditionEvaluation = false;
Parser->getParser().EvaluateConditionals = false;
// If there is a syntax parsing cache, incremental syntax parsing is
// performed and thus the generated AST may not be up-to-date.

View File

@@ -39,8 +39,8 @@ static bool swiftTypeContextInfoImpl(
std::unique_ptr<CodeCompletionCallbacksFactory> callbacksFactory(
ide::makeTypeContextInfoCallbacksFactory(Consumer));
performCodeCompletionSecondPass(CI.getPersistentParserState(),
*callbacksFactory);
auto SF = CI.getCodeCompletionFile();
performCodeCompletionSecondPass(*SF.get(), *callbacksFactory);
});
}

View File

@@ -290,7 +290,7 @@ swiftparse_client_node_t SynParser::parse(const char *source) {
"syntax_parse_module", std::move(parseActions),
/*SyntaxCache=*/nullptr);
// Evaluating pound conditions may lead to unknown syntax.
PU.getParser().State->PerformConditionEvaluation = false;
PU.getParser().EvaluateConditionals = false;
std::unique_ptr<SynParserDiagConsumer> pConsumer;
if (DiagHandler) {
pConsumer = std::make_unique<SynParserDiagConsumer>(*this, bufID);

View File

@@ -776,8 +776,8 @@ static bool doCodeCompletionImpl(
Offset, /*EnableASTCaching=*/false, Error,
CodeCompletionDiagnostics ? &PrintDiags : nullptr,
[&](CompilerInstance &CI) {
performCodeCompletionSecondPass(CI.getPersistentParserState(),
*callbacksFactory);
auto SF = CI.getCodeCompletionFile();
performCodeCompletionSecondPass(*SF.get(), *callbacksFactory);
});
return isSuccess ? 0 : 1;
}
@@ -1124,7 +1124,7 @@ static int doSyntaxColoring(const CompilerInvocation &InitInvok,
registerTypeCheckerRequestFunctions(Parser.getParser().Context.evaluator);
// Collecting syntactic information shouldn't evaluate # conditions.
Parser.getParser().State->PerformConditionEvaluation = false;
Parser.getParser().EvaluateConditionals = false;
Parser.getDiagnosticEngine().addConsumer(PrintDiags);
(void)Parser.parse();
@@ -1361,7 +1361,7 @@ static int doStructureAnnotation(const CompilerInvocation &InitInvok,
Parser.getParser().Context.evaluator);
// Collecting syntactic information shouldn't evaluate # conditions.
Parser.getParser().State->PerformConditionEvaluation = false;
Parser.getParser().EvaluateConditionals = false;
// Display diagnostics to stderr.
PrintingDiagnosticConsumer PrintDiags;