Commit ad49e64f authored by Nikolai Kosjar's avatar Nikolai Kosjar Committed by Tim Jenssen

CppTools: Cancel parsing if editor is closed

The m_parserFuture.cancel() in ~BuiltinEditorDocumentProcessor() did not
cancel anything. Thus, closing a document while the parser was running
led to a blocking UI thread.

Now it cancels at the next include directive it encounters.

Change-Id: I092fddbbd747e0bc95265b6e9b4fcc26b3f76cb3
Reviewed-by: Friedemann Kleint's avatarFriedemann Kleint <Friedemann.Kleint@qt.io>
Reviewed-by: Tim Jenssen's avatarTim Jenssen <tim.jenssen@qt.io>
parent c8020af9
......@@ -762,6 +762,11 @@ QByteArray Preprocessor::run(const QString &fileName,
return preprocessed;
}
void Preprocessor::setCancelChecker(const Preprocessor::CancelChecker &cancelChecker)
{
m_cancelChecker = cancelChecker;
}
bool Preprocessor::expandFunctionlikeMacros() const
{
return m_expandFunctionlikeMacros;
......@@ -1636,6 +1641,9 @@ void Preprocessor::handlePreprocessorDirective(PPToken *tk)
void Preprocessor::handleIncludeDirective(PPToken *tk, bool includeNext)
{
if (m_cancelChecker && m_cancelChecker())
return;
m_state.m_lexer->setScanAngleStringLiteralTokens(true);
lex(tk); // consume "include" token
m_state.m_lexer->setScanAngleStringLiteralTokens(false);
......
......@@ -56,6 +56,8 @@
#include <QByteArray>
#include <QPair>
#include <functional>
namespace CPlusPlus {
class Environment;
......@@ -81,6 +83,9 @@ public:
QByteArray run(const QString &filename, const QByteArray &source,
bool noLines = false, bool markGeneratedTokens = true);
using CancelChecker = std::function<bool()>;
void setCancelChecker(const CancelChecker &cancelChecker);
bool expandFunctionlikeMacros() const;
void setExpandFunctionlikeMacros(bool expandFunctionlikeMacros);
......@@ -253,6 +258,7 @@ private:
Client *m_client;
Environment *m_env;
QByteArray m_scratchBuffer;
CancelChecker m_cancelChecker;
bool m_expandFunctionlikeMacros;
bool m_keepComments;
......
......@@ -35,7 +35,8 @@ ClangEditorDocumentParser::ClangEditorDocumentParser(const QString &filePath)
setConfiguration(config);
}
void ClangEditorDocumentParser::updateHelper(const CppTools::WorkingCopy &)
void ClangEditorDocumentParser::updateHelper(const QFutureInterface<void> &,
const CppTools::WorkingCopy &)
{
State state_ = state();
state_.projectPart = determineProjectPart(filePath(), configuration(), state_);
......
......@@ -37,7 +37,8 @@ public:
ClangEditorDocumentParser(const QString &filePath);
private:
void updateHelper(const CppTools::WorkingCopy &) override;
void updateHelper(const QFutureInterface<void> &future,
const CppTools::WorkingCopy &) override;
};
} // namespace ClangCodeModel
......@@ -77,9 +77,16 @@ void BaseEditorDocumentParser::setConfiguration(const Configuration &configurati
}
void BaseEditorDocumentParser::update(const WorkingCopy &workingCopy)
{
QFutureInterface<void> dummy;
update(dummy, workingCopy);
}
void BaseEditorDocumentParser::update(const QFutureInterface<void> &future,
const WorkingCopy &workingCopy)
{
QMutexLocker locker(&m_updateIsRunning);
updateHelper(workingCopy);
updateHelper(future, workingCopy);
}
BaseEditorDocumentParser::State BaseEditorDocumentParser::state() const
......
......@@ -29,6 +29,7 @@
#include "cppworkingcopy.h"
#include "projectpart.h"
#include <QFutureInterface>
#include <QObject>
#include <QMutex>
......@@ -39,7 +40,7 @@ class CPPTOOLS_EXPORT BaseEditorDocumentParser : public QObject
Q_OBJECT
public:
using Ptr = QSharedPointer<BaseEditorDocumentParser>;;
using Ptr = QSharedPointer<BaseEditorDocumentParser>;
static Ptr get(const QString &filePath);
struct Configuration {
......@@ -58,6 +59,7 @@ public:
void setConfiguration(const Configuration &configuration);
void update(const WorkingCopy &workingCopy);
void update(const QFutureInterface<void> &future, const WorkingCopy &workingCopy);
ProjectPart::Ptr projectPart() const;
......@@ -76,7 +78,8 @@ protected:
mutable QMutex m_stateAndConfigurationMutex;
private:
virtual void updateHelper(const WorkingCopy &workingCopy) = 0;
virtual void updateHelper(const QFutureInterface<void> &future,
const WorkingCopy &workingCopy) = 0;
const QString m_filePath;
Configuration m_configuration;
......
......@@ -77,7 +77,7 @@ void BaseEditorDocumentProcessor::runParser(QFutureInterface<void> &future,
return;
}
parser->update(workingCopy);
parser->update(future, workingCopy);
CppToolsBridge::finishedRefreshingSourceFiles({parser->filePath()});
future.setProgressValue(1);
......
......@@ -55,7 +55,8 @@ BuiltinEditorDocumentParser::BuiltinEditorDocumentParser(const QString &filePath
qRegisterMetaType<CPlusPlus::Snapshot>("CPlusPlus::Snapshot");
}
void BuiltinEditorDocumentParser::updateHelper(const WorkingCopy &theWorkingCopy)
void BuiltinEditorDocumentParser::updateHelper(const QFutureInterface<void> &future,
const WorkingCopy &theWorkingCopy)
{
if (filePath().isEmpty())
return;
......@@ -181,6 +182,10 @@ void BuiltinEditorDocumentParser::updateHelper(const WorkingCopy &theWorkingCopy
if (releaseSourceAndAST_)
doc->releaseSourceAndAST();
});
sourceProcessor.setCancelChecker([future]() {
return future.isCanceled();
});
Snapshot globalSnapshot = modelManager->snapshot();
globalSnapshot.remove(filePath());
sourceProcessor.setGlobalSnapshot(globalSnapshot);
......
......@@ -58,7 +58,8 @@ public:
static Ptr get(const QString &filePath);
private:
void updateHelper(const WorkingCopy &workingCopy) override;
void updateHelper(const QFutureInterface<void> &future,
const WorkingCopy &workingCopy) override;
void addFileAndDependencies(CPlusPlus::Snapshot *snapshot,
QSet<Utils::FileName> *toRemove,
const Utils::FileName &fileName) const;
......
......@@ -121,6 +121,11 @@ CppSourceProcessor::CppSourceProcessor(const Snapshot &snapshot, DocumentCallbac
CppSourceProcessor::~CppSourceProcessor()
{ }
void CppSourceProcessor::setCancelChecker(const CppSourceProcessor::CancelChecker &cancelChecker)
{
m_preprocess.setCancelChecker(cancelChecker);
}
void CppSourceProcessor::setWorkingCopy(const WorkingCopy &workingCopy)
{ m_workingCopy = workingCopy; }
......
......@@ -59,6 +59,9 @@ public:
CppSourceProcessor(const CPlusPlus::Snapshot &snapshot, DocumentCallback documentFinished);
~CppSourceProcessor();
using CancelChecker = std::function<bool()>;
void setCancelChecker(const CancelChecker &cancelChecker);
void setWorkingCopy(const CppTools::WorkingCopy &workingCopy);
void setHeaderPaths(const ProjectPartHeaderPaths &headerPaths);
void setLanguageFeatures(CPlusPlus::LanguageFeatures languageFeatures);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment