diff options
author | Nikolai Kosjar <nikolai.kosjar@qt.io> | 2018-05-14 11:40:40 +0200 |
---|---|---|
committer | Nikolai Kosjar <nikolai.kosjar@qt.io> | 2018-05-15 07:26:22 +0000 |
commit | 9b74948a617eb48c2c1131632edba7f96ec052ed (patch) | |
tree | aedcc9f43d51e2b01b4fed6d7f7816bee6d1cfdd /src | |
parent | 2522275b69f14ad0378ddbf42004c0b7104f3d73 (diff) |
ClangTools: Allow selecting diagnostic config for project
When starting the Clazy/Tidy tool, allow to select the diagnostic
configuration for the run.
As a side effect, fix a race condition where the runner could end up
with no diagnostic config (removed during run) - copy the diagnostic
config instead of referencing/querying it by the id.
Change-Id: Iedafa8f31a3bbd233d65818fe8de16add1e4d443
Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
Diffstat (limited to 'src')
12 files changed, 206 insertions, 25 deletions
diff --git a/src/plugins/clangtools/clangselectablefilesdialog.cpp b/src/plugins/clangtools/clangselectablefilesdialog.cpp index b6544efb15..4dab13a726 100644 --- a/src/plugins/clangtools/clangselectablefilesdialog.cpp +++ b/src/plugins/clangtools/clangselectablefilesdialog.cpp @@ -27,6 +27,7 @@ #include "ui_clangselectablefilesdialog.h" #include "clangtoolsprojectsettings.h" +#include "clangtoolssettings.h" #include "clangtoolsutils.h" #include <cpptools/compileroptionsbuilder.h> @@ -262,6 +263,8 @@ private: } }; +enum { GlobalSettings , CustomSettings }; + SelectableFilesDialog::SelectableFilesDialog(const ProjectInfo &projectInfo, const FileInfos &allFileInfos) : QDialog(nullptr) @@ -278,8 +281,42 @@ SelectableFilesDialog::SelectableFilesDialog(const ProjectInfo &projectInfo, m_ui->buttons->setStandardButtons(QDialogButtonBox::Cancel); m_ui->buttons->addButton(m_analyzeButton, QDialogButtonBox::AcceptRole); - // Restore selection + m_ui->diagnosticConfigsSelectionWidget->showLabel(false); + ClangToolsProjectSettings *settings = ClangToolsProjectSettingsManager::getSettings(m_project); + + Core::Id diagnosticConfig; + if (settings->useGlobalSettings()) { + m_ui->globalOrCustom->setCurrentIndex(GlobalSettings); + m_ui->diagnosticConfigsSelectionWidget->setEnabled(false); + diagnosticConfig = ClangToolsSettings::instance()->savedDiagnosticConfigId(); + } else { + m_ui->globalOrCustom->setCurrentIndex(CustomSettings); + m_ui->diagnosticConfigsSelectionWidget->setEnabled(true); + diagnosticConfig = settings->diagnosticConfig(); + } + m_customDiagnosticConfig = diagnosticConfig; + m_ui->diagnosticConfigsSelectionWidget->refresh(diagnosticConfig); + + connect(m_ui->globalOrCustom, + static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), + [this](int index){ + m_ui->diagnosticConfigsSelectionWidget->setEnabled(index == CustomSettings); + if (index == CustomSettings) { + m_ui->diagnosticConfigsSelectionWidget->refresh(m_customDiagnosticConfig); + } else { + m_ui->diagnosticConfigsSelectionWidget->refresh( + ClangToolsSettings::instance()->savedDiagnosticConfigId()); + } + }); + connect(m_ui->diagnosticConfigsSelectionWidget, + &ClangDiagnosticConfigsSelectionWidget::currentConfigChanged, + [this](const Core::Id ¤tConfigId) { + if (m_ui->globalOrCustom->currentIndex() == CustomSettings) + m_customDiagnosticConfig = currentConfigId; + }); + + // Restore selection if (settings->selectedDirs().isEmpty() && settings->selectedFiles().isEmpty()) m_filesModel->selectAllFiles(); // Initially, all files are selected else // Restore selection @@ -300,11 +337,16 @@ FileInfos SelectableFilesDialog::filteredFileInfos() const void SelectableFilesDialog::accept() { + ClangToolsProjectSettings *settings = ClangToolsProjectSettingsManager::getSettings(m_project); + + // Save diagnostic configuration + settings->setUseGlobalSettings(m_ui->globalOrCustom->currentIndex() == GlobalSettings); + settings->setDiagnosticConfig(m_customDiagnosticConfig); + // Save selection QSet<FileName> checkedDirs; QSet<FileName> checkedFiles; m_filesModel->minimalSelection(checkedDirs, checkedFiles); - ClangToolsProjectSettings *settings = ClangToolsProjectSettingsManager::getSettings(m_project); settings->setSelectedDirs(checkedDirs); settings->setSelectedFiles(checkedFiles); diff --git a/src/plugins/clangtools/clangselectablefilesdialog.h b/src/plugins/clangtools/clangselectablefilesdialog.h index ec4f093d4b..e639d06199 100644 --- a/src/plugins/clangtools/clangselectablefilesdialog.h +++ b/src/plugins/clangtools/clangselectablefilesdialog.h @@ -27,6 +27,8 @@ #include "clangfileinfo.h" +#include <coreplugin/id.h> + #include <QDialog> #include <memory> @@ -60,6 +62,7 @@ private: std::unique_ptr<Ui::SelectableFilesDialog> m_ui; std::unique_ptr<SelectableFilesModel> m_filesModel; + Core::Id m_customDiagnosticConfig; ProjectExplorer::Project *m_project; QPushButton *m_analyzeButton = nullptr; }; diff --git a/src/plugins/clangtools/clangselectablefilesdialog.ui b/src/plugins/clangtools/clangselectablefilesdialog.ui index 16d620cd7c..69af94c4c6 100644 --- a/src/plugins/clangtools/clangselectablefilesdialog.ui +++ b/src/plugins/clangtools/clangselectablefilesdialog.ui @@ -11,14 +11,55 @@ </rect> </property> <property name="windowTitle"> - <string>Select the Files to Analyze</string> + <string>Analyzer Configuration</string> </property> <layout class="QVBoxLayout" name="verticalLayout"> <item> - <widget class="QTreeView" name="filesView"> - <property name="headerHidden"> - <bool>true</bool> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Diagnostic Configuration</string> </property> + <property name="checkable"> + <bool>false</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QComboBox" name="globalOrCustom"> + <item> + <property name="text"> + <string>Global</string> + </property> + </item> + <item> + <property name="text"> + <string>Custom</string> + </property> + </item> + </widget> + </item> + <item> + <widget class="CppTools::ClangDiagnosticConfigsSelectionWidget" name="diagnosticConfigsSelectionWidget" native="true"/> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Files to Analyze</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QTreeView" name="filesView"> + <property name="headerHidden"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> </widget> </item> <item> @@ -33,6 +74,13 @@ </item> </layout> </widget> + <customwidgets> + <customwidget> + <class>CppTools::ClangDiagnosticConfigsSelectionWidget</class> + <extends>QWidget</extends> + <header>cpptools/clangdiagnosticconfigsselectionwidget.h</header> + </customwidget> + </customwidgets> <resources/> <connections> <connection> diff --git a/src/plugins/clangtools/clangtidyclazyruncontrol.cpp b/src/plugins/clangtools/clangtidyclazyruncontrol.cpp index 44fcf746df..12f158ae68 100644 --- a/src/plugins/clangtools/clangtidyclazyruncontrol.cpp +++ b/src/plugins/clangtools/clangtidyclazyruncontrol.cpp @@ -33,10 +33,13 @@ using namespace ProjectExplorer; namespace ClangTools { namespace Internal { -ClangTidyClazyRunControl::ClangTidyClazyRunControl(RunControl *runControl, - Target *target, - const FileInfos &fileInfos) +ClangTidyClazyRunControl::ClangTidyClazyRunControl( + RunControl *runControl, + Target *target, + const CppTools::ClangDiagnosticConfig &diagnosticConfig, + const FileInfos &fileInfos) : ClangToolRunControl(runControl, target, fileInfos) + , m_diagnosticConfig(diagnosticConfig) { setDisplayName("ClangTidyClazyRunner"); init(); @@ -47,7 +50,8 @@ ClangToolRunner *ClangTidyClazyRunControl::createRunner() QTC_ASSERT(!m_clangExecutable.isEmpty(), return 0); QTC_ASSERT(!m_clangLogFileDir.isEmpty(), return 0); - auto runner = new ClangTidyClazyRunner(m_clangExecutable, + auto runner = new ClangTidyClazyRunner(m_diagnosticConfig, + m_clangExecutable, m_clangLogFileDir, m_environment, this); diff --git a/src/plugins/clangtools/clangtidyclazyruncontrol.h b/src/plugins/clangtools/clangtidyclazyruncontrol.h index 4cc2b39ddc..b0dfafef6a 100644 --- a/src/plugins/clangtools/clangtidyclazyruncontrol.h +++ b/src/plugins/clangtools/clangtidyclazyruncontrol.h @@ -27,6 +27,8 @@ #include "clangtoolruncontrol.h" +#include <cpptools/clangdiagnosticconfig.h> + namespace ClangTools { namespace Internal { @@ -37,11 +39,15 @@ class ClangTidyClazyRunControl final : public ClangToolRunControl public: ClangTidyClazyRunControl(ProjectExplorer::RunControl *runControl, ProjectExplorer::Target *target, + const CppTools::ClangDiagnosticConfig &diagnosticConfig, const FileInfos &fileInfos); protected: ClangToolRunner *createRunner() final; ClangTool *tool() final; + +private: + CppTools::ClangDiagnosticConfig m_diagnosticConfig; }; } // namespace Internal diff --git a/src/plugins/clangtools/clangtidyclazyrunner.cpp b/src/plugins/clangtools/clangtidyclazyrunner.cpp index 83094fe349..71cbc78bec 100644 --- a/src/plugins/clangtools/clangtidyclazyrunner.cpp +++ b/src/plugins/clangtools/clangtidyclazyrunner.cpp @@ -42,7 +42,8 @@ static Q_LOGGING_CATEGORY(LOG, "qtc.clangtools.runner") namespace ClangTools { namespace Internal { -ClangTidyClazyRunner::ClangTidyClazyRunner(const QString &clangExecutable, +ClangTidyClazyRunner::ClangTidyClazyRunner(const CppTools::ClangDiagnosticConfig &diagnosticConfig, + const QString &clangExecutable, const QString &clangLogFileDir, const Utils::Environment &environment, QObject *parent) @@ -51,6 +52,7 @@ ClangTidyClazyRunner::ClangTidyClazyRunner(const QString &clangExecutable, environment, tr("Clang-Tidy and Clazy"), parent) + , m_diagnosticConfig(diagnosticConfig) { } @@ -78,28 +80,21 @@ QStringList ClangTidyClazyRunner::constructCommandLineArguments(const QStringLis << QString("-serialize-diagnostics") << QString(m_logFile); - const ClangDiagnosticConfigsModel configsModel( - CppTools::codeModelSettings()->clangCustomDiagnosticConfigs()); - const Core::Id configId = ClangToolsSettings::instance()->savedDiagnosticConfigId(); - QTC_ASSERT(configsModel.hasConfigWithId(configId), return arguments;); - - const ClangDiagnosticConfig &config = configsModel.configWithId(configId); - - const ClangDiagnosticConfig::TidyMode tidyMode = config.clangTidyMode(); + const ClangDiagnosticConfig::TidyMode tidyMode = m_diagnosticConfig.clangTidyMode(); if (tidyMode != ClangDiagnosticConfig::TidyMode::Disabled) { addXclangArg(arguments, QString("-add-plugin"), QString("clang-tidy")); if (tidyMode != ClangDiagnosticConfig::TidyMode::File) { - const QString tidyChecks = config.clangTidyChecks(); + const QString tidyChecks = m_diagnosticConfig.clangTidyChecks(); addXclangArg(arguments, QString("-plugin-arg-clang-tidy"), "-checks=" + tidyChecks); } } - const QString clazyChecks = config.clazyChecks(); + const QString clazyChecks = m_diagnosticConfig.clazyChecks(); if (!clazyChecks.isEmpty()) { addXclangArg(arguments, QString("-add-plugin"), QString("clang-lazy")); addXclangArg(arguments, QString("-plugin-arg-clang-lazy"), QString("enable-all-fixits")); addXclangArg(arguments, QString("-plugin-arg-clang-lazy"), QString("no-autowrite-fixits")); - addXclangArg(arguments, QString("-plugin-arg-clang-lazy"), config.clazyChecks()); + addXclangArg(arguments, QString("-plugin-arg-clang-lazy"), m_diagnosticConfig.clazyChecks()); } arguments += options; diff --git a/src/plugins/clangtools/clangtidyclazyrunner.h b/src/plugins/clangtools/clangtidyclazyrunner.h index e723653192..507ac2977d 100644 --- a/src/plugins/clangtools/clangtidyclazyrunner.h +++ b/src/plugins/clangtools/clangtidyclazyrunner.h @@ -25,6 +25,8 @@ #pragma once +#include <cpptools/clangdiagnosticconfig.h> + #include "clangtoolrunner.h" namespace ClangTools { @@ -35,12 +37,17 @@ class ClangTidyClazyRunner final : public ClangToolRunner Q_OBJECT public: - ClangTidyClazyRunner(const QString &clangExecutable, + ClangTidyClazyRunner(const CppTools::ClangDiagnosticConfig &diagnosticConfig, + const QString &clangExecutable, const QString &clangLogFileDir, const Utils::Environment &environment, QObject *parent = nullptr); + protected: QStringList constructCommandLineArguments(const QStringList &options) final; + +private: + const CppTools::ClangDiagnosticConfig m_diagnosticConfig; }; } // namespace Internal diff --git a/src/plugins/clangtools/clangtidyclazytool.cpp b/src/plugins/clangtools/clangtidyclazytool.cpp index 51236d98d3..ab922e2c4d 100644 --- a/src/plugins/clangtools/clangtidyclazytool.cpp +++ b/src/plugins/clangtools/clangtidyclazytool.cpp @@ -31,11 +31,16 @@ #include "clangtoolslogfilereader.h" #include "clangtidyclazyruncontrol.h" #include "clangtoolsdiagnosticview.h" +#include "clangtoolsprojectsettings.h" +#include "clangtoolssettings.h" #include <coreplugin/actionmanager/actioncontainer.h> #include <coreplugin/actionmanager/actionmanager.h> +#include <cpptools/clangdiagnosticconfigsmodel.h> +#include <cpptools/cppcodemodelsettings.h> #include <cpptools/cppmodelmanager.h> +#include <cpptools/cpptoolsreuse.h> #include <debugger/analyzer/analyzermanager.h> @@ -50,6 +55,7 @@ #include <QAction> using namespace Core; +using namespace CppTools; using namespace Debugger; using namespace ProjectExplorer; using namespace Utils; @@ -140,6 +146,24 @@ ClangTidyClazyTool *ClangTidyClazyTool::instance() return s_instance; } +static ClangDiagnosticConfig getDiagnosticConfig(Project *project) +{ + ClangToolsProjectSettings *projectSettings = ClangToolsProjectSettingsManager::getSettings( + project); + + Core::Id diagnosticConfigId; + if (projectSettings->useGlobalSettings()) + diagnosticConfigId = ClangToolsSettings::instance()->savedDiagnosticConfigId(); + else + diagnosticConfigId = projectSettings->diagnosticConfig(); + + const ClangDiagnosticConfigsModel configsModel( + CppTools::codeModelSettings()->clangCustomDiagnosticConfigs()); + + QTC_ASSERT(configsModel.hasConfigWithId(diagnosticConfigId), return ClangDiagnosticConfig()); + return configsModel.configWithId(diagnosticConfigId); +} + void ClangTidyClazyTool::startTool(bool askUserForFileSelection) { auto runControl = new RunControl(nullptr, Constants::CLANGTIDYCLAZY_RUN_MODE); @@ -153,7 +177,10 @@ void ClangTidyClazyTool::startTool(bool askUserForFileSelection) if (fileInfos.isEmpty()) return; - auto clangTool = new ClangTidyClazyRunControl(runControl, project->activeTarget(), fileInfos); + auto clangTool = new ClangTidyClazyRunControl(runControl, + project->activeTarget(), + getDiagnosticConfig(project), + fileInfos); m_stopAction->disconnect(); connect(m_stopAction, &QAction::triggered, runControl, [runControl] { diff --git a/src/plugins/clangtools/clangtoolsprojectsettings.cpp b/src/plugins/clangtools/clangtoolsprojectsettings.cpp index d6c87bd876..4622afe2c4 100644 --- a/src/plugins/clangtools/clangtoolsprojectsettings.cpp +++ b/src/plugins/clangtools/clangtoolsprojectsettings.cpp @@ -34,6 +34,8 @@ namespace ClangTools { namespace Internal { +static const char SETTINGS_KEY_USE_GLOBAL_SETTINGS[] = "ClangTools.UseGlobalSettings"; +static const char SETTINGS_KEY_DIAGNOSTIC_CONFIG[] = "ClangTools.DiagnosticConfig"; static const char SETTINGS_KEY_SELECTED_DIRS[] = "ClangTools.SelectedDirs"; static const char SETTINGS_KEY_SELECTED_FILES[] = "ClangTools.SelectedFiles"; static const char SETTINGS_KEY_SUPPRESSED_DIAGS[] = "ClangTools.SuppressedDiagnostics"; @@ -80,6 +82,11 @@ void ClangToolsProjectSettings::removeAllSuppressedDiagnostics() void ClangToolsProjectSettings::load() { + const QVariant useGlobalVariant = m_project->namedSettings(SETTINGS_KEY_USE_GLOBAL_SETTINGS); + m_useGlobalSettings = useGlobalVariant.isValid() ? useGlobalVariant.toBool() : true; + m_diagnosticConfig = Core::Id::fromSetting( + m_project->namedSettings(SETTINGS_KEY_DIAGNOSTIC_CONFIG)); + auto toFileName = [](const QString &s) { return Utils::FileName::fromString(s); }; const QStringList dirs = m_project->namedSettings(SETTINGS_KEY_SELECTED_DIRS).toStringList(); @@ -115,6 +122,9 @@ void ClangToolsProjectSettings::load() void ClangToolsProjectSettings::store() { + m_project->setNamedSettings(SETTINGS_KEY_USE_GLOBAL_SETTINGS, m_useGlobalSettings); + m_project->setNamedSettings(SETTINGS_KEY_DIAGNOSTIC_CONFIG, m_diagnosticConfig.toSetting()); + const QStringList dirs = Utils::transform(m_selectedDirs.toList(), &Utils::FileName::toString); m_project->setNamedSettings(SETTINGS_KEY_SELECTED_DIRS, dirs); @@ -134,6 +144,26 @@ void ClangToolsProjectSettings::store() m_project->setNamedSettings(SETTINGS_KEY_SUPPRESSED_DIAGS, list); } +bool ClangToolsProjectSettings::useGlobalSettings() const +{ + return m_useGlobalSettings; +} + +void ClangToolsProjectSettings::setUseGlobalSettings(bool useGlobalSettings) +{ + m_useGlobalSettings = useGlobalSettings; +} + +Core::Id ClangToolsProjectSettings::diagnosticConfig() const +{ + return m_diagnosticConfig; +} + +void ClangToolsProjectSettings::setDiagnosticConfig(const Core::Id &diagnosticConfig) +{ + m_diagnosticConfig = diagnosticConfig; +} + ClangToolsProjectSettingsManager::ClangToolsProjectSettingsManager() { QObject::connect(ProjectExplorer::SessionManager::instance(), diff --git a/src/plugins/clangtools/clangtoolsprojectsettings.h b/src/plugins/clangtools/clangtoolsprojectsettings.h index d29c0405d7..659a7b5648 100644 --- a/src/plugins/clangtools/clangtoolsprojectsettings.h +++ b/src/plugins/clangtools/clangtoolsprojectsettings.h @@ -27,6 +27,7 @@ #include <QObject> +#include <coreplugin/id.h> #include <projectexplorer/project.h> #include <utils/fileutils.h> @@ -74,6 +75,12 @@ public: ClangToolsProjectSettings(ProjectExplorer::Project *project); ~ClangToolsProjectSettings() override; + bool useGlobalSettings() const; + void setUseGlobalSettings(bool useGlobalSettings); + + Core::Id diagnosticConfig() const; + void setDiagnosticConfig(const Core::Id &diagnosticConfig); + QSet<Utils::FileName> selectedDirs() const { return m_selectedDirs; } void setSelectedDirs(const QSet<Utils::FileName> &value) { m_selectedDirs = value; } @@ -93,6 +100,8 @@ private: void store(); ProjectExplorer::Project *m_project; + bool m_useGlobalSettings = true; + Core::Id m_diagnosticConfig; QSet<Utils::FileName> m_selectedDirs; QSet<Utils::FileName> m_selectedFiles; SuppressedDiagnosticsList m_suppressedDiagnostics; diff --git a/src/plugins/cpptools/clangdiagnosticconfigsselectionwidget.cpp b/src/plugins/cpptools/clangdiagnosticconfigsselectionwidget.cpp index d4efc67f5a..17df43705f 100644 --- a/src/plugins/cpptools/clangdiagnosticconfigsselectionwidget.cpp +++ b/src/plugins/cpptools/clangdiagnosticconfigsselectionwidget.cpp @@ -69,12 +69,13 @@ static void connectToClangDiagnosticConfigsDialog(QPushButton *button) ClangDiagnosticConfigsSelectionWidget::ClangDiagnosticConfigsSelectionWidget(QWidget *parent) : QWidget(parent) + , m_label(new QLabel(tr("Diagnostic Configuration:"), this)) , m_selectionComboBox(new QComboBox(this)) { auto *layout = new QHBoxLayout(this); layout->setMargin(0); setLayout(layout); - layout->addWidget(new QLabel(tr("Diagnostic Configuration:"), this)); + layout->addWidget(m_label); layout->addWidget(m_selectionComboBox); auto *manageButton = new QPushButton(tr("Manage..."), this); layout->addWidget(manageButton); @@ -133,4 +134,9 @@ void ClangDiagnosticConfigsSelectionWidget::refresh(Core::Id id) connectToCurrentIndexChanged(); } +void ClangDiagnosticConfigsSelectionWidget::showLabel(bool show) +{ + m_label->setVisible(show); +} + } // CppTools namespace diff --git a/src/plugins/cpptools/clangdiagnosticconfigsselectionwidget.h b/src/plugins/cpptools/clangdiagnosticconfigsselectionwidget.h index abcdacf365..f8cff89edc 100644 --- a/src/plugins/cpptools/clangdiagnosticconfigsselectionwidget.h +++ b/src/plugins/cpptools/clangdiagnosticconfigsselectionwidget.h @@ -33,6 +33,7 @@ QT_BEGIN_NAMESPACE class QComboBox; +class QLabel; QT_END_NAMESPACE namespace CppTools { @@ -48,6 +49,8 @@ public: void refresh(Core::Id id); + void showLabel(bool show); + signals: void currentConfigChanged(const Core::Id ¤tConfigId); @@ -58,6 +61,7 @@ private: QMetaObject::Connection m_currentIndexChangedConnection; ClangDiagnosticConfigsModel m_diagnosticConfigsModel; + QLabel *m_label = nullptr; QComboBox *m_selectionComboBox = nullptr; }; |