Clang: Fix delayed reparse of dirty and visible but not current documents

1. Open document foo.h
2. Create a split and open foo.cpp (#including "foo.h")
3. Edit foo.h (e.g. by introducing a syntax error, so that foo.cpp will
   indicate header errors in the toolbar or as info bar)
=> Actual: foo.cpp will be reparsed immediately.
 Expected: foo.cpp should be reparsed after a delay.

This saves resources (cpu time) and minimizes poping up of the header
info bar while editing header files in splits.

Regression introduced by

    commit 380d756a03
    Clang: Hook up supportive translation unit on first edit

Change-Id: Ib5fd90e49415dfc3aefacab7cd627b0e1937f5fc
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Nikolai Kosjar
2016-10-14 13:05:44 +02:00
parent d29781fcd8
commit 4fbdbdb1ee
6 changed files with 121 additions and 15 deletions

View File

@@ -50,6 +50,8 @@
#include <updatetranslationunitsforeditormessage.h>
#include <updatevisibletranslationunitsmessage.h>
#include <utils/qtcassert.h>
#include <QCoreApplication>
#include <QDebug>
@@ -57,16 +59,21 @@ namespace ClangBackEnd {
ClangCodeModelServer::ClangCodeModelServer()
: documents(projects, unsavedFiles)
, updateDocumentAnnotationsTimeOutInMs(1500)
{
updateDocumentAnnotationsTimer.setSingleShot(true);
QObject::connect(&updateDocumentAnnotationsTimer,
&QTimer::timeout,
[this]() {
processJobsForDirtyAndVisibleDocuments();
});
updateVisibleButNotCurrentDocumentsTimer.setSingleShot(true);
QObject::connect(&updateVisibleButNotCurrentDocumentsTimer,
&QTimer::timeout,
[this]() {
processJobsForDirtyAndVisibleButNotCurrentDocuments();
});
QObject::connect(documents.clangFileSystemWatcher(),
&ClangFileSystemWatcher::fileChanged,
[this](const Utf8String &filePath) {
@@ -265,16 +272,44 @@ bool ClangCodeModelServer::isTimerRunningForTestOnly() const
void ClangCodeModelServer::processJobsForDirtyAndVisibleDocuments()
{
for (const auto &document : documents.documents()) {
if (document.isNeedingReparse() && document.isVisibleInEditor()) {
DocumentProcessor processor = documentProcessors().processor(document);
processor.addJob(createJobRequest(document,
JobRequest::Type::UpdateDocumentAnnotations,
PreferredTranslationUnit::PreviouslyParsed));
}
}
processJobsForDirtyCurrentDocument();
processTimerForVisibleButNotCurrentDocuments();
}
documentProcessors().process();
void ClangCodeModelServer::processJobsForDirtyCurrentDocument()
{
const auto currentDirtyDocuments = documents.filtered([](const Document &document) {
return document.isNeedingReparse() && document.isUsedByCurrentEditor();
});
QTC_CHECK(currentDirtyDocuments.size() <= 1);
addAndRunUpdateJobs(currentDirtyDocuments);
}
void ClangCodeModelServer::addAndRunUpdateJobs(const std::vector<Document> &documents)
{
for (const auto &document : documents) {
DocumentProcessor processor = documentProcessors().processor(document);
processor.addJob(createJobRequest(document,
JobRequest::Type::UpdateDocumentAnnotations,
PreferredTranslationUnit::PreviouslyParsed));
processor.process();
}
}
void ClangCodeModelServer::processTimerForVisibleButNotCurrentDocuments()
{
if (documents.dirtyAndVisibleButNotCurrentDocuments().empty()) {
updateVisibleButNotCurrentDocumentsTimer.stop();
} else {
updateVisibleButNotCurrentDocumentsTimer.start(
updateVisibleButNotCurrentDocumentsTimeOutInMs);
}
}
void ClangCodeModelServer::processJobsForDirtyAndVisibleButNotCurrentDocuments()
{
addAndRunUpdateJobs(documents.dirtyAndVisibleButNotCurrentDocuments());
}
void ClangCodeModelServer::processInitialJobsForDocuments(const std::vector<Document> &documents)
@@ -332,6 +367,11 @@ void ClangCodeModelServer::setUpdateDocumentAnnotationsTimeOutInMsForTestsOnly(i
updateDocumentAnnotationsTimeOutInMs = value;
}
void ClangCodeModelServer::setUpdateVisibleButNotCurrentDocumentsTimeOutInMsForTestsOnly(int value)
{
updateVisibleButNotCurrentDocumentsTimeOutInMs = value;
}
DocumentProcessors &ClangCodeModelServer::documentProcessors()
{
if (!documentProcessors_) {