Skip to content

Delay parsing more often #26991

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Sep 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions include/swift/Frontend/Frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,6 @@ class CompilerInstance {

private:
void createREPLFile(const ImplicitImports &implicitImports);
std::unique_ptr<DelayedParsingCallbacks> computeDelayedParsingCallback();

void addMainFileToModule(const ImplicitImports &implicitImports);

Expand All @@ -625,20 +624,17 @@ class CompilerInstance {
SourceFile::ASTStage_t LimitStage);

void parseLibraryFile(unsigned BufferID,
const ImplicitImports &implicitImports,
DelayedParsingCallbacks *DelayedCB);
const ImplicitImports &implicitImports);

/// Return true if had load error
bool
parsePartialModulesAndLibraryFiles(const ImplicitImports &implicitImports,
DelayedParsingCallbacks *DelayedCB);
parsePartialModulesAndLibraryFiles(const ImplicitImports &implicitImports);

OptionSet<TypeCheckingFlags> computeTypeCheckingOptions();

void forEachFileToTypeCheck(llvm::function_ref<void(SourceFile &)> fn);

void parseAndTypeCheckMainFileUpTo(SourceFile::ASTStage_t LimitStage,
DelayedParsingCallbacks *DelayedParseCB,
OptionSet<TypeCheckingFlags> TypeCheckOptions);

void finishTypeChecking(OptionSet<TypeCheckingFlags> TypeCheckOptions);
Expand Down
59 changes: 0 additions & 59 deletions include/swift/Parse/DelayedParsingCallbacks.h

This file was deleted.

9 changes: 1 addition & 8 deletions include/swift/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ namespace llvm {
namespace swift {
class CodeCompletionCallbacks;
class DefaultArgumentInitializer;
class DelayedParsingCallbacks;
class DiagnosticEngine;
class Expr;
class Lexer;
Expand Down Expand Up @@ -165,14 +164,8 @@ class Parser {

LocalContext *CurLocalContext = nullptr;

DelayedParsingCallbacks *DelayedParseCB = nullptr;

bool isDelayedParsingEnabled() const {
return DelayBodyParsing || DelayedParseCB != nullptr;
}

void setDelayedParsingCallbacks(DelayedParsingCallbacks *DelayedParseCB) {
this->DelayedParseCB = DelayedParseCB;
return DelayBodyParsing || SourceMgr.getCodeCompletionLoc().isValid();
}

void setCodeCompletionCallbacks(CodeCompletionCallbacks *Callbacks) {
Expand Down
19 changes: 12 additions & 7 deletions include/swift/Subsystems.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ namespace swift {
class CodeCompletionCallbacksFactory;
class Decl;
class DeclContext;
class DelayedParsingCallbacks;
class DiagnosticConsumer;
class DiagnosticEngine;
class Evaluator;
Expand Down Expand Up @@ -114,23 +113,29 @@ namespace swift {
/// \param PersistentState if non-null the same PersistentState object can
/// be used to resume parsing or parse delayed function bodies.
///
/// \param DelayedParseCB if non-null enables delayed parsing for function
/// bodies.
///
/// \return true if the parser found code with side effects.
bool parseIntoSourceFile(SourceFile &SF, unsigned BufferID, bool *Done,
SILParserState *SIL = nullptr,
PersistentParserState *PersistentState = nullptr,
DelayedParsingCallbacks *DelayedParseCB = nullptr,
bool DelayBodyParsing = true);

/// DEPRECATED: Only used to break LLDB/Swift dependency.
inline
bool parseIntoSourceFile(SourceFile &SF, unsigned BufferID, bool *Done,
SILParserState *SIL,
PersistentParserState *PersistentState,
std::nullptr_t,
bool DelayBodyParsing) {
return parseIntoSourceFile(SF, BufferID, Done, SIL, PersistentState,
DelayBodyParsing);
}

/// Parse a single buffer into the given source file, until the full source
/// contents are parsed.
///
/// \return true if the parser found code with side effects.
bool parseIntoSourceFileFull(SourceFile &SF, unsigned BufferID,
PersistentParserState *PersistentState = nullptr,
DelayedParsingCallbacks *DelayedParseCB = nullptr,
PersistentParserState *PersistentState = nullptr,
bool DelayBodyParsing = true);

/// Finish the parsing by going over the nodes that were delayed
Expand Down
3 changes: 3 additions & 0 deletions lib/Basic/SourceLoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ void SourceManager::verifyAllBuffers() const {
}

SourceLoc SourceManager::getCodeCompletionLoc() const {
if (CodeCompletionBufferID == 0U)
return SourceLoc();

return getLocForBufferStart(CodeCompletionBufferID)
.getAdvancedLoc(CodeCompletionOffset);
}
Expand Down
33 changes: 9 additions & 24 deletions lib/Frontend/Frontend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
#include "swift/Basic/SourceManager.h"
#include "swift/Basic/Statistic.h"
#include "swift/Frontend/ParseableInterfaceModuleLoader.h"
#include "swift/Parse/DelayedParsingCallbacks.h"
#include "swift/Parse/Lexer.h"
#include "swift/SIL/SILModule.h"
#include "swift/SILOptimizer/PassManager/Passes.h"
Expand Down Expand Up @@ -758,14 +757,6 @@ void CompilerInstance::createREPLFile(const ImplicitImports &implicitImports) {
addAdditionalInitialImportsTo(SingleInputFile, implicitImports);
}

std::unique_ptr<DelayedParsingCallbacks>
CompilerInstance::computeDelayedParsingCallback() {
if (Invocation.isCodeCompletion())
return llvm::make_unique<CodeCompleteDelayedCallbacks>(
SourceMgr.getCodeCompletionLoc());
return nullptr;
}

void CompilerInstance::addMainFileToModule(
const ImplicitImports &implicitImports) {
auto *MainFile = createSourceFileForMainModule(
Expand All @@ -776,13 +767,10 @@ void CompilerInstance::addMainFileToModule(
void CompilerInstance::parseAndCheckTypesUpTo(
const ImplicitImports &implicitImports, SourceFile::ASTStage_t limitStage) {
FrontendStatsTracer tracer(Context->Stats, "parse-and-check-types");
std::unique_ptr<DelayedParsingCallbacks> DelayedCB{
computeDelayedParsingCallback()};

PersistentState = llvm::make_unique<PersistentParserState>();

bool hadLoadError = parsePartialModulesAndLibraryFiles(
implicitImports, DelayedCB.get());
bool hadLoadError = parsePartialModulesAndLibraryFiles(implicitImports);
if (Invocation.isCodeCompletion()) {
// When we are doing code completion, make sure to emit at least one
// diagnostic, so that ASTContext is marked as erroneous. In this case
Expand All @@ -800,7 +788,7 @@ void CompilerInstance::parseAndCheckTypesUpTo(
// In addition, the main file has parsing and type-checking
// interwined.
if (MainBufferID != NO_SUCH_BUFFER) {
parseAndTypeCheckMainFileUpTo(limitStage, DelayedCB.get(), TypeCheckOptions);
parseAndTypeCheckMainFileUpTo(limitStage, TypeCheckOptions);
}

assert(llvm::all_of(MainModule->getFiles(), [](const FileUnit *File) -> bool {
Expand Down Expand Up @@ -846,8 +834,7 @@ void CompilerInstance::parseAndCheckTypesUpTo(
}

void CompilerInstance::parseLibraryFile(
unsigned BufferID, const ImplicitImports &implicitImports,
DelayedParsingCallbacks *DelayedCB) {
unsigned BufferID, const ImplicitImports &implicitImports) {
FrontendStatsTracer tracer(Context->Stats, "parse-library-file");

auto *NextInput = createSourceFileForMainModule(
Expand All @@ -865,7 +852,7 @@ void CompilerInstance::parseLibraryFile(
// Parser may stop at some erroneous constructions like #else, #endif
// or '}' in some cases, continue parsing until we are done
parseIntoSourceFile(*NextInput, BufferID, &Done, nullptr,
PersistentState.get(), DelayedCB,
PersistentState.get(),
/*DelayedBodyParsing=*/!IsPrimary);
} while (!Done);

Expand Down Expand Up @@ -893,8 +880,7 @@ OptionSet<TypeCheckingFlags> CompilerInstance::computeTypeCheckingOptions() {
}

bool CompilerInstance::parsePartialModulesAndLibraryFiles(
const ImplicitImports &implicitImports,
DelayedParsingCallbacks *DelayedCB) {
const ImplicitImports &implicitImports) {
FrontendStatsTracer tracer(Context->Stats,
"parse-partial-modules-and-library-files");
bool hadLoadError = false;
Expand All @@ -910,15 +896,14 @@ bool CompilerInstance::parsePartialModulesAndLibraryFiles(
// Then parse all the library files.
for (auto BufferID : InputSourceCodeBufferIDs) {
if (BufferID != MainBufferID) {
parseLibraryFile(BufferID, implicitImports, DelayedCB);
parseLibraryFile(BufferID, implicitImports);
}
}
return hadLoadError;
}

void CompilerInstance::parseAndTypeCheckMainFileUpTo(
SourceFile::ASTStage_t LimitStage,
DelayedParsingCallbacks *DelayedParseCB,
OptionSet<TypeCheckingFlags> TypeCheckOptions) {
FrontendStatsTracer tracer(Context->Stats,
"parse-and-typecheck-main-file");
Expand All @@ -942,7 +927,7 @@ void CompilerInstance::parseAndTypeCheckMainFileUpTo(
// with 'sil' definitions.
parseIntoSourceFile(MainFile, MainFile.getBufferID().getValue(), &Done,
TheSILModule ? &SILContext : nullptr,
PersistentState.get(), DelayedParseCB,
PersistentState.get(),
/*DelayedBodyParsing=*/false);

if (mainIsPrimary && (Done || CurTUElem < MainFile.Decls.size())) {
Expand Down Expand Up @@ -1069,7 +1054,7 @@ void CompilerInstance::performParseOnly(bool EvaluateConditionals,
BufferID);

parseIntoSourceFileFull(*NextInput, BufferID, PersistentState.get(),
nullptr, /*DelayBodyParsing=*/!IsPrimary);
/*DelayBodyParsing=*/!IsPrimary);
}

// Now parse the main file.
Expand All @@ -1079,7 +1064,7 @@ void CompilerInstance::performParseOnly(bool EvaluateConditionals,
MainFile.SyntaxParsingCache = Invocation.getMainFileSyntaxParsingCache();

parseIntoSourceFileFull(MainFile, MainFile.getBufferID().getValue(),
PersistentState.get(), nullptr,
PersistentState.get(),
/*DelayBodyParsing=*/false);
}

Expand Down
6 changes: 1 addition & 5 deletions lib/IDE/REPLCodeCompletion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
#include "swift/AST/Module.h"
#include "swift/Basic/LLVM.h"
#include "swift/Basic/SourceManager.h"
#include "swift/Parse/DelayedParsingCallbacks.h"
#include "swift/Parse/Parser.h"
#include "swift/IDE/CodeCompletion.h"
#include "swift/Subsystems.h"
Expand Down Expand Up @@ -208,12 +207,9 @@ doCodeCompletion(SourceFile &SF, StringRef EnteredCode, unsigned *BufferID,
const unsigned OriginalDeclCount = SF.Decls.size();

PersistentParserState PersistentState;
std::unique_ptr<DelayedParsingCallbacks> DelayedCB(
new CodeCompleteDelayedCallbacks(Ctx.SourceMgr.getCodeCompletionLoc()));
bool Done;
do {
parseIntoSourceFile(SF, *BufferID, &Done, nullptr, &PersistentState,
DelayedCB.get());
parseIntoSourceFile(SF, *BufferID, &Done, nullptr, &PersistentState);
} while (!Done);
performTypeChecking(SF, PersistentState.getTopLevelContext(), None,
OriginalDeclCount);
Expand Down
6 changes: 2 additions & 4 deletions lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

#include "swift/Parse/Parser.h"
#include "swift/Parse/CodeCompletionCallbacks.h"
#include "swift/Parse/DelayedParsingCallbacks.h"
#include "swift/Parse/ParsedSyntaxRecorder.h"
#include "swift/Parse/ParseSILSupport.h"
#include "swift/Parse/SyntaxParsingContext.h"
Expand Down Expand Up @@ -5387,9 +5386,8 @@ void Parser::consumeAbstractFunctionBody(AbstractFunctionDecl *AFD,

BodyRange.End = PreviousLoc;

if (DelayedParseCB &&
DelayedParseCB->shouldDelayFunctionBodyParsing(*this, AFD, Attrs,
BodyRange)) {
if (SourceMgr.getCodeCompletionLoc().isInvalid() ||
SourceMgr.rangeContainsCodeCompletionLoc(BodyRange)) {
AFD->setBodyDelayed(BodyRange);
} else {
AFD->setBodySkipped(BodyRange);
Expand Down
4 changes: 1 addition & 3 deletions lib/Parse/ParseRequests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,12 @@ BraceStmt *ParseAbstractFunctionBodyRequest::evaluate(
}

case BodyKind::Unparsed: {
// FIXME: It should be fine to delay body parsing of local functions, so
// the DelayBodyParsing should go away entirely
// FIXME: How do we configure code completion?
SourceFile &sf = *afd->getDeclContext()->getParentSourceFile();
SourceManager &sourceMgr = sf.getASTContext().SourceMgr;
unsigned bufferID = sourceMgr.findBufferContainingLoc(afd->getLoc());
Parser parser(bufferID, sf, static_cast<SILParserTUStateBase *>(nullptr),
nullptr, nullptr, /*DelayBodyParsing=*/false);
nullptr, nullptr);
parser.SyntaxContext->setDiscard();
auto body = parser.parseAbstractFunctionBodyDelayed(afd);
afd->setBodyKind(BodyKind::Parsed);
Expand Down
2 changes: 0 additions & 2 deletions lib/Parse/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
#include "swift/Basic/Timer.h"
#include "swift/Parse/Lexer.h"
#include "swift/Parse/CodeCompletionCallbacks.h"
#include "swift/Parse/DelayedParsingCallbacks.h"
#include "swift/Parse/ParsedSyntaxNodes.h"
#include "swift/Parse/ParsedSyntaxRecorder.h"
#include "swift/Parse/ParseSILSupport.h"
Expand Down Expand Up @@ -112,7 +111,6 @@ void tokenize(const LangOptions &LangOpts, const SourceManager &SM,
using namespace swift;
using namespace swift::syntax;

void DelayedParsingCallbacks::anchor() { }
void SILParserTUStateBase::anchor() { }

namespace {
Expand Down
Loading