forked from qt-creator/qt-creator
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 <Friedemann.Kleint@qt.io> Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
committed by
Tim Jenssen
parent
c8020af997
commit
ad49e64ff0
@@ -762,6 +762,11 @@ QByteArray Preprocessor::run(const QString &fileName,
|
|||||||
return preprocessed;
|
return preprocessed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Preprocessor::setCancelChecker(const Preprocessor::CancelChecker &cancelChecker)
|
||||||
|
{
|
||||||
|
m_cancelChecker = cancelChecker;
|
||||||
|
}
|
||||||
|
|
||||||
bool Preprocessor::expandFunctionlikeMacros() const
|
bool Preprocessor::expandFunctionlikeMacros() const
|
||||||
{
|
{
|
||||||
return m_expandFunctionlikeMacros;
|
return m_expandFunctionlikeMacros;
|
||||||
@@ -1636,6 +1641,9 @@ void Preprocessor::handlePreprocessorDirective(PPToken *tk)
|
|||||||
|
|
||||||
void Preprocessor::handleIncludeDirective(PPToken *tk, bool includeNext)
|
void Preprocessor::handleIncludeDirective(PPToken *tk, bool includeNext)
|
||||||
{
|
{
|
||||||
|
if (m_cancelChecker && m_cancelChecker())
|
||||||
|
return;
|
||||||
|
|
||||||
m_state.m_lexer->setScanAngleStringLiteralTokens(true);
|
m_state.m_lexer->setScanAngleStringLiteralTokens(true);
|
||||||
lex(tk); // consume "include" token
|
lex(tk); // consume "include" token
|
||||||
m_state.m_lexer->setScanAngleStringLiteralTokens(false);
|
m_state.m_lexer->setScanAngleStringLiteralTokens(false);
|
||||||
|
|||||||
@@ -56,6 +56,8 @@
|
|||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
#include <QPair>
|
#include <QPair>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
namespace CPlusPlus {
|
namespace CPlusPlus {
|
||||||
|
|
||||||
class Environment;
|
class Environment;
|
||||||
@@ -81,6 +83,9 @@ public:
|
|||||||
QByteArray run(const QString &filename, const QByteArray &source,
|
QByteArray run(const QString &filename, const QByteArray &source,
|
||||||
bool noLines = false, bool markGeneratedTokens = true);
|
bool noLines = false, bool markGeneratedTokens = true);
|
||||||
|
|
||||||
|
using CancelChecker = std::function<bool()>;
|
||||||
|
void setCancelChecker(const CancelChecker &cancelChecker);
|
||||||
|
|
||||||
bool expandFunctionlikeMacros() const;
|
bool expandFunctionlikeMacros() const;
|
||||||
void setExpandFunctionlikeMacros(bool expandFunctionlikeMacros);
|
void setExpandFunctionlikeMacros(bool expandFunctionlikeMacros);
|
||||||
|
|
||||||
@@ -253,6 +258,7 @@ private:
|
|||||||
Client *m_client;
|
Client *m_client;
|
||||||
Environment *m_env;
|
Environment *m_env;
|
||||||
QByteArray m_scratchBuffer;
|
QByteArray m_scratchBuffer;
|
||||||
|
CancelChecker m_cancelChecker;
|
||||||
|
|
||||||
bool m_expandFunctionlikeMacros;
|
bool m_expandFunctionlikeMacros;
|
||||||
bool m_keepComments;
|
bool m_keepComments;
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ ClangEditorDocumentParser::ClangEditorDocumentParser(const QString &filePath)
|
|||||||
setConfiguration(config);
|
setConfiguration(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangEditorDocumentParser::updateHelper(const CppTools::WorkingCopy &)
|
void ClangEditorDocumentParser::updateHelper(const QFutureInterface<void> &,
|
||||||
|
const CppTools::WorkingCopy &)
|
||||||
{
|
{
|
||||||
State state_ = state();
|
State state_ = state();
|
||||||
state_.projectPart = determineProjectPart(filePath(), configuration(), state_);
|
state_.projectPart = determineProjectPart(filePath(), configuration(), state_);
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ public:
|
|||||||
ClangEditorDocumentParser(const QString &filePath);
|
ClangEditorDocumentParser(const QString &filePath);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateHelper(const CppTools::WorkingCopy &) override;
|
void updateHelper(const QFutureInterface<void> &future,
|
||||||
|
const CppTools::WorkingCopy &) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ClangCodeModel
|
} // namespace ClangCodeModel
|
||||||
|
|||||||
@@ -77,9 +77,16 @@ void BaseEditorDocumentParser::setConfiguration(const Configuration &configurati
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BaseEditorDocumentParser::update(const WorkingCopy &workingCopy)
|
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);
|
QMutexLocker locker(&m_updateIsRunning);
|
||||||
updateHelper(workingCopy);
|
updateHelper(future, workingCopy);
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseEditorDocumentParser::State BaseEditorDocumentParser::state() const
|
BaseEditorDocumentParser::State BaseEditorDocumentParser::state() const
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "cppworkingcopy.h"
|
#include "cppworkingcopy.h"
|
||||||
#include "projectpart.h"
|
#include "projectpart.h"
|
||||||
|
|
||||||
|
#include <QFutureInterface>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
|
|
||||||
@@ -39,7 +40,7 @@ class CPPTOOLS_EXPORT BaseEditorDocumentParser : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using Ptr = QSharedPointer<BaseEditorDocumentParser>;;
|
using Ptr = QSharedPointer<BaseEditorDocumentParser>;
|
||||||
static Ptr get(const QString &filePath);
|
static Ptr get(const QString &filePath);
|
||||||
|
|
||||||
struct Configuration {
|
struct Configuration {
|
||||||
@@ -58,6 +59,7 @@ public:
|
|||||||
void setConfiguration(const Configuration &configuration);
|
void setConfiguration(const Configuration &configuration);
|
||||||
|
|
||||||
void update(const WorkingCopy &workingCopy);
|
void update(const WorkingCopy &workingCopy);
|
||||||
|
void update(const QFutureInterface<void> &future, const WorkingCopy &workingCopy);
|
||||||
|
|
||||||
ProjectPart::Ptr projectPart() const;
|
ProjectPart::Ptr projectPart() const;
|
||||||
|
|
||||||
@@ -76,7 +78,8 @@ protected:
|
|||||||
mutable QMutex m_stateAndConfigurationMutex;
|
mutable QMutex m_stateAndConfigurationMutex;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void updateHelper(const WorkingCopy &workingCopy) = 0;
|
virtual void updateHelper(const QFutureInterface<void> &future,
|
||||||
|
const WorkingCopy &workingCopy) = 0;
|
||||||
|
|
||||||
const QString m_filePath;
|
const QString m_filePath;
|
||||||
Configuration m_configuration;
|
Configuration m_configuration;
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ void BaseEditorDocumentProcessor::runParser(QFutureInterface<void> &future,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
parser->update(workingCopy);
|
parser->update(future, workingCopy);
|
||||||
CppToolsBridge::finishedRefreshingSourceFiles({parser->filePath()});
|
CppToolsBridge::finishedRefreshingSourceFiles({parser->filePath()});
|
||||||
|
|
||||||
future.setProgressValue(1);
|
future.setProgressValue(1);
|
||||||
|
|||||||
@@ -55,7 +55,8 @@ BuiltinEditorDocumentParser::BuiltinEditorDocumentParser(const QString &filePath
|
|||||||
qRegisterMetaType<CPlusPlus::Snapshot>("CPlusPlus::Snapshot");
|
qRegisterMetaType<CPlusPlus::Snapshot>("CPlusPlus::Snapshot");
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuiltinEditorDocumentParser::updateHelper(const WorkingCopy &theWorkingCopy)
|
void BuiltinEditorDocumentParser::updateHelper(const QFutureInterface<void> &future,
|
||||||
|
const WorkingCopy &theWorkingCopy)
|
||||||
{
|
{
|
||||||
if (filePath().isEmpty())
|
if (filePath().isEmpty())
|
||||||
return;
|
return;
|
||||||
@@ -181,6 +182,10 @@ void BuiltinEditorDocumentParser::updateHelper(const WorkingCopy &theWorkingCopy
|
|||||||
if (releaseSourceAndAST_)
|
if (releaseSourceAndAST_)
|
||||||
doc->releaseSourceAndAST();
|
doc->releaseSourceAndAST();
|
||||||
});
|
});
|
||||||
|
sourceProcessor.setCancelChecker([future]() {
|
||||||
|
return future.isCanceled();
|
||||||
|
});
|
||||||
|
|
||||||
Snapshot globalSnapshot = modelManager->snapshot();
|
Snapshot globalSnapshot = modelManager->snapshot();
|
||||||
globalSnapshot.remove(filePath());
|
globalSnapshot.remove(filePath());
|
||||||
sourceProcessor.setGlobalSnapshot(globalSnapshot);
|
sourceProcessor.setGlobalSnapshot(globalSnapshot);
|
||||||
|
|||||||
@@ -58,7 +58,8 @@ public:
|
|||||||
static Ptr get(const QString &filePath);
|
static Ptr get(const QString &filePath);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateHelper(const WorkingCopy &workingCopy) override;
|
void updateHelper(const QFutureInterface<void> &future,
|
||||||
|
const WorkingCopy &workingCopy) override;
|
||||||
void addFileAndDependencies(CPlusPlus::Snapshot *snapshot,
|
void addFileAndDependencies(CPlusPlus::Snapshot *snapshot,
|
||||||
QSet<Utils::FileName> *toRemove,
|
QSet<Utils::FileName> *toRemove,
|
||||||
const Utils::FileName &fileName) const;
|
const Utils::FileName &fileName) const;
|
||||||
|
|||||||
@@ -121,6 +121,11 @@ CppSourceProcessor::CppSourceProcessor(const Snapshot &snapshot, DocumentCallbac
|
|||||||
CppSourceProcessor::~CppSourceProcessor()
|
CppSourceProcessor::~CppSourceProcessor()
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
void CppSourceProcessor::setCancelChecker(const CppSourceProcessor::CancelChecker &cancelChecker)
|
||||||
|
{
|
||||||
|
m_preprocess.setCancelChecker(cancelChecker);
|
||||||
|
}
|
||||||
|
|
||||||
void CppSourceProcessor::setWorkingCopy(const WorkingCopy &workingCopy)
|
void CppSourceProcessor::setWorkingCopy(const WorkingCopy &workingCopy)
|
||||||
{ m_workingCopy = workingCopy; }
|
{ m_workingCopy = workingCopy; }
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,9 @@ public:
|
|||||||
CppSourceProcessor(const CPlusPlus::Snapshot &snapshot, DocumentCallback documentFinished);
|
CppSourceProcessor(const CPlusPlus::Snapshot &snapshot, DocumentCallback documentFinished);
|
||||||
~CppSourceProcessor();
|
~CppSourceProcessor();
|
||||||
|
|
||||||
|
using CancelChecker = std::function<bool()>;
|
||||||
|
void setCancelChecker(const CancelChecker &cancelChecker);
|
||||||
|
|
||||||
void setWorkingCopy(const CppTools::WorkingCopy &workingCopy);
|
void setWorkingCopy(const CppTools::WorkingCopy &workingCopy);
|
||||||
void setHeaderPaths(const ProjectPartHeaderPaths &headerPaths);
|
void setHeaderPaths(const ProjectPartHeaderPaths &headerPaths);
|
||||||
void setLanguageFeatures(CPlusPlus::LanguageFeatures languageFeatures);
|
void setLanguageFeatures(CPlusPlus::LanguageFeatures languageFeatures);
|
||||||
|
|||||||
Reference in New Issue
Block a user