forked from qt-creator/qt-creator
ClangTools: Generalize run control for multiple runners
No functional change at this point. Change-Id: I537f9d8c9eed0b48056918809358a0a179b42eaa Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -45,18 +45,23 @@ ClangTidyClazyRunControl::ClangTidyClazyRunControl(
|
|||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<RunnerCreator> ClangTidyClazyRunControl::runnerCreators()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
[this]() { return createRunner(); }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
ClangToolRunner *ClangTidyClazyRunControl::createRunner()
|
ClangToolRunner *ClangTidyClazyRunControl::createRunner()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!m_clangExecutable.isEmpty(), return nullptr);
|
|
||||||
|
|
||||||
auto runner = new ClangTidyClazyRunner(m_diagnosticConfig,
|
auto runner = new ClangTidyClazyRunner(m_diagnosticConfig,
|
||||||
m_clangExecutable,
|
m_clangExecutable,
|
||||||
m_temporaryDir.path(),
|
m_temporaryDir.path(),
|
||||||
m_environment,
|
m_environment,
|
||||||
this);
|
this);
|
||||||
connect(runner, &ClangTidyClazyRunner::finishedWithSuccess,
|
connect(runner, &ClangToolRunner::finishedWithSuccess,
|
||||||
this, &ClangTidyClazyRunControl::onRunnerFinishedWithSuccess);
|
this, &ClangTidyClazyRunControl::onRunnerFinishedWithSuccess);
|
||||||
connect(runner, &ClangTidyClazyRunner::finishedWithFailure,
|
connect(runner, &ClangToolRunner::finishedWithFailure,
|
||||||
this, &ClangTidyClazyRunControl::onRunnerFinishedWithFailure);
|
this, &ClangTidyClazyRunControl::onRunnerFinishedWithFailure);
|
||||||
return runner;
|
return runner;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,9 +43,12 @@ public:
|
|||||||
const FileInfos &fileInfos);
|
const FileInfos &fileInfos);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ClangToolRunner *createRunner() final;
|
QList<RunnerCreator> runnerCreators() final;
|
||||||
ClangTool *tool() final;
|
ClangTool *tool() final;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ClangToolRunner *createRunner();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CppTools::ClangDiagnosticConfig m_diagnosticConfig;
|
CppTools::ClangDiagnosticConfig m_diagnosticConfig;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -319,10 +319,15 @@ void ClangToolRunControl::start()
|
|||||||
// Collect files
|
// Collect files
|
||||||
const AnalyzeUnits unitsToProcess = unitsToAnalyze();
|
const AnalyzeUnits unitsToProcess = unitsToAnalyze();
|
||||||
qCDebug(LOG) << "Files to process:" << unitsToProcess;
|
qCDebug(LOG) << "Files to process:" << unitsToProcess;
|
||||||
m_unitsToProcess = unitsToProcess;
|
|
||||||
m_initialFilesToProcessSize = m_unitsToProcess.count();
|
m_queue.clear();
|
||||||
m_filesAnalyzed = 0;
|
for (const AnalyzeUnit &unit : unitsToProcess) {
|
||||||
m_filesNotAnalyzed = 0;
|
for (auto creator : runnerCreators())
|
||||||
|
m_queue << QueueItem{unit, creator};
|
||||||
|
}
|
||||||
|
m_initialQueueSize = m_queue.count();
|
||||||
|
m_filesAnalyzed.clear();
|
||||||
|
m_filesNotAnalyzed.clear();
|
||||||
|
|
||||||
// Set up progress information
|
// Set up progress information
|
||||||
using namespace Core;
|
using namespace Core;
|
||||||
@@ -333,7 +338,7 @@ void ClangToolRunControl::start()
|
|||||||
futureProgress->setKeepOnFinish(FutureProgress::HideOnFinish);
|
futureProgress->setKeepOnFinish(FutureProgress::HideOnFinish);
|
||||||
connect(futureProgress, &FutureProgress::canceled,
|
connect(futureProgress, &FutureProgress::canceled,
|
||||||
this, &ClangToolRunControl::onProgressCanceled);
|
this, &ClangToolRunControl::onProgressCanceled);
|
||||||
m_progress.setProgressRange(0, m_initialFilesToProcessSize);
|
m_progress.setProgressRange(0, m_initialQueueSize);
|
||||||
m_progress.reportStarted();
|
m_progress.reportStarted();
|
||||||
|
|
||||||
// Start process(es)
|
// Start process(es)
|
||||||
@@ -343,14 +348,14 @@ void ClangToolRunControl::start()
|
|||||||
QTC_ASSERT(parallelRuns >= 1, reportFailure(); return);
|
QTC_ASSERT(parallelRuns >= 1, reportFailure(); return);
|
||||||
m_success = true;
|
m_success = true;
|
||||||
|
|
||||||
if (m_unitsToProcess.isEmpty()) {
|
if (m_queue.isEmpty()) {
|
||||||
finalize();
|
finalize();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reportStarted();
|
reportStarted();
|
||||||
|
|
||||||
while (m_runners.size() < parallelRuns && !m_unitsToProcess.isEmpty())
|
while (m_runners.size() < parallelRuns && !m_queue.isEmpty())
|
||||||
analyzeNextFile();
|
analyzeNextFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,7 +367,7 @@ void ClangToolRunControl::stop()
|
|||||||
}
|
}
|
||||||
m_projectFiles.clear();
|
m_projectFiles.clear();
|
||||||
m_runners.clear();
|
m_runners.clear();
|
||||||
m_unitsToProcess.clear();
|
m_queue.clear();
|
||||||
m_progress.reportFinished();
|
m_progress.reportFinished();
|
||||||
|
|
||||||
reportStopped();
|
reportStopped();
|
||||||
@@ -373,16 +378,17 @@ void ClangToolRunControl::analyzeNextFile()
|
|||||||
if (m_progress.isFinished())
|
if (m_progress.isFinished())
|
||||||
return; // The previous call already reported that we are finished.
|
return; // The previous call already reported that we are finished.
|
||||||
|
|
||||||
if (m_unitsToProcess.isEmpty()) {
|
if (m_queue.isEmpty()) {
|
||||||
if (m_runners.isEmpty())
|
if (m_runners.isEmpty())
|
||||||
finalize();
|
finalize();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AnalyzeUnit unit = m_unitsToProcess.takeFirst();
|
const QueueItem queueItem = m_queue.takeFirst();
|
||||||
|
const AnalyzeUnit unit = queueItem.unit;
|
||||||
qCDebug(LOG) << "analyzeNextFile:" << unit.file;
|
qCDebug(LOG) << "analyzeNextFile:" << unit.file;
|
||||||
|
|
||||||
ClangToolRunner *runner = createRunner();
|
ClangToolRunner *runner = queueItem.runnerCreator();
|
||||||
m_runners.insert(runner);
|
m_runners.insert(runner);
|
||||||
QTC_ASSERT(runner->run(unit.file, unit.arguments), return);
|
QTC_ASSERT(runner->run(unit.file, unit.arguments), return);
|
||||||
|
|
||||||
@@ -403,12 +409,15 @@ void ClangToolRunControl::onRunnerFinishedWithSuccess(const QString &filePath)
|
|||||||
QFile::remove(logFilePath); // Clean-up.
|
QFile::remove(logFilePath); // Clean-up.
|
||||||
|
|
||||||
if (!errorMessage.isEmpty()) {
|
if (!errorMessage.isEmpty()) {
|
||||||
|
m_filesAnalyzed.remove(filePath);
|
||||||
|
m_filesNotAnalyzed.insert(filePath);
|
||||||
qCDebug(LOG) << "onRunnerFinishedWithSuccess: Error reading log file:" << errorMessage;
|
qCDebug(LOG) << "onRunnerFinishedWithSuccess: Error reading log file:" << errorMessage;
|
||||||
const QString filePath = qobject_cast<ClangToolRunner *>(sender())->filePath();
|
const QString filePath = qobject_cast<ClangToolRunner *>(sender())->filePath();
|
||||||
appendMessage(tr("Failed to analyze \"%1\": %2").arg(filePath, errorMessage),
|
appendMessage(tr("Failed to analyze \"%1\": %2").arg(filePath, errorMessage),
|
||||||
Utils::StdErrFormat);
|
Utils::StdErrFormat);
|
||||||
} else {
|
} else {
|
||||||
++m_filesAnalyzed;
|
if (!m_filesNotAnalyzed.contains(filePath))
|
||||||
|
m_filesAnalyzed.insert(filePath);
|
||||||
if (!diagnostics.isEmpty())
|
if (!diagnostics.isEmpty())
|
||||||
tool()->onNewDiagnosticsAvailable(diagnostics);
|
tool()->onNewDiagnosticsAvailable(diagnostics);
|
||||||
}
|
}
|
||||||
@@ -429,10 +438,11 @@ void ClangToolRunControl::onRunnerFinishedWithFailure(const QString &errorMessag
|
|||||||
// Even in the error case the log file was created, so clean it up here, too.
|
// Even in the error case the log file was created, so clean it up here, too.
|
||||||
QFile::remove(logFilePath);
|
QFile::remove(logFilePath);
|
||||||
|
|
||||||
const QString message = tr("Failed to analyze \"%1\": %2").arg(filePath, errorMessage);
|
m_filesAnalyzed.remove(filePath);
|
||||||
|
m_filesNotAnalyzed.insert(filePath);
|
||||||
++m_filesNotAnalyzed;
|
|
||||||
m_success = false;
|
m_success = false;
|
||||||
|
|
||||||
|
const QString message = tr("Failed to analyze \"%1\": %2").arg(filePath, errorMessage);
|
||||||
appendMessage(message, Utils::StdErrFormat);
|
appendMessage(message, Utils::StdErrFormat);
|
||||||
appendMessage(errorDetails, Utils::StdErrFormat);
|
appendMessage(errorDetails, Utils::StdErrFormat);
|
||||||
TaskHub::addTask(Task::Error, message, Debugger::Constants::ANALYZERTASK_ID);
|
TaskHub::addTask(Task::Error, message, Debugger::Constants::ANALYZERTASK_ID);
|
||||||
@@ -455,7 +465,7 @@ void ClangToolRunControl::onProgressCanceled()
|
|||||||
|
|
||||||
void ClangToolRunControl::updateProgressValue()
|
void ClangToolRunControl::updateProgressValue()
|
||||||
{
|
{
|
||||||
m_progress.setProgressValue(m_initialFilesToProcessSize - m_unitsToProcess.size());
|
m_progress.setProgressValue(m_initialQueueSize - m_queue.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangToolRunControl::finalize()
|
void ClangToolRunControl::finalize()
|
||||||
@@ -463,10 +473,12 @@ void ClangToolRunControl::finalize()
|
|||||||
const QString toolName = tool()->name();
|
const QString toolName = tool()->name();
|
||||||
appendMessage(tr("%1 finished: "
|
appendMessage(tr("%1 finished: "
|
||||||
"Processed %2 files successfully, %3 failed.")
|
"Processed %2 files successfully, %3 failed.")
|
||||||
.arg(toolName).arg(m_filesAnalyzed).arg(m_filesNotAnalyzed),
|
.arg(toolName)
|
||||||
|
.arg(m_filesAnalyzed.size())
|
||||||
|
.arg(m_filesNotAnalyzed.size()),
|
||||||
Utils::NormalMessageFormat);
|
Utils::NormalMessageFormat);
|
||||||
|
|
||||||
if (m_filesNotAnalyzed != 0) {
|
if (m_filesNotAnalyzed.size() != 0) {
|
||||||
QString msg = tr("%1: Not all files could be analyzed.").arg(toolName);
|
QString msg = tr("%1: Not all files could be analyzed.").arg(toolName);
|
||||||
TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID);
|
TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID);
|
||||||
if (m_target && !m_target->activeBuildConfiguration()->buildDirectory().exists()
|
if (m_target && !m_target->activeBuildConfiguration()->buildDirectory().exists()
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include <utils/temporarydirectory.h>
|
#include <utils/temporarydirectory.h>
|
||||||
|
|
||||||
#include <QFutureInterface>
|
#include <QFutureInterface>
|
||||||
|
#include <QSet>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
|
||||||
namespace ClangTools {
|
namespace ClangTools {
|
||||||
@@ -40,7 +41,6 @@ namespace Internal {
|
|||||||
|
|
||||||
class ClangTool;
|
class ClangTool;
|
||||||
class ClangToolRunner;
|
class ClangToolRunner;
|
||||||
class Diagnostic;
|
|
||||||
class ProjectBuilder;
|
class ProjectBuilder;
|
||||||
|
|
||||||
struct AnalyzeUnit {
|
struct AnalyzeUnit {
|
||||||
@@ -52,6 +52,14 @@ struct AnalyzeUnit {
|
|||||||
};
|
};
|
||||||
using AnalyzeUnits = QList<AnalyzeUnit>;
|
using AnalyzeUnits = QList<AnalyzeUnit>;
|
||||||
|
|
||||||
|
using RunnerCreator = std::function<ClangToolRunner*()>;
|
||||||
|
|
||||||
|
struct QueueItem {
|
||||||
|
AnalyzeUnit unit;
|
||||||
|
RunnerCreator runnerCreator;
|
||||||
|
};
|
||||||
|
using QueueItems = QList<QueueItem>;
|
||||||
|
|
||||||
class ClangToolRunControl : public ProjectExplorer::RunWorker
|
class ClangToolRunControl : public ProjectExplorer::RunWorker
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -68,7 +76,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
virtual ClangToolRunner *createRunner() = 0;
|
virtual QList<RunnerCreator> runnerCreators() = 0;
|
||||||
|
|
||||||
void onRunnerFinishedWithSuccess(const QString &filePath);
|
void onRunnerFinishedWithSuccess(const QString &filePath);
|
||||||
void onRunnerFinishedWithFailure(const QString &errorMessage, const QString &errorDetails);
|
void onRunnerFinishedWithFailure(const QString &errorMessage, const QString &errorDetails);
|
||||||
@@ -103,12 +111,12 @@ private:
|
|||||||
Core::Id m_toolChainType;
|
Core::Id m_toolChainType;
|
||||||
|
|
||||||
QFutureInterface<void> m_progress;
|
QFutureInterface<void> m_progress;
|
||||||
AnalyzeUnits m_unitsToProcess;
|
QueueItems m_queue;
|
||||||
QSet<Utils::FilePath> m_projectFiles;
|
QSet<Utils::FilePath> m_projectFiles;
|
||||||
QSet<ClangToolRunner *> m_runners;
|
QSet<ClangToolRunner *> m_runners;
|
||||||
int m_initialFilesToProcessSize = 0;
|
int m_initialQueueSize = 0;
|
||||||
int m_filesAnalyzed = 0;
|
QSet<QString> m_filesAnalyzed;
|
||||||
int m_filesNotAnalyzed = 0;
|
QSet<QString> m_filesNotAnalyzed;
|
||||||
bool m_success = false;
|
bool m_success = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user