Clang: Avoid waiting plugin side if (re)parse fails

If a parse or reparse operation fails, the corresponding translation
unit is "not intact" anymore and further job requests for that
translation unit will be silently discarded without notifying the
plugin. This is especially problematic when the plugin expects/waits
(for) a certain message.

A parse/reparse can fail due to e.g. an invalid commandline or an
internal crash.

In such a case, ensure to send some dummy results.

Task-number: QTCREATORBUG-18864
Change-Id: Ida9b8066fd55e64027a9b0d8bd5cf365b16a7356
Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Nikolai Kosjar
2017-09-07 16:28:44 +02:00
parent d85e9bbe2f
commit f2e5e22009
5 changed files with 114 additions and 3 deletions

View File

@@ -53,6 +53,19 @@ bool JobQueue::add(const JobRequest &job)
return false;
}
if (!m_documents.hasDocument(job.filePath, job.projectPartId)) {
qCDebug(jobsLog) << "Not adding / cancelling due to already closed document:" << job;
cancelJobRequest(job);
return false;
}
const Document document = m_documents.document(job.filePath, job.projectPartId);
if (!document.isIntact()) {
qCDebug(jobsLog) << "Not adding / cancelling due not intact document:" << job;
cancelJobRequest(job);
return false;
}
qCDebug(jobsLog) << "Adding" << job;
m_queue.append(job);
@@ -90,7 +103,7 @@ void JobQueue::removeExpiredRequests()
m_queue = cleanedRequests;
}
bool JobQueue::isJobRequestExpired(const JobRequest &jobRequest) const
bool JobQueue::isJobRequestExpired(const JobRequest &jobRequest)
{
const JobRequest::ExpirationReasons expirationReasons = jobRequest.expirationReasons;
const UnsavedFiles unsavedFiles = m_documents.unsavedFiles();
@@ -120,7 +133,8 @@ bool JobQueue::isJobRequestExpired(const JobRequest &jobRequest) const
const Document document
= m_documents.document(jobRequest.filePath, jobRequest.projectPartId);
if (!document.isIntact()) {
qCDebug(jobsLog) << "Removing due to not intact translation unit:" << jobRequest;
qCDebug(jobsLog) << "Removing/Cancelling due to not intact document:" << jobRequest;
cancelJobRequest(jobRequest);
return true;
}
@@ -174,6 +188,12 @@ void JobQueue::prioritizeRequests()
std::stable_sort(m_queue.begin(), m_queue.end(), lessThan);
}
void JobQueue::cancelJobRequest(const JobRequest &jobRequest)
{
if (m_cancelJobRequest)
m_cancelJobRequest(jobRequest);
}
static bool passesPreconditions(const JobRequest &request, const Document &document)
{
using Condition = JobRequest::Condition;
@@ -280,6 +300,11 @@ void JobQueue::setIsJobRunningForJobRequestHandler(
m_isJobRunningForJobRequestHandler = isJobRunningHandler;
}
void JobQueue::setCancelJobRequest(const JobQueue::CancelJobRequest &cancelJobRequest)
{
m_cancelJobRequest = cancelJobRequest;
}
JobRequests &JobQueue::queue()
{
return m_queue;