Cppcheck: Add ability to manually run cppcheck

Run cppcheck on selected files from current project via "Analyze"->"Cppcheck...."
Show results in a separate view in the same manner as ClangTools plugin.

Fixes: QTCREATORBUG-21673
Change-Id: Ibcaf4057a387a990f1da59025f15ba58f996953f
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
This commit is contained in:
Sergey Morozov
2019-11-03 23:00:16 +03:00
parent 07490e76de
commit 0aa95576c2
20 changed files with 936 additions and 126 deletions

View File

@@ -23,16 +23,34 @@
**
****************************************************************************/
#include "cppcheckoptions.h"
#include "cppcheckplugin.h"
#include "cppcheckconstants.h"
#include "cppcheckdiagnosticview.h"
#include "cppchecktextmarkmanager.h"
#include "cppchecktool.h"
#include "cppchecktrigger.h"
#include "cppcheckdiagnosticsmodel.h"
#include "cppcheckmanualrundialog.h"
#include <projectexplorer/session.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/project.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/target.h>
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <debugger/analyzer/analyzerconstants.h>
#include <debugger/debuggermainwindow.h>
#include <utils/qtcassert.h>
#include <utils/utilsicons.h>
namespace Cppcheck {
namespace Internal {
class CppcheckPluginPrivate final
class CppcheckPluginPrivate final : public QObject
{
public:
explicit CppcheckPluginPrivate();
@@ -40,13 +58,98 @@ public:
CppcheckTool tool;
CppcheckTrigger trigger;
CppcheckOptionsPage options;
DiagnosticsModel manualRunModel;
CppcheckTool manualRunTool;
Utils::Perspective perspective{Constants::PERSPECTIVE_ID,
tr("Cppcheck", "CppcheckPlugin")};
QAction *manualRunAction;
void startManualRun();
void updateManualRunAction();
};
CppcheckPluginPrivate::CppcheckPluginPrivate() :
tool(marks),
tool(marks, Constants::CHECK_PROGRESS_ID),
trigger(marks, tool),
options(tool, trigger)
options(tool, trigger),
manualRunTool(manualRunModel, Constants::MANUAL_CHECK_PROGRESS_ID)
{
manualRunTool.updateOptions(tool.options());
auto manualRunView = new DiagnosticView;
manualRunView->setModel(&manualRunModel);
perspective.addWindow(manualRunView, Utils::Perspective::SplitVertical, nullptr);
{
// Go to previous diagnostic
auto action = new QAction(this);
action->setEnabled(false);
action->setIcon(Utils::Icons::PREV_TOOLBAR.icon());
action->setToolTip(tr("Go to previous diagnostic."));
connect(action, &QAction::triggered,
manualRunView, &Debugger::DetailedErrorView::goBack);
connect (&manualRunModel, &DiagnosticsModel::hasDataChanged,
action, &QAction::setEnabled);
perspective.addToolBarAction(action);
}
{
// Go to next diagnostic
auto action = new QAction(this);
action->setEnabled(false);
action->setIcon(Utils::Icons::NEXT_TOOLBAR.icon());
action->setToolTip(tr("Go to next diagnostic."));
connect(action, &QAction::triggered,
manualRunView, &Debugger::DetailedErrorView::goNext);
connect (&manualRunModel, &DiagnosticsModel::hasDataChanged,
action, &QAction::setEnabled);
perspective.addToolBarAction(action);
}
{
// Clear data
auto action = new QAction(this);
action->setEnabled(false);
action->setIcon(Utils::Icons::CLEAN_TOOLBAR.icon());
action->setToolTip(tr("Clear"));
connect(action, &QAction::triggered,
&manualRunModel, &DiagnosticsModel::clear);
connect (&manualRunModel, &DiagnosticsModel::hasDataChanged,
action, &QAction::setEnabled);
perspective.addToolBarAction(action);
}
}
void CppcheckPluginPrivate::startManualRun() {
auto project = ProjectExplorer::SessionManager::startupProject();
if (!project)
return;
ManualRunDialog dialog(manualRunTool.options(), project);
if (dialog.exec() == ManualRunDialog::Rejected)
return;
manualRunModel.clear();
const auto files = dialog.filePaths();
if (files.isEmpty())
return;
manualRunTool.setProject(project);
manualRunTool.updateOptions(dialog.options());
manualRunTool.check(files);
perspective.select();
}
void CppcheckPluginPrivate::updateManualRunAction()
{
using namespace ProjectExplorer;
const Project *project = SessionManager::startupProject();
const Target *target = SessionManager::startupTarget();
const Core::Id cxx = ProjectExplorer::Constants::CXX_LANGUAGE_ID;
const bool canRun = target && project->projectLanguages().contains(cxx)
&& ToolChainKitAspect::toolChain(target->kit(), cxx);
manualRunAction->setEnabled(canRun);
}
CppcheckPlugin::CppcheckPlugin() = default;
@@ -60,6 +163,23 @@ bool CppcheckPlugin::initialize(const QStringList &arguments, QString *errorStri
d.reset(new CppcheckPluginPrivate);
using namespace Core;
ActionContainer *menu = ActionManager::actionContainer(Debugger::Constants::M_DEBUG_ANALYZER);
{
auto action = new QAction(tr("Cppcheck..."), this);
menu->addAction(ActionManager::registerAction(action, Constants::MANUAL_RUN_ACTION),
Debugger::Constants::G_ANALYZER_TOOLS);
connect(action, &QAction::triggered,
d.get(), &CppcheckPluginPrivate::startManualRun);
d->manualRunAction = action;
}
using ProjectExplorer::ProjectExplorerPlugin;
connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::updateRunActions,
d.get(), &CppcheckPluginPrivate::updateManualRunAction);
d->updateManualRunAction();
return true;
}