forked from qt-creator/qt-creator
ClangStaticAnalyzer: Avoid use of DummyRunConfigurations
This moves the explicit build step into a dependent runWorker, making the whole setup more aligned with a normal tool run. Change-Id: Icd01b2e82f7f95774434d2ede04d08a5311b64e7 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io> Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
This commit is contained in:
@@ -130,21 +130,6 @@ bool ClangStaticAnalyzerPlugin::initialize(const QStringList &arguments, QString
|
|||||||
addAutoReleasedObject(new ClangStaticAnalyzerTool);
|
addAutoReleasedObject(new ClangStaticAnalyzerTool);
|
||||||
addAutoReleasedObject(new ClangStaticAnalyzerOptionsPage);
|
addAutoReleasedObject(new ClangStaticAnalyzerOptionsPage);
|
||||||
|
|
||||||
auto constraint = [](RunConfiguration *runConfiguration) {
|
|
||||||
Target *target = runConfiguration->target();
|
|
||||||
QTC_ASSERT(target, return false);
|
|
||||||
|
|
||||||
Project *project = target->project();
|
|
||||||
QTC_ASSERT(project, return false);
|
|
||||||
|
|
||||||
const Core::Id cxx = ProjectExplorer::Constants::CXX_LANGUAGE_ID;
|
|
||||||
return project->projectLanguages().contains(cxx)
|
|
||||||
&& ToolChainKitInformation::toolChain(target->kit(), cxx);
|
|
||||||
};
|
|
||||||
|
|
||||||
RunControl::registerWorker<ClangStaticAnalyzerToolRunner>
|
|
||||||
(Constants::CLANGSTATICANALYZER_RUN_MODE, constraint, /*priority*/ -1);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -35,6 +35,7 @@
|
|||||||
|
|
||||||
#include <clangcodemodel/clangutils.h>
|
#include <clangcodemodel/clangutils.h>
|
||||||
|
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/progressmanager/futureprogress.h>
|
#include <coreplugin/progressmanager/futureprogress.h>
|
||||||
#include <coreplugin/progressmanager/progressmanager.h>
|
#include <coreplugin/progressmanager/progressmanager.h>
|
||||||
|
|
||||||
@@ -46,8 +47,10 @@
|
|||||||
|
|
||||||
#include <projectexplorer/abi.h>
|
#include <projectexplorer/abi.h>
|
||||||
#include <projectexplorer/buildconfiguration.h>
|
#include <projectexplorer/buildconfiguration.h>
|
||||||
|
#include <projectexplorer/buildmanager.h>
|
||||||
#include <projectexplorer/kitinformation.h>
|
#include <projectexplorer/kitinformation.h>
|
||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/project.h>
|
||||||
|
#include <projectexplorer/projectexplorer.h>
|
||||||
#include <projectexplorer/projectexplorericons.h>
|
#include <projectexplorer/projectexplorericons.h>
|
||||||
#include <projectexplorer/runconfiguration.h>
|
#include <projectexplorer/runconfiguration.h>
|
||||||
#include <projectexplorer/target.h>
|
#include <projectexplorer/target.h>
|
||||||
@@ -55,6 +58,7 @@
|
|||||||
#include <projectexplorer/toolchain.h>
|
#include <projectexplorer/toolchain.h>
|
||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
|
#include <utils/checkablemessagebox.h>
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
#include <utils/temporarydirectory.h>
|
#include <utils/temporarydirectory.h>
|
||||||
|
|
||||||
@@ -63,71 +67,74 @@
|
|||||||
|
|
||||||
using namespace CppTools;
|
using namespace CppTools;
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
static Q_LOGGING_CATEGORY(LOG, "qtc.clangstaticanalyzer.runcontrol")
|
static Q_LOGGING_CATEGORY(LOG, "qtc.clangstaticanalyzer.runcontrol")
|
||||||
|
|
||||||
namespace ClangStaticAnalyzer {
|
namespace ClangStaticAnalyzer {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
ClangStaticAnalyzerToolRunner::ClangStaticAnalyzerToolRunner(RunControl *runControl)
|
class ProjectBuilder : public RunWorker
|
||||||
: RunWorker(runControl)
|
|
||||||
{
|
{
|
||||||
setDisplayName("ClangStaticAnalyzerRunner");
|
public:
|
||||||
runControl->setDisplayName(tr("Clang Static Analyzer"));
|
ProjectBuilder(RunControl *runControl, Project *project)
|
||||||
runControl->setIcon(ProjectExplorer::Icons::ANALYZER_START_SMALL_TOOLBAR);
|
: RunWorker(runControl), m_project(project)
|
||||||
setSupportsReRunning(false);
|
{
|
||||||
|
setDisplayName("ProjectBuilder");
|
||||||
RunConfiguration *runConfiguration = runControl->runConfiguration();
|
|
||||||
auto tool = ClangStaticAnalyzerTool::instance();
|
|
||||||
tool->stopAction()->disconnect();
|
|
||||||
connect(tool->stopAction(), &QAction::triggered, runControl, [&] {
|
|
||||||
initiateStop();
|
|
||||||
appendMessage(tr("Clang Static Analyzer stopped by user."),
|
|
||||||
Utils::NormalMessageFormat);
|
|
||||||
});
|
|
||||||
tool->handleWorkerStart(this);
|
|
||||||
|
|
||||||
ProjectInfo projectInfoBeforeBuild = tool->projectInfoBeforeBuild();
|
|
||||||
QTC_ASSERT(projectInfoBeforeBuild.isValid(), return);
|
|
||||||
|
|
||||||
QTC_ASSERT(runConfiguration, return);
|
|
||||||
Target * const target = runConfiguration->target();
|
|
||||||
QTC_ASSERT(target, return);
|
|
||||||
Project * const project = target->project();
|
|
||||||
QTC_ASSERT(project, return);
|
|
||||||
|
|
||||||
// so pass on the updated Project Info unless no configuration change
|
|
||||||
// (defines/includes/files) happened.
|
|
||||||
const CppTools::ProjectInfo projectInfoAfterBuild
|
|
||||||
= CppTools::CppModelManager::instance()->projectInfo(project);
|
|
||||||
|
|
||||||
if (projectInfoAfterBuild.configurationOrFilesChanged(projectInfoBeforeBuild)) {
|
|
||||||
// If it's more than a release/debug build configuration change, e.g.
|
|
||||||
// a version control checkout, files might be not valid C++ anymore
|
|
||||||
// or even gone, so better stop here.
|
|
||||||
|
|
||||||
tool->resetCursorAndProjectInfoBeforeBuild();
|
|
||||||
reportFailure(tr(
|
|
||||||
"The project configuration changed since the start of the Clang Static Analyzer. "
|
|
||||||
"Please re-run with current configuration."));
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some projects provides CompilerCallData once a build is finished,
|
bool success() const { return m_success; }
|
||||||
QTC_ASSERT(!projectInfoAfterBuild.configurationOrFilesChanged(projectInfoBeforeBuild),
|
|
||||||
return);
|
|
||||||
|
|
||||||
m_projectInfo = projectInfoAfterBuild;
|
private:
|
||||||
|
void start() final
|
||||||
|
{
|
||||||
|
Target *target = m_project->activeTarget();
|
||||||
|
QTC_ASSERT(target, reportFailure(); return);
|
||||||
|
|
||||||
BuildConfiguration *buildConfiguration = target->activeBuildConfiguration();
|
BuildConfiguration::BuildType buildType = BuildConfiguration::Unknown;
|
||||||
QTC_ASSERT(buildConfiguration, return);
|
if (const BuildConfiguration *buildConfig = target->activeBuildConfiguration())
|
||||||
m_environment = buildConfiguration->environment();
|
buildType = buildConfig->buildType();
|
||||||
|
|
||||||
ToolChain *toolChain = ToolChainKitInformation::toolChain(target->kit(), ProjectExplorer::Constants::CXX_LANGUAGE_ID);
|
if (buildType == BuildConfiguration::Release) {
|
||||||
QTC_ASSERT(toolChain, return);
|
const QString wrongMode = ClangStaticAnalyzerTool::tr("Release");
|
||||||
m_targetTriple = toolChain->originalTargetTriple();
|
const QString toolName = ClangStaticAnalyzerTool::tr("Clang Static Analyzer");
|
||||||
m_toolChainType = toolChain->typeId();
|
const QString title = ClangStaticAnalyzerTool::tr("Run %1 in %2 Mode?").arg(toolName)
|
||||||
}
|
.arg(wrongMode);
|
||||||
|
const QString message = ClangStaticAnalyzerTool::tr(
|
||||||
|
"<html><head/><body>"
|
||||||
|
"<p>You are trying to run the tool \"%1\" on an application in %2 mode. The tool is "
|
||||||
|
"designed to be used in Debug mode since enabled assertions can reduce the number of "
|
||||||
|
"false positives.</p>"
|
||||||
|
"<p>Do you want to continue and run the tool in %2 mode?</p>"
|
||||||
|
"</body></html>")
|
||||||
|
.arg(toolName).arg(wrongMode);
|
||||||
|
if (CheckableMessageBox::doNotAskAgainQuestion(Core::ICore::mainWindow(),
|
||||||
|
title, message, Core::ICore::settings(),
|
||||||
|
"ClangStaticAnalyzerCorrectModeWarning") != QDialogButtonBox::Yes)
|
||||||
|
{
|
||||||
|
reportFailure();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(BuildManager::instance(), &BuildManager::buildQueueFinished,
|
||||||
|
this, &ProjectBuilder::onBuildFinished, Qt::QueuedConnection);
|
||||||
|
|
||||||
|
ProjectExplorerPlugin::buildProject(m_project);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onBuildFinished(bool success)
|
||||||
|
{
|
||||||
|
disconnect(BuildManager::instance(), &BuildManager::buildQueueFinished,
|
||||||
|
this, &ProjectBuilder::onBuildFinished);
|
||||||
|
m_success = success;
|
||||||
|
reportDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QPointer<Project> m_project;
|
||||||
|
bool m_success = false;
|
||||||
|
};
|
||||||
|
|
||||||
static void prependWordWidthArgumentIfNotIncluded(QStringList *arguments,
|
static void prependWordWidthArgumentIfNotIncluded(QStringList *arguments,
|
||||||
ProjectPart::ToolChainWordWidth wordWidth)
|
ProjectPart::ToolChainWordWidth wordWidth)
|
||||||
@@ -390,16 +397,47 @@ static QDebug operator<<(QDebug debug, const AnalyzeUnits &analyzeUnits)
|
|||||||
return debug;
|
return debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClangStaticAnalyzerToolRunner::ClangStaticAnalyzerToolRunner(RunControl *runControl, Target *target)
|
||||||
|
: RunWorker(runControl), m_target(target)
|
||||||
|
{
|
||||||
|
setDisplayName("ClangStaticAnalyzerRunner");
|
||||||
|
setSupportsReRunning(false);
|
||||||
|
|
||||||
|
m_projectBuilder = new ProjectBuilder(runControl, target->project());
|
||||||
|
addStartDependency(m_projectBuilder);
|
||||||
|
|
||||||
|
m_projectInfoBeforeBuild = CppTools::CppModelManager::instance()->projectInfo(target->project());
|
||||||
|
|
||||||
|
BuildConfiguration *buildConfiguration = target->activeBuildConfiguration();
|
||||||
|
QTC_ASSERT(buildConfiguration, return);
|
||||||
|
m_environment = buildConfiguration->environment();
|
||||||
|
|
||||||
|
ToolChain *toolChain = ToolChainKitInformation::toolChain(target->kit(), ProjectExplorer::Constants::CXX_LANGUAGE_ID);
|
||||||
|
QTC_ASSERT(toolChain, return);
|
||||||
|
m_targetTriple = toolChain->originalTargetTriple();
|
||||||
|
m_toolChainType = toolChain->typeId();
|
||||||
|
}
|
||||||
|
|
||||||
void ClangStaticAnalyzerToolRunner::start()
|
void ClangStaticAnalyzerToolRunner::start()
|
||||||
{
|
{
|
||||||
m_success = false;
|
m_success = m_projectBuilder->success();
|
||||||
ClangStaticAnalyzerTool::instance()->onEngineIsStarting();
|
if (!m_success) {
|
||||||
|
reportFailure();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
connect(runControl(), &RunControl::stopped, this, [this] {
|
m_projectInfo = CppTools::CppModelManager::instance()->projectInfo(m_target->project());
|
||||||
ClangStaticAnalyzerTool::instance()->onEngineFinished(m_success);
|
|
||||||
});
|
// Some projects provides CompilerCallData once a build is finished,
|
||||||
|
if (m_projectInfo.configurationOrFilesChanged(m_projectInfoBeforeBuild)) {
|
||||||
|
// If it's more than a release/debug build configuration change, e.g.
|
||||||
|
// a version control checkout, files might be not valid C++ anymore
|
||||||
|
// or even gone, so better stop here.
|
||||||
|
reportFailure(tr("The project configuration changed since the start of "
|
||||||
|
"the Clang Static Analyzer. Please re-run with current configuration."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QTC_ASSERT(m_projectInfo.isValid(), reportFailure(); return);
|
|
||||||
const Utils::FileName projectFile = m_projectInfo.project()->projectFilePath();
|
const Utils::FileName projectFile = m_projectInfo.project()->projectFilePath();
|
||||||
appendMessage(tr("Running Clang Static Analyzer on %1").arg(projectFile.toUserOutput()),
|
appendMessage(tr("Running Clang Static Analyzer on %1").arg(projectFile.toUserOutput()),
|
||||||
Utils::NormalMessageFormat);
|
Utils::NormalMessageFormat);
|
||||||
@@ -502,7 +540,7 @@ void ClangStaticAnalyzerToolRunner::stop()
|
|||||||
m_runners.clear();
|
m_runners.clear();
|
||||||
m_unitsToProcess.clear();
|
m_unitsToProcess.clear();
|
||||||
m_progress.reportFinished();
|
m_progress.reportFinished();
|
||||||
ClangStaticAnalyzerTool::instance()->onEngineFinished(m_success);
|
//ClangStaticAnalyzerTool::instance()->onEngineFinished(m_success);
|
||||||
reportStopped();
|
reportStopped();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -36,6 +36,7 @@ namespace ClangStaticAnalyzer {
|
|||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class ClangStaticAnalyzerRunner;
|
class ClangStaticAnalyzerRunner;
|
||||||
|
class ProjectBuilder;
|
||||||
class Diagnostic;
|
class Diagnostic;
|
||||||
|
|
||||||
struct AnalyzeUnit {
|
struct AnalyzeUnit {
|
||||||
@@ -52,14 +53,15 @@ class ClangStaticAnalyzerToolRunner : public ProjectExplorer::RunWorker
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ClangStaticAnalyzerToolRunner(ProjectExplorer::RunControl *runControl);
|
ClangStaticAnalyzerToolRunner(ProjectExplorer::RunControl *runControl,
|
||||||
|
ProjectExplorer::Target *target);
|
||||||
void start() override;
|
|
||||||
void stop() override;
|
|
||||||
|
|
||||||
bool success() const { return m_success; } // For testing.
|
bool success() const { return m_success; } // For testing.
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void start() final;
|
||||||
|
void stop() final;
|
||||||
|
|
||||||
AnalyzeUnits sortedUnitsToAnalyze();
|
AnalyzeUnits sortedUnitsToAnalyze();
|
||||||
void analyzeNextFile();
|
void analyzeNextFile();
|
||||||
ClangStaticAnalyzerRunner *createRunner();
|
ClangStaticAnalyzerRunner *createRunner();
|
||||||
@@ -74,6 +76,10 @@ private:
|
|||||||
void finalize();
|
void finalize();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QPointer<ProjectExplorer::Target> m_target;
|
||||||
|
ProjectBuilder *m_projectBuilder;
|
||||||
|
|
||||||
|
CppTools::ProjectInfo m_projectInfoBeforeBuild;
|
||||||
CppTools::ProjectInfo m_projectInfo;
|
CppTools::ProjectInfo m_projectInfo;
|
||||||
QString m_targetTriple;
|
QString m_targetTriple;
|
||||||
Core::Id m_toolChainType;
|
Core::Id m_toolChainType;
|
||||||
|
@@ -36,24 +36,19 @@
|
|||||||
#include <coreplugin/coreconstants.h>
|
#include <coreplugin/coreconstants.h>
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
#include <cpptools/cppmodelmanager.h>
|
|
||||||
|
|
||||||
#include <debugger/analyzer/analyzermanager.h>
|
#include <debugger/analyzer/analyzermanager.h>
|
||||||
|
|
||||||
#include <projectexplorer/buildconfiguration.h>
|
#include <projectexplorer/kitinformation.h>
|
||||||
#include <projectexplorer/projectexplorer.h>
|
#include <projectexplorer/projectexplorer.h>
|
||||||
#include <projectexplorer/session.h>
|
#include <projectexplorer/projectexplorericons.h>
|
||||||
#include <projectexplorer/target.h>
|
#include <projectexplorer/target.h>
|
||||||
|
#include <projectexplorer/session.h>
|
||||||
|
|
||||||
#include <utils/checkablemessagebox.h>
|
|
||||||
#include <utils/fancymainwindow.h>
|
#include <utils/fancymainwindow.h>
|
||||||
#include <utils/utilsicons.h>
|
#include <utils/utilsicons.h>
|
||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QDockWidget>
|
|
||||||
#include <QHBoxLayout>
|
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QListView>
|
|
||||||
#include <QSortFilterProxyModel>
|
#include <QSortFilterProxyModel>
|
||||||
#include <QToolButton>
|
#include <QToolButton>
|
||||||
|
|
||||||
@@ -65,23 +60,6 @@ using namespace Utils;
|
|||||||
namespace ClangStaticAnalyzer {
|
namespace ClangStaticAnalyzer {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class DummyRunConfiguration : public RunConfiguration
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
DummyRunConfiguration(Target *parent)
|
|
||||||
: RunConfiguration(parent)
|
|
||||||
{
|
|
||||||
initialize("ClangStaticAnalyzer.DummyRunConfig");
|
|
||||||
setDefaultDisplayName(tr("Clang Static Analyzer"));
|
|
||||||
setEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
QWidget *createConfigurationWidget() override { return 0; }
|
|
||||||
};
|
|
||||||
|
|
||||||
static ClangStaticAnalyzerTool *s_instance;
|
static ClangStaticAnalyzerTool *s_instance;
|
||||||
|
|
||||||
ClangStaticAnalyzerTool::ClangStaticAnalyzerTool()
|
ClangStaticAnalyzerTool::ClangStaticAnalyzerTool()
|
||||||
@@ -180,90 +158,43 @@ ClangStaticAnalyzerTool *ClangStaticAnalyzerTool::instance()
|
|||||||
return s_instance;
|
return s_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool dontStartAfterHintForDebugMode(Project *project)
|
|
||||||
{
|
|
||||||
BuildConfiguration::BuildType buildType = BuildConfiguration::Unknown;
|
|
||||||
if (project) {
|
|
||||||
if (const Target *target = project->activeTarget()) {
|
|
||||||
if (const BuildConfiguration *buildConfig = target->activeBuildConfiguration())
|
|
||||||
buildType = buildConfig->buildType();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buildType == BuildConfiguration::Release) {
|
|
||||||
const QString wrongMode = ClangStaticAnalyzerTool::tr("Release");
|
|
||||||
const QString toolName = ClangStaticAnalyzerTool::tr("Clang Static Analyzer");
|
|
||||||
const QString title = ClangStaticAnalyzerTool::tr("Run %1 in %2 Mode?").arg(toolName)
|
|
||||||
.arg(wrongMode);
|
|
||||||
const QString message = ClangStaticAnalyzerTool::tr(
|
|
||||||
"<html><head/><body>"
|
|
||||||
"<p>You are trying to run the tool \"%1\" on an application in %2 mode. The tool is "
|
|
||||||
"designed to be used in Debug mode since enabled assertions can reduce the number of "
|
|
||||||
"false positives.</p>"
|
|
||||||
"<p>Do you want to continue and run the tool in %2 mode?</p>"
|
|
||||||
"</body></html>")
|
|
||||||
.arg(toolName).arg(wrongMode);
|
|
||||||
if (Utils::CheckableMessageBox::doNotAskAgainQuestion(Core::ICore::mainWindow(),
|
|
||||||
title, message, Core::ICore::settings(),
|
|
||||||
QLatin1String("ClangStaticAnalyzerCorrectModeWarning")) != QDialogButtonBox::Yes)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClangStaticAnalyzerTool::handleWorkerStart(RunWorker *runWorker)
|
|
||||||
{
|
|
||||||
RunControl *runControl = runWorker->runControl();
|
|
||||||
Project *project = runControl->project();
|
|
||||||
QTC_ASSERT(project, emit finished(false); return);
|
|
||||||
|
|
||||||
Debugger::selectPerspective(ClangStaticAnalyzerPerspectiveId);
|
|
||||||
m_diagnosticModel->clear();
|
|
||||||
setBusyCursor(true);
|
|
||||||
m_diagnosticFilterModel->setProject(project);
|
|
||||||
m_projectInfoBeforeBuild = CppTools::CppModelManager::instance()->projectInfo(project);
|
|
||||||
QTC_ASSERT(m_projectInfoBeforeBuild.isValid(), emit finished(false); return);
|
|
||||||
m_running = true;
|
|
||||||
handleStateUpdate();
|
|
||||||
|
|
||||||
m_toolBusy = true;
|
|
||||||
updateRunActions();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClangStaticAnalyzerTool::startTool()
|
void ClangStaticAnalyzerTool::startTool()
|
||||||
{
|
{
|
||||||
|
auto runControl = new RunControl(nullptr, Constants::CLANGSTATICANALYZER_RUN_MODE);
|
||||||
|
runControl->setDisplayName(tr("Clang Static Analyzer"));
|
||||||
|
runControl->setIcon(ProjectExplorer::Icons::ANALYZER_START_SMALL_TOOLBAR);
|
||||||
|
|
||||||
Project *project = SessionManager::startupProject();
|
Project *project = SessionManager::startupProject();
|
||||||
QTC_ASSERT(project, return);
|
QTC_ASSERT(project, return);
|
||||||
Target *target = project->activeTarget();
|
|
||||||
QTC_ASSERT(target, return);
|
|
||||||
DummyRunConfiguration *& rc = m_runConfigs[target];
|
|
||||||
if (!rc) {
|
|
||||||
rc = new DummyRunConfiguration(target);
|
|
||||||
connect(project, &Project::aboutToRemoveTarget, this,
|
|
||||||
[this](Target *t) { m_runConfigs.remove(t); });
|
|
||||||
const auto onProjectRemoved = [this](Project *p) {
|
|
||||||
foreach (Target * const t, p->targets())
|
|
||||||
m_runConfigs.remove(t);
|
|
||||||
};
|
|
||||||
connect(SessionManager::instance(), &SessionManager::aboutToRemoveProject, this,
|
|
||||||
onProjectRemoved, Qt::UniqueConnection);
|
|
||||||
}
|
|
||||||
if (dontStartAfterHintForDebugMode(project))
|
|
||||||
return;
|
|
||||||
|
|
||||||
ProjectExplorerPlugin::runRunConfiguration(rc, Constants::CLANGSTATICANALYZER_RUN_MODE);
|
auto clangTool = new ClangStaticAnalyzerToolRunner(runControl, project->activeTarget());
|
||||||
}
|
|
||||||
|
|
||||||
CppTools::ProjectInfo ClangStaticAnalyzerTool::projectInfoBeforeBuild() const
|
m_stopAction->disconnect();
|
||||||
{
|
connect(m_stopAction, &QAction::triggered, runControl, [this, runControl] {
|
||||||
return m_projectInfoBeforeBuild;
|
runControl->appendMessage(tr("Clang Static Analyzer stopped by user."),
|
||||||
}
|
NormalMessageFormat);
|
||||||
|
runControl->initiateStop();
|
||||||
|
});
|
||||||
|
|
||||||
void ClangStaticAnalyzerTool::resetCursorAndProjectInfoBeforeBuild()
|
connect(runControl, &RunControl::stopped, this, [this, clangTool] {
|
||||||
{
|
bool success = clangTool->success();
|
||||||
setBusyCursor(false);
|
setToolBusy(false);
|
||||||
m_projectInfoBeforeBuild = CppTools::ProjectInfo();
|
m_running = false;
|
||||||
|
handleStateUpdate();
|
||||||
|
updateRunActions();
|
||||||
|
emit finished(success);
|
||||||
|
});
|
||||||
|
|
||||||
|
Debugger::selectPerspective(ClangStaticAnalyzerPerspectiveId);
|
||||||
|
|
||||||
|
m_diagnosticModel->clear();
|
||||||
|
setToolBusy(true);
|
||||||
|
m_diagnosticFilterModel->setProject(project);
|
||||||
|
m_running = true;
|
||||||
|
handleStateUpdate();
|
||||||
|
updateRunActions();
|
||||||
|
|
||||||
|
ProjectExplorerPlugin::startRunControl(runControl);
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Diagnostic> ClangStaticAnalyzerTool::diagnostics() const
|
QList<Diagnostic> ClangStaticAnalyzerTool::diagnostics() const
|
||||||
@@ -271,27 +202,12 @@ QList<Diagnostic> ClangStaticAnalyzerTool::diagnostics() const
|
|||||||
return m_diagnosticModel->diagnostics();
|
return m_diagnosticModel->diagnostics();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangStaticAnalyzerTool::onEngineIsStarting()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(m_diagnosticModel, return);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClangStaticAnalyzerTool::onNewDiagnosticsAvailable(const QList<Diagnostic> &diagnostics)
|
void ClangStaticAnalyzerTool::onNewDiagnosticsAvailable(const QList<Diagnostic> &diagnostics)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_diagnosticModel, return);
|
QTC_ASSERT(m_diagnosticModel, return);
|
||||||
m_diagnosticModel->addDiagnostics(diagnostics);
|
m_diagnosticModel->addDiagnostics(diagnostics);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangStaticAnalyzerTool::onEngineFinished(bool success)
|
|
||||||
{
|
|
||||||
resetCursorAndProjectInfoBeforeBuild();
|
|
||||||
m_running = false;
|
|
||||||
handleStateUpdate();
|
|
||||||
emit finished(success);
|
|
||||||
m_toolBusy = false;
|
|
||||||
updateRunActions();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClangStaticAnalyzerTool::updateRunActions()
|
void ClangStaticAnalyzerTool::updateRunActions()
|
||||||
{
|
{
|
||||||
if (m_toolBusy) {
|
if (m_toolBusy) {
|
||||||
@@ -299,19 +215,27 @@ void ClangStaticAnalyzerTool::updateRunActions()
|
|||||||
m_startAction->setToolTip(tr("Clang Static Analyzer is still running."));
|
m_startAction->setToolTip(tr("Clang Static Analyzer is still running."));
|
||||||
m_stopAction->setEnabled(true);
|
m_stopAction->setEnabled(true);
|
||||||
} else {
|
} else {
|
||||||
QString whyNot = tr("Start Clang Static Analyzer.");
|
QString toolTip = tr("Start Clang Static Analyzer.");
|
||||||
bool canRun = ProjectExplorerPlugin::canRunStartupProject(
|
Project *project = SessionManager::startupProject();
|
||||||
Constants::CLANGSTATICANALYZER_RUN_MODE, &whyNot);
|
Target *target = project ? project->activeTarget() : nullptr;
|
||||||
m_startAction->setToolTip(whyNot);
|
const Core::Id cxx = ProjectExplorer::Constants::CXX_LANGUAGE_ID;
|
||||||
|
bool canRun = target && project->projectLanguages().contains(cxx)
|
||||||
|
&& ToolChainKitInformation::toolChain(target->kit(), cxx);
|
||||||
|
if (!canRun)
|
||||||
|
toolTip = tr("This is not C++ project");
|
||||||
|
|
||||||
|
m_startAction->setToolTip(toolTip);
|
||||||
m_startAction->setEnabled(canRun);
|
m_startAction->setEnabled(canRun);
|
||||||
m_stopAction->setEnabled(false);
|
m_stopAction->setEnabled(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void ClangStaticAnalyzerTool::setBusyCursor(bool busy)
|
|
||||||
|
void ClangStaticAnalyzerTool::setToolBusy(bool busy)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_diagnosticView, return);
|
QTC_ASSERT(m_diagnosticView, return);
|
||||||
QCursor cursor(busy ? Qt::BusyCursor : Qt::ArrowCursor);
|
QCursor cursor(busy ? Qt::BusyCursor : Qt::ArrowCursor);
|
||||||
m_diagnosticView->setCursor(cursor);
|
m_diagnosticView->setCursor(cursor);
|
||||||
|
m_toolBusy = busy;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangStaticAnalyzerTool::handleStateUpdate()
|
void ClangStaticAnalyzerTool::handleStateUpdate()
|
||||||
@@ -326,8 +250,12 @@ void ClangStaticAnalyzerTool::handleStateUpdate()
|
|||||||
m_goBack->setEnabled(issuesVisible > 1);
|
m_goBack->setEnabled(issuesVisible > 1);
|
||||||
m_goNext->setEnabled(issuesVisible > 1);
|
m_goNext->setEnabled(issuesVisible > 1);
|
||||||
|
|
||||||
QString message = m_running ? tr("Clang Static Analyzer is running.")
|
QString message;
|
||||||
: tr("Clang Static Analyzer finished.");
|
if (m_running)
|
||||||
|
message = tr("Clang Static Analyzer is running.");
|
||||||
|
else
|
||||||
|
message = tr("Clang Static Analyzer finished.");
|
||||||
|
|
||||||
message += QLatin1Char(' ');
|
message += QLatin1Char(' ');
|
||||||
if (issuesFound == 0) {
|
if (issuesFound == 0) {
|
||||||
message += tr("No issues found.");
|
message += tr("No issues found.");
|
||||||
@@ -340,5 +268,3 @@ void ClangStaticAnalyzerTool::handleStateUpdate()
|
|||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace ClangStaticAnalyzer
|
} // namespace ClangStaticAnalyzer
|
||||||
|
|
||||||
#include "clangstaticanalyzertool.moc"
|
|
||||||
|
@@ -28,8 +28,6 @@
|
|||||||
#include <projectexplorer/runconfiguration.h>
|
#include <projectexplorer/runconfiguration.h>
|
||||||
#include <cpptools/projectinfo.h>
|
#include <cpptools/projectinfo.h>
|
||||||
|
|
||||||
#include <QHash>
|
|
||||||
|
|
||||||
namespace ClangStaticAnalyzer {
|
namespace ClangStaticAnalyzer {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -37,7 +35,6 @@ class ClangStaticAnalyzerDiagnosticFilterModel;
|
|||||||
class ClangStaticAnalyzerDiagnosticModel;
|
class ClangStaticAnalyzerDiagnosticModel;
|
||||||
class ClangStaticAnalyzerDiagnosticView;
|
class ClangStaticAnalyzerDiagnosticView;
|
||||||
class Diagnostic;
|
class Diagnostic;
|
||||||
class DummyRunConfiguration;
|
|
||||||
|
|
||||||
const char ClangStaticAnalyzerPerspectiveId[] = "ClangStaticAnalyzer.Perspective";
|
const char ClangStaticAnalyzerPerspectiveId[] = "ClangStaticAnalyzer.Perspective";
|
||||||
const char ClangStaticAnalyzerDockId[] = "ClangStaticAnalyzer.Dock";
|
const char ClangStaticAnalyzerDockId[] = "ClangStaticAnalyzer.Dock";
|
||||||
@@ -51,32 +48,21 @@ public:
|
|||||||
~ClangStaticAnalyzerTool();
|
~ClangStaticAnalyzerTool();
|
||||||
|
|
||||||
static ClangStaticAnalyzerTool *instance();
|
static ClangStaticAnalyzerTool *instance();
|
||||||
QAction *stopAction() { return m_stopAction; }
|
|
||||||
|
|
||||||
CppTools::ProjectInfo projectInfoBeforeBuild() const;
|
|
||||||
void resetCursorAndProjectInfoBeforeBuild();
|
|
||||||
|
|
||||||
// For testing.
|
// For testing.
|
||||||
QList<Diagnostic> diagnostics() const;
|
QList<Diagnostic> diagnostics() const;
|
||||||
void startTool();
|
void startTool();
|
||||||
|
|
||||||
void handleWorkerStart(ProjectExplorer::RunWorker *runWorker);
|
|
||||||
|
|
||||||
void onEngineIsStarting();
|
|
||||||
void onNewDiagnosticsAvailable(const QList<Diagnostic> &diagnostics);
|
void onNewDiagnosticsAvailable(const QList<Diagnostic> &diagnostics);
|
||||||
void onEngineFinished(bool success);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void finished(bool success); // For testing.
|
void finished(bool success); // For testing.
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setBusyCursor(bool busy);
|
void setToolBusy(bool busy);
|
||||||
void handleStateUpdate();
|
void handleStateUpdate();
|
||||||
void updateRunActions();
|
void updateRunActions();
|
||||||
|
|
||||||
private:
|
|
||||||
CppTools::ProjectInfo m_projectInfoBeforeBuild;
|
|
||||||
|
|
||||||
ClangStaticAnalyzerDiagnosticModel *m_diagnosticModel = nullptr;
|
ClangStaticAnalyzerDiagnosticModel *m_diagnosticModel = nullptr;
|
||||||
ClangStaticAnalyzerDiagnosticFilterModel *m_diagnosticFilterModel = nullptr;
|
ClangStaticAnalyzerDiagnosticFilterModel *m_diagnosticFilterModel = nullptr;
|
||||||
ClangStaticAnalyzerDiagnosticView *m_diagnosticView = nullptr;
|
ClangStaticAnalyzerDiagnosticView *m_diagnosticView = nullptr;
|
||||||
@@ -85,7 +71,6 @@ private:
|
|||||||
QAction *m_stopAction = nullptr;
|
QAction *m_stopAction = nullptr;
|
||||||
QAction *m_goBack = nullptr;
|
QAction *m_goBack = nullptr;
|
||||||
QAction *m_goNext = nullptr;
|
QAction *m_goNext = nullptr;
|
||||||
QHash<ProjectExplorer::Target *, DummyRunConfiguration *> m_runConfigs;
|
|
||||||
bool m_running = false;
|
bool m_running = false;
|
||||||
bool m_toolBusy = false;
|
bool m_toolBusy = false;
|
||||||
};
|
};
|
||||||
|
@@ -616,6 +616,8 @@ public:
|
|||||||
outputFormatter = runConfiguration->createOutputFormatter();
|
outputFormatter = runConfiguration->createOutputFormatter();
|
||||||
device = DeviceKitInformation::device(runConfiguration->target()->kit());
|
device = DeviceKitInformation::device(runConfiguration->target()->kit());
|
||||||
project = runConfiguration->target()->project();
|
project = runConfiguration->target()->project();
|
||||||
|
} else {
|
||||||
|
outputFormatter = new OutputFormatter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user