forked from qt-creator/qt-creator
ClangTools: Utilize TaskTree to parse diagnostics from file
This reduces the time the main thread is blocked for reading the diagnostics from the result file. Change-Id: If6cc5671c709cb519b651c2b7ce3e8067e0b5f39 Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
@@ -242,26 +242,15 @@ void ClangToolRunWorker::onDone(const AnalyzeOutputData &output)
|
|||||||
|
|
||||||
qCDebug(LOG) << "onRunnerFinishedWithSuccess:" << output.outputFilePath;
|
qCDebug(LOG) << "onRunnerFinishedWithSuccess:" << output.outputFilePath;
|
||||||
|
|
||||||
QString errorMessage;
|
const Diagnostics diagnostics = output.diagnostics;
|
||||||
const Diagnostics diagnostics = m_tool->read(output.outputFilePath, m_projectFiles,
|
|
||||||
&errorMessage);
|
|
||||||
|
|
||||||
if (!errorMessage.isEmpty()) {
|
if (!m_filesNotAnalyzed.contains(output.fileToAnalyze))
|
||||||
m_filesAnalyzed.remove(output.fileToAnalyze);
|
m_filesAnalyzed.insert(output.fileToAnalyze);
|
||||||
m_filesNotAnalyzed.insert(output.fileToAnalyze);
|
if (!diagnostics.isEmpty()) {
|
||||||
qCDebug(LOG) << "onRunnerFinishedWithSuccess: Error reading log file:" << errorMessage;
|
// do not generate marks when we always analyze open files since marks from that
|
||||||
appendMessage(Tr::tr("Failed to analyze \"%1\": %2")
|
// analysis should be more up to date
|
||||||
.arg(output.fileToAnalyze.toUserOutput(), errorMessage),
|
const bool generateMarks = !m_runSettings.analyzeOpenFiles();
|
||||||
Utils::StdErrFormat);
|
m_tool->onNewDiagnosticsAvailable(diagnostics, generateMarks);
|
||||||
} else {
|
|
||||||
if (!m_filesNotAnalyzed.contains(output.fileToAnalyze))
|
|
||||||
m_filesAnalyzed.insert(output.fileToAnalyze);
|
|
||||||
if (!diagnostics.isEmpty()) {
|
|
||||||
// do not generate marks when we always analyze open files since marks from that
|
|
||||||
// analysis should be more up to date
|
|
||||||
const bool generateMarks = !m_runSettings.analyzeOpenFiles();
|
|
||||||
m_tool->onNewDiagnosticsAvailable(diagnostics, generateMarks);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "clangtoolrunner.h"
|
#include "clangtoolrunner.h"
|
||||||
|
|
||||||
|
#include "clangtoolslogfilereader.h"
|
||||||
#include "clangtoolstr.h"
|
#include "clangtoolstr.h"
|
||||||
#include "clangtoolsutils.h"
|
#include "clangtoolsutils.h"
|
||||||
|
|
||||||
@@ -11,6 +12,9 @@
|
|||||||
#include <cppeditor/clangdiagnosticconfigsmodel.h>
|
#include <cppeditor/clangdiagnosticconfigsmodel.h>
|
||||||
#include <cppeditor/cpptoolsreuse.h>
|
#include <cppeditor/cpptoolsreuse.h>
|
||||||
|
|
||||||
|
#include <extensionsystem/pluginmanager.h>
|
||||||
|
|
||||||
|
#include <utils/async.h>
|
||||||
#include <utils/process.h>
|
#include <utils/process.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
#include <utils/temporaryfile.h>
|
#include <utils/temporaryfile.h>
|
||||||
@@ -20,6 +24,7 @@
|
|||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
|
|
||||||
static Q_LOGGING_CATEGORY(LOG, "qtc.clangtools.runner", QtWarningMsg)
|
static Q_LOGGING_CATEGORY(LOG, "qtc.clangtools.runner", QtWarningMsg)
|
||||||
|
|
||||||
using namespace CppEditor;
|
using namespace CppEditor;
|
||||||
@@ -109,6 +114,7 @@ GroupItem clangToolTask(const AnalyzeInputData &input,
|
|||||||
QString name;
|
QString name;
|
||||||
FilePath executable;
|
FilePath executable;
|
||||||
FilePath outputFilePath;
|
FilePath outputFilePath;
|
||||||
|
QString errorMessage;
|
||||||
};
|
};
|
||||||
const TreeStorage<ClangToolStorage> storage;
|
const TreeStorage<ClangToolStorage> storage;
|
||||||
|
|
||||||
@@ -160,9 +166,6 @@ GroupItem clangToolTask(const AnalyzeInputData &input,
|
|||||||
};
|
};
|
||||||
const auto onProcessDone = [=](const Process &process) {
|
const auto onProcessDone = [=](const Process &process) {
|
||||||
qCDebug(LOG).noquote() << "Output:\n" << process.cleanedStdOut();
|
qCDebug(LOG).noquote() << "Output:\n" << process.cleanedStdOut();
|
||||||
if (!outputHandler)
|
|
||||||
return;
|
|
||||||
outputHandler({true, input.unit.file, storage->outputFilePath, input.tool});
|
|
||||||
};
|
};
|
||||||
const auto onProcessError = [=](const Process &process) {
|
const auto onProcessError = [=](const Process &process) {
|
||||||
if (!outputHandler)
|
if (!outputHandler)
|
||||||
@@ -179,15 +182,38 @@ GroupItem clangToolTask(const AnalyzeInputData &input,
|
|||||||
message = Tr::tr("%1 finished with exit code: %2.").arg(data.name).arg(process.exitCode());
|
message = Tr::tr("%1 finished with exit code: %2.").arg(data.name).arg(process.exitCode());
|
||||||
else
|
else
|
||||||
message = Tr::tr("%1 crashed.").arg(data.name);
|
message = Tr::tr("%1 crashed.").arg(data.name);
|
||||||
outputHandler({false, input.unit.file, data.outputFilePath, input.tool, message, details});
|
outputHandler(
|
||||||
|
{false, input.unit.file, data.outputFilePath, {}, input.tool, message, details});
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto onReadSetup = [=](Async<Diagnostics> &data) {
|
||||||
|
data.setConcurrentCallData(&readExportedDiagnostics,
|
||||||
|
storage->outputFilePath,
|
||||||
|
input.diagnosticsFilter,
|
||||||
|
&storage->errorMessage);
|
||||||
|
data.setFutureSynchronizer(ExtensionSystem::PluginManager::futureSynchronizer());
|
||||||
|
};
|
||||||
|
const auto onReadDone = [=](const Async<Diagnostics> &data) {
|
||||||
|
if (!outputHandler)
|
||||||
|
return;
|
||||||
|
outputHandler(
|
||||||
|
{true, input.unit.file, storage->outputFilePath, data.result(), input.tool});
|
||||||
|
};
|
||||||
|
const auto onReadError = [=](const Async<Diagnostics> &) {
|
||||||
|
if (!outputHandler)
|
||||||
|
return;
|
||||||
|
outputHandler(
|
||||||
|
{false, input.unit.file, storage->outputFilePath, {}, input.tool, storage->errorMessage});
|
||||||
};
|
};
|
||||||
|
|
||||||
const Group group {
|
const Group group {
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
onGroupSetup(onSetup),
|
onGroupSetup(onSetup),
|
||||||
Group {
|
Group {
|
||||||
|
sequential,
|
||||||
finishAllAndDone,
|
finishAllAndDone,
|
||||||
ProcessTask(onProcessSetup, onProcessDone, onProcessError)
|
ProcessTask(onProcessSetup, onProcessDone, onProcessError),
|
||||||
|
AsyncTask<Diagnostics>(onReadSetup, onReadDone, onReadError)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return group;
|
return group;
|
||||||
|
@@ -4,6 +4,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "clangfileinfo.h"
|
#include "clangfileinfo.h"
|
||||||
|
#include "clangtoolsdiagnostic.h"
|
||||||
|
#include "clangtoolslogfilereader.h"
|
||||||
#include "clangtoolssettings.h"
|
#include "clangtoolssettings.h"
|
||||||
|
|
||||||
#include <cppeditor/clangdiagnosticconfig.h>
|
#include <cppeditor/clangdiagnosticconfig.h>
|
||||||
@@ -35,6 +37,7 @@ struct AnalyzeInputData
|
|||||||
Utils::Environment environment;
|
Utils::Environment environment;
|
||||||
AnalyzeUnit unit;
|
AnalyzeUnit unit;
|
||||||
QString overlayFilePath = {};
|
QString overlayFilePath = {};
|
||||||
|
AcceptDiagsFromFilePath diagnosticsFilter = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AnalyzeOutputData
|
struct AnalyzeOutputData
|
||||||
@@ -42,6 +45,7 @@ struct AnalyzeOutputData
|
|||||||
bool success = true;
|
bool success = true;
|
||||||
Utils::FilePath fileToAnalyze;
|
Utils::FilePath fileToAnalyze;
|
||||||
Utils::FilePath outputFilePath;
|
Utils::FilePath outputFilePath;
|
||||||
|
Diagnostics diagnostics;
|
||||||
CppEditor::ClangToolType toolType;
|
CppEditor::ClangToolType toolType;
|
||||||
QString errorMessage = {};
|
QString errorMessage = {};
|
||||||
QString errorDetails = {};
|
QString errorDetails = {};
|
||||||
|
@@ -201,8 +201,16 @@ void DocumentClangToolRunner::run()
|
|||||||
if (includeDir.isEmpty() || clangVersion.isEmpty())
|
if (includeDir.isEmpty() || clangVersion.isEmpty())
|
||||||
return;
|
return;
|
||||||
const AnalyzeUnit unit(m_fileInfo, includeDir, clangVersion);
|
const AnalyzeUnit unit(m_fileInfo, includeDir, clangVersion);
|
||||||
const AnalyzeInputData input{tool, runSettings, config, m_temporaryDir.path(), env, unit,
|
auto diagnosticFilter = [mappedPath = vfso().autoSavedFilePath(m_document)](
|
||||||
vfso().overlayFilePath().toString()};
|
const FilePath &path) { return path == mappedPath; };
|
||||||
|
const AnalyzeInputData input{tool,
|
||||||
|
runSettings,
|
||||||
|
config,
|
||||||
|
m_temporaryDir.path(),
|
||||||
|
env,
|
||||||
|
unit,
|
||||||
|
vfso().overlayFilePath().toString(),
|
||||||
|
diagnosticFilter};
|
||||||
const auto setupHandler = [this, executable] {
|
const auto setupHandler = [this, executable] {
|
||||||
return !m_document->isModified() || isVFSOverlaySupported(executable);
|
return !m_document->isModified() || isVFSOverlaySupported(executable);
|
||||||
};
|
};
|
||||||
@@ -234,11 +242,7 @@ void DocumentClangToolRunner::onDone(const AnalyzeOutputData &output)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const FilePath mappedPath = vfso().autoSavedFilePath(m_document);
|
Diagnostics diagnostics = output.diagnostics;
|
||||||
Diagnostics diagnostics = readExportedDiagnostics(
|
|
||||||
output.outputFilePath,
|
|
||||||
[&](const FilePath &path) { return path == mappedPath; });
|
|
||||||
|
|
||||||
for (Diagnostic &diag : diagnostics) {
|
for (Diagnostic &diag : diagnostics) {
|
||||||
updateLocation(diag.location);
|
updateLocation(diag.location);
|
||||||
for (ExplainingStep &explainingStep : diag.explainingSteps) {
|
for (ExplainingStep &explainingStep : diag.explainingSteps) {
|
||||||
|
Reference in New Issue
Block a user