Clang/ClangTools: Separate custom diagnostic configs

Add a separate pool of custom diagnostic configs for the
ClangTools plugin. That is, the diagnostic configs in

  Menu: Tools > C++ > Code Model

are not shared anymore with the configs at

  Menu: Tools > Analyzer > ClangTools

On plugin initialization of ClangTools, move tidy/clazy related configs
to ClangTools.

Change-Id: Id06087a58b53e466a3d7bbac669550c5fbe9899d
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
This commit is contained in:
Nikolai Kosjar
2019-09-25 15:46:15 +02:00
parent d2648db914
commit b895dfa382
35 changed files with 523 additions and 443 deletions

View File

@@ -24,6 +24,11 @@
****************************************************************************/
#include "clangdiagnosticconfig.h"
#include "cpptoolsreuse.h"
#include <utils/qtcassert.h>
#include <QSettings>
namespace CppTools {
@@ -124,4 +129,73 @@ void ClangDiagnosticConfig::setClazyChecks(const QString &checks)
m_clazyChecks = checks;
}
static QString convertToNewClazyChecksFormat(const QString &checks)
{
// Before Qt Creator 4.9 valid values for checks were: "", "levelN".
// Starting with Qt Creator 4.9, checks are a comma-separated string of checks: "x,y,z".
if (checks.isEmpty())
return checks;
if (checks.size() == 6 && checks.startsWith("level")) {
bool ok = false;
const int level = checks.midRef(5).toInt(&ok);
QTC_ASSERT(ok, return QString());
return clazyChecksForLevel(level);
}
return checks;
}
static const char diagnosticConfigsArrayKey[] = "ClangDiagnosticConfigs";
static const char diagnosticConfigIdKey[] = "id";
static const char diagnosticConfigDisplayNameKey[] = "displayName";
static const char diagnosticConfigWarningsKey[] = "diagnosticOptions";
static const char diagnosticConfigsTidyChecksKey[] = "clangTidyChecks";
static const char diagnosticConfigsTidyModeKey[] = "clangTidyMode";
static const char diagnosticConfigsClazyChecksKey[] = "clazyChecks";
void diagnosticConfigsToSettings(QSettings *s, const ClangDiagnosticConfigs &configs)
{
s->beginWriteArray(diagnosticConfigsArrayKey);
for (int i = 0, size = configs.size(); i < size; ++i) {
const ClangDiagnosticConfig &config = configs.at(i);
s->setArrayIndex(i);
s->setValue(diagnosticConfigIdKey, config.id().toSetting());
s->setValue(diagnosticConfigDisplayNameKey, config.displayName());
s->setValue(diagnosticConfigWarningsKey, config.clangOptions());
s->setValue(diagnosticConfigsTidyModeKey, int(config.clangTidyMode()));
s->setValue(diagnosticConfigsTidyChecksKey,
config.clangTidyChecks());
s->setValue(diagnosticConfigsClazyChecksKey, config.clazyChecks());
}
s->endArray();
}
ClangDiagnosticConfigs diagnosticConfigsFromSettings(QSettings *s)
{
ClangDiagnosticConfigs configs;
const int size = s->beginReadArray(diagnosticConfigsArrayKey);
for (int i = 0; i < size; ++i) {
s->setArrayIndex(i);
ClangDiagnosticConfig config;
config.setId(Core::Id::fromSetting(s->value(diagnosticConfigIdKey)));
config.setDisplayName(s->value(diagnosticConfigDisplayNameKey).toString());
config.setClangOptions(s->value(diagnosticConfigWarningsKey).toStringList());
config.setClangTidyMode(static_cast<ClangDiagnosticConfig::TidyMode>(
s->value(diagnosticConfigsTidyModeKey).toInt()));
config.setClangTidyChecks(
s->value(diagnosticConfigsTidyChecksKey).toString());
const QString clazyChecks = s->value(diagnosticConfigsClazyChecksKey).toString();
config.setClazyChecks(convertToNewClazyChecksFormat(clazyChecks));
configs.append(config);
}
s->endArray();
return configs;
}
} // namespace CppTools

View File

@@ -32,8 +32,13 @@
#include <QStringList>
#include <QVector>
QT_BEGIN_NAMESPACE
class QSettings;
QT_END_NAMESPACE
namespace CppTools {
// TODO: Split this class as needed for ClangCodeModel and ClangTools
class CPPTOOLS_EXPORT ClangDiagnosticConfig
{
public:
@@ -84,4 +89,8 @@ private:
using ClangDiagnosticConfigs = QVector<ClangDiagnosticConfig>;
ClangDiagnosticConfigs CPPTOOLS_EXPORT diagnosticConfigsFromSettings(QSettings *s);
void CPPTOOLS_EXPORT diagnosticConfigsToSettings(QSettings *s,
const ClangDiagnosticConfigs &configs);
} // namespace CppTools

View File

@@ -35,161 +35,9 @@
namespace CppTools {
static void addConfigForQuestionableConstructs(ClangDiagnosticConfigsModel &model)
ClangDiagnosticConfigsModel::ClangDiagnosticConfigsModel(const ClangDiagnosticConfigs &configs)
{
ClangDiagnosticConfig config;
config.setId("Builtin.Questionable");
config.setDisplayName(QCoreApplication::translate(
"ClangDiagnosticConfigsModel",
"Clang-only checks for questionable constructs"));
config.setIsReadOnly(true);
config.setClangOptions(QStringList{
QStringLiteral("-Wall"),
QStringLiteral("-Wextra"),
});
model.appendOrUpdate(config);
}
static void addConfigForPedanticWarnings(ClangDiagnosticConfigsModel &model)
{
ClangDiagnosticConfig config;
config.setId("Builtin.Pedantic");
config.setDisplayName(QCoreApplication::translate("ClangDiagnosticConfigsModel",
"Clang-only pedantic checks"));
config.setIsReadOnly(true);
config.setClangOptions(QStringList{QStringLiteral("-Wpedantic")});
model.appendOrUpdate(config);
}
constexpr const char *DEFAULT_TIDY_CHECKS = "-*,"
"bugprone-*,"
"cppcoreguidelines-*,"
"misc-*,"
"modernize-*,"
"performance-*,"
"readability-*,"
"-cppcoreguidelines-owning-memory,"
"-readability-braces-around-statements,"
"-readability-implicit-bool-conversion,"
"-readability-named-parameter";
static void addConfigForAlmostEveryWarning(ClangDiagnosticConfigsModel &model)
{
ClangDiagnosticConfig config;
config.setId(Constants::CPP_CLANG_BUILTIN_CONFIG_ID_EVERYTHING_WITH_EXCEPTIONS);
config.setDisplayName(QCoreApplication::translate(
"ClangDiagnosticConfigsModel",
"Clang-only checks for almost everything"));
config.setIsReadOnly(true);
config.setClangOptions(QStringList{
QStringLiteral("-Weverything"),
QStringLiteral("-Wno-c++98-compat"),
QStringLiteral("-Wno-c++98-compat-pedantic"),
QStringLiteral("-Wno-unused-macros"),
QStringLiteral("-Wno-newline-eof"),
QStringLiteral("-Wno-exit-time-destructors"),
QStringLiteral("-Wno-global-constructors"),
QStringLiteral("-Wno-gnu-zero-variadic-macro-arguments"),
QStringLiteral("-Wno-documentation"),
QStringLiteral("-Wno-shadow"),
QStringLiteral("-Wno-switch-enum"),
QStringLiteral("-Wno-missing-prototypes"), // Not optimal for C projects.
QStringLiteral("-Wno-used-but-marked-unused"), // e.g. QTest::qWait
});
model.appendOrUpdate(config);
}
static void addConfigForTidy(ClangDiagnosticConfigsModel &model)
{
ClangDiagnosticConfig config;
config.setId("Builtin.Tidy");
config.setDisplayName(QCoreApplication::translate("ClangDiagnosticConfigsModel",
"Clang-Tidy thorough checks"));
config.setIsReadOnly(true);
config.setClangOptions(QStringList{QStringLiteral("-w")});
config.setClangTidyMode(ClangDiagnosticConfig::TidyMode::ChecksPrefixList);
config.setClangTidyChecks(QString::fromUtf8(DEFAULT_TIDY_CHECKS));
model.appendOrUpdate(config);
}
static void addConfigForClangAnalyze(ClangDiagnosticConfigsModel &model)
{
ClangDiagnosticConfig config;
config.setId("Builtin.TidyClangAnalyze");
config.setDisplayName(QCoreApplication::translate(
"ClangDiagnosticConfigsModel",
"Clang-Tidy static analyzer checks"));
config.setIsReadOnly(true);
config.setClangOptions(QStringList{
QStringLiteral("-w"),
});
config.setClangTidyMode(ClangDiagnosticConfig::TidyMode::ChecksPrefixList);
config.setClangTidyChecks("-*,clang-analyzer-*");
model.appendOrUpdate(config);
}
static void addConfigForClazy(ClangDiagnosticConfigsModel &model)
{
ClangDiagnosticConfig config;
config.setId("Builtin.Clazy");
config.setDisplayName(QCoreApplication::translate("ClangDiagnosticConfigsModel",
"Clazy level0 checks"));
config.setIsReadOnly(true);
config.setClangOptions(QStringList{QStringLiteral("-w")});
config.setClazyChecks(clazyChecksForLevel(0));
model.appendOrUpdate(config);
}
static void addConfigForTidyAndClazy(ClangDiagnosticConfigsModel &model)
{
ClangDiagnosticConfig config;
config.setId("Builtin.TidyAndClazy");
config.setDisplayName(QCoreApplication::translate("ClangDiagnosticConfigsModel",
"Clang-Tidy and Clazy preselected checks"));
config.setIsReadOnly(true);
config.setClangOptions(QStringList{QStringLiteral("-w")});
config.setClangTidyMode(ClangDiagnosticConfig::TidyMode::ChecksPrefixList);
config.setClangTidyChecks(QString::fromUtf8(DEFAULT_TIDY_CHECKS));
config.setClazyChecks(clazyChecksForLevel(0));
model.appendOrUpdate(config);
}
static void addConfigForBuildSystem(ClangDiagnosticConfigsModel &model)
{
ClangDiagnosticConfig config;
config.setId("Builtin.BuildSystem");
config.setDisplayName(QCoreApplication::translate("ClangDiagnosticConfigsModel",
"Build-system warnings"));
config.setIsReadOnly(true);
config.setUseBuildSystemWarnings(true);
model.appendOrUpdate(config);
}
static void addBuiltinConfigs(ClangDiagnosticConfigsModel &model)
{
addConfigForPedanticWarnings(model);
addConfigForQuestionableConstructs(model);
addConfigForAlmostEveryWarning(model);
addConfigForTidy(model);
addConfigForClangAnalyze(model);
addConfigForClazy(model);
addConfigForTidyAndClazy(model);
addConfigForBuildSystem(model);
}
ClangDiagnosticConfigsModel::ClangDiagnosticConfigsModel(const ClangDiagnosticConfigs &customConfigs)
{
addBuiltinConfigs(*this);
m_diagnosticConfigs.append(customConfigs);
m_diagnosticConfigs.append(configs);
}
int ClangDiagnosticConfigsModel::size() const

View File

@@ -37,7 +37,7 @@ class CPPTOOLS_EXPORT ClangDiagnosticConfigsModel
{
public:
ClangDiagnosticConfigsModel() = default;
explicit ClangDiagnosticConfigsModel(const ClangDiagnosticConfigs &customConfigs);
explicit ClangDiagnosticConfigsModel(const ClangDiagnosticConfigs &configs);
int size() const;
const ClangDiagnosticConfig &at(int index) const;

View File

@@ -49,14 +49,23 @@ ClangDiagnosticConfigsSelectionWidget::ClangDiagnosticConfigsSelectionWidget(QWi
setLayout(layout);
layout->addWidget(m_label);
layout->addWidget(m_selectionComboBox, 1);
auto *manageButton = new QPushButton(tr("Manage..."), this);
layout->addWidget(manageButton);
m_manageButton = new QPushButton(tr("Manage..."), this);
layout->addWidget(m_manageButton);
layout->addStretch();
}
connectToClangDiagnosticConfigsDialog(manageButton);
void ClangDiagnosticConfigsSelectionWidget::refresh(const ClangDiagnosticConfigsModel &model,
const Core::Id &configToSelect,
bool showTidyClazyUi)
{
m_showTidyClazyUi = showTidyClazyUi;
m_diagnosticConfigsModel = model;
refresh(codeModelSettings()->clangDiagnosticConfigId());
disconnect(m_manageButton, 0, 0, 0);
connectToClangDiagnosticConfigsDialog();
disconnectFromCurrentIndexChanged();
refresh(configToSelect);
connectToCurrentIndexChanged();
}
@@ -83,8 +92,6 @@ void ClangDiagnosticConfigsSelectionWidget::refresh(Core::Id id)
int configToSelectIndex = -1;
m_selectionComboBox->clear();
m_diagnosticConfigsModel = ClangDiagnosticConfigsModel(
codeModelSettings()->clangCustomDiagnosticConfigs());
const int size = m_diagnosticConfigsModel.size();
for (int i = 0; i < size; ++i) {
const ClangDiagnosticConfig &config = m_diagnosticConfigsModel.at(i);
@@ -104,10 +111,13 @@ void ClangDiagnosticConfigsSelectionWidget::refresh(Core::Id id)
connectToCurrentIndexChanged();
}
void ClangDiagnosticConfigsSelectionWidget::connectToClangDiagnosticConfigsDialog(QPushButton *button)
void ClangDiagnosticConfigsSelectionWidget::connectToClangDiagnosticConfigsDialog()
{
connect(button, &QPushButton::clicked, [this]() {
ClangDiagnosticConfigsWidget *widget = new ClangDiagnosticConfigsWidget(currentConfigId());
connect(m_manageButton, &QPushButton::clicked, [this]() {
ClangDiagnosticConfigsWidget *widget
= new ClangDiagnosticConfigsWidget(m_diagnosticConfigsModel,
currentConfigId(),
m_showTidyClazyUi);
widget->layout()->setContentsMargins(0, 0, 0, 0);
QDialog dialog;
dialog.setWindowTitle(ClangDiagnosticConfigsWidget::tr("Diagnostic Configurations"));
@@ -119,19 +129,10 @@ void ClangDiagnosticConfigsSelectionWidget::connectToClangDiagnosticConfigsDialo
connect(buttonsBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
const bool previousEnableLowerClazyLevels = codeModelSettings()->enableLowerClazyLevels();
connect(&dialog, &QDialog::accepted, [widget, previousEnableLowerClazyLevels]() {
QSharedPointer<CppCodeModelSettings> settings = codeModelSettings();
const ClangDiagnosticConfigs oldDiagnosticConfigs
= settings->clangCustomDiagnosticConfigs();
const ClangDiagnosticConfigs currentDiagnosticConfigs = widget->customConfigs();
if (oldDiagnosticConfigs != currentDiagnosticConfigs
|| previousEnableLowerClazyLevels != codeModelSettings()->enableLowerClazyLevels()) {
const ClangDiagnosticConfigsModel configsModel(currentDiagnosticConfigs);
if (!configsModel.hasConfigWithId(settings->clangDiagnosticConfigId()))
settings->resetClangDiagnosticConfigId();
settings->setClangCustomDiagnosticConfigs(currentDiagnosticConfigs);
settings->toSettings(Core::ICore::settings());
}
connect(&dialog, &QDialog::accepted, [this, widget, previousEnableLowerClazyLevels]() {
if (previousEnableLowerClazyLevels != codeModelSettings()->enableLowerClazyLevels())
codeModelSettings()->toSettings(Core::ICore::settings());
emit diagnosticConfigsEdited(widget->customConfigs());
});
dialog.exec();
});

View File

@@ -46,22 +46,29 @@ class CPPTOOLS_EXPORT ClangDiagnosticConfigsSelectionWidget : public QWidget
public:
explicit ClangDiagnosticConfigsSelectionWidget(QWidget *parent = nullptr);
void refresh(const ClangDiagnosticConfigsModel &model,
const Core::Id &configToSelect,
bool showTidyClazyUi);
Core::Id currentConfigId() const;
void refresh(Core::Id id);
signals:
void diagnosticConfigsEdited(const ClangDiagnosticConfigs &configs);
void currentConfigChanged(const Core::Id &currentConfigId);
private:
void connectToClangDiagnosticConfigsDialog(QPushButton *button);
void connectToClangDiagnosticConfigsDialog();
void connectToCurrentIndexChanged();
void disconnectFromCurrentIndexChanged();
void refresh(Core::Id id);
QMetaObject::Connection m_currentIndexChangedConnection;
bool m_showTidyClazyUi = true;
ClangDiagnosticConfigsModel m_diagnosticConfigsModel;
QLabel *m_label = nullptr;
QPushButton *m_manageButton = nullptr;
QComboBox *m_selectionComboBox = nullptr;
};

View File

@@ -568,19 +568,19 @@ private:
QStringList m_topics;
};
ClangDiagnosticConfigsWidget::ClangDiagnosticConfigsWidget(const Core::Id &configToSelect,
QWidget *parent)
ClangDiagnosticConfigsWidget::ClangDiagnosticConfigsWidget(
const ClangDiagnosticConfigsModel &configsModel,
const Core::Id &configToSelect,
bool showTidyClazyTabs,
QWidget *parent)
: QWidget(parent)
, m_ui(new Ui::ClangDiagnosticConfigsWidget)
, m_diagnosticConfigsModel(codeModelSettings()->clangCustomDiagnosticConfigs())
, m_diagnosticConfigsModel(configsModel)
, m_clazyTreeModel(new ClazyChecksTreeModel())
, m_tidyTreeModel(new TidyChecksTreeModel())
{
m_ui->setupUi(this);
setupTabs();
m_selectedConfigIndex = m_diagnosticConfigsModel.indexOfConfig(
codeModelSettings()->clangDiagnosticConfigId());
setupTabs(showTidyClazyTabs);
connectConfigChooserCurrentIndex();
connect(m_ui->copyButton, &QPushButton::clicked,
@@ -989,7 +989,7 @@ static void setupTreeView(QTreeView *view, QAbstractItemModel *model, int expand
view->setHeaderHidden(true);
}
void ClangDiagnosticConfigsWidget::setupTabs()
void ClangDiagnosticConfigsWidget::setupTabs(bool showTidyClazyTabs)
{
m_clangBaseChecks = std::make_unique<CppTools::Ui::ClangBaseChecks>();
m_clangBaseChecksWidget = new QWidget();
@@ -1075,8 +1075,10 @@ void ClangDiagnosticConfigsWidget::setupTabs()
connectClazyItemChanged();
m_ui->tabWidget->addTab(m_clangBaseChecksWidget, tr("Clang"));
m_ui->tabWidget->addTab(m_tidyChecksWidget, tr("Clang-Tidy"));
m_ui->tabWidget->addTab(m_clazyChecksWidget, tr("Clazy"));
if (showTidyClazyTabs) {
m_ui->tabWidget->addTab(m_tidyChecksWidget, tr("Clang-Tidy"));
m_ui->tabWidget->addTab(m_clazyChecksWidget, tr("Clazy"));
}
m_ui->tabWidget->setCurrentIndex(0);
}

View File

@@ -58,7 +58,10 @@ class CPPTOOLS_EXPORT ClangDiagnosticConfigsWidget : public QWidget
Q_OBJECT
public:
explicit ClangDiagnosticConfigsWidget(const Core::Id &configToSelect, QWidget *parent = nullptr);
explicit ClangDiagnosticConfigsWidget(const ClangDiagnosticConfigsModel &configsModel,
const Core::Id &configToSelect,
bool showTidyClazyTabs,
QWidget *parent = nullptr);
~ClangDiagnosticConfigsWidget() override;
ClangDiagnosticConfigs customConfigs() const;
@@ -67,7 +70,7 @@ signals:
void customConfigsChanged(const CppTools::ClangDiagnosticConfigs &customConfigs);
private:
void setupTabs();
void setupTabs(bool showTidyClazyTabs);
void onCurrentConfigChanged(int index);
void onCopyButtonClicked();

View File

@@ -44,27 +44,6 @@ static CppCodeModelSettings::PCHUsage initialPchUsage()
static QString clangDiagnosticConfigKey()
{ return QStringLiteral("ClangDiagnosticConfig"); }
static QString clangDiagnosticConfigsArrayKey()
{ return QStringLiteral("ClangDiagnosticConfigs"); }
static QString clangDiagnosticConfigsArrayIdKey()
{ return QLatin1String("id"); }
static QString clangDiagnosticConfigsArrayDisplayNameKey()
{ return QLatin1String("displayName"); }
static QString clangDiagnosticConfigsArrayWarningsKey()
{ return QLatin1String("diagnosticOptions"); }
static QString clangDiagnosticConfigsArrayClangTidyChecksKey()
{ return QLatin1String("clangTidyChecks"); }
static QString clangDiagnosticConfigsArrayClangTidyModeKey()
{ return QLatin1String("clangTidyMode"); }
static QString clangDiagnosticConfigsArrayClazyChecksKey()
{ return QLatin1String("clazyChecks"); }
static QString enableLowerClazyLevelsKey()
{ return QLatin1String("enableLowerClazyLevels"); }
@@ -80,53 +59,6 @@ static QString skipIndexingBigFilesKey()
static QString indexerFileSizeLimitKey()
{ return QLatin1String(Constants::CPPTOOLS_INDEXER_FILE_SIZE_LIMIT); }
static QString convertToNewClazyChecksFormat(const QString &checks)
{
// Before Qt Creator 4.9 valid values for checks were: "", "levelN".
// Starting with Qt Creator 4.9, checks are a comma-separated string of checks: "x,y,z".
if (checks.isEmpty())
return checks;
if (checks.size() == 6 && checks.startsWith("level")) {
bool ok = false;
const int level = checks.midRef(5).toInt(&ok);
QTC_ASSERT(ok, return QString());
return clazyChecksForLevel(level);
}
return checks;
}
static ClangDiagnosticConfigs customDiagnosticConfigsFromSettings(QSettings *s)
{
QTC_ASSERT(s->group() == QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP),
return ClangDiagnosticConfigs());
ClangDiagnosticConfigs configs;
const int size = s->beginReadArray(clangDiagnosticConfigsArrayKey());
for (int i = 0; i < size; ++i) {
s->setArrayIndex(i);
ClangDiagnosticConfig config;
config.setId(Core::Id::fromSetting(s->value(clangDiagnosticConfigsArrayIdKey())));
config.setDisplayName(s->value(clangDiagnosticConfigsArrayDisplayNameKey()).toString());
config.setClangOptions(s->value(clangDiagnosticConfigsArrayWarningsKey()).toStringList());
config.setClangTidyMode(static_cast<ClangDiagnosticConfig::TidyMode>(
s->value(clangDiagnosticConfigsArrayClangTidyModeKey()).toInt()));
config.setClangTidyChecks(
s->value(clangDiagnosticConfigsArrayClangTidyChecksKey()).toString());
const QString clazyChecks = s->value(clangDiagnosticConfigsArrayClazyChecksKey()).toString();
config.setClazyChecks(convertToNewClazyChecksFormat(clazyChecks));
configs.append(config);
}
s->endArray();
return configs;
}
static Core::Id clangDiagnosticConfigIdFromSettings(QSettings *s)
{
QTC_ASSERT(s->group() == QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP), return Core::Id());
@@ -139,11 +71,12 @@ void CppCodeModelSettings::fromSettings(QSettings *s)
{
s->beginGroup(QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP));
setClangCustomDiagnosticConfigs(customDiagnosticConfigsFromSettings(s));
setClangCustomDiagnosticConfigs(diagnosticConfigsFromSettings(s));
setClangDiagnosticConfigId(clangDiagnosticConfigIdFromSettings(s));
{ // Before Qt Creator 4.8, inconsistent settings might have been written.
const ClangDiagnosticConfigsModel model(m_clangCustomDiagnosticConfigs);
const ClangDiagnosticConfigsModel model = diagnosticConfigsModel(
m_clangCustomDiagnosticConfigs);
if (!model.hasConfigWithId(m_clangDiagnosticConfigId))
setClangDiagnosticConfigId(initialClangDiagnosticConfigId());
}
@@ -171,24 +104,10 @@ void CppCodeModelSettings::fromSettings(QSettings *s)
void CppCodeModelSettings::toSettings(QSettings *s)
{
s->beginGroup(QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP));
const ClangDiagnosticConfigs previousConfigs = customDiagnosticConfigsFromSettings(s);
const ClangDiagnosticConfigs previousConfigs = diagnosticConfigsFromSettings(s);
const Core::Id previousConfigId = clangDiagnosticConfigIdFromSettings(s);
s->beginWriteArray(clangDiagnosticConfigsArrayKey());
for (int i = 0, size = m_clangCustomDiagnosticConfigs.size(); i < size; ++i) {
const ClangDiagnosticConfig &config = m_clangCustomDiagnosticConfigs.at(i);
s->setArrayIndex(i);
s->setValue(clangDiagnosticConfigsArrayIdKey(), config.id().toSetting());
s->setValue(clangDiagnosticConfigsArrayDisplayNameKey(), config.displayName());
s->setValue(clangDiagnosticConfigsArrayWarningsKey(), config.clangOptions());
s->setValue(clangDiagnosticConfigsArrayClangTidyModeKey(),
static_cast<int>(config.clangTidyMode()));
s->setValue(clangDiagnosticConfigsArrayClangTidyChecksKey(),
config.clangTidyChecks());
s->setValue(clangDiagnosticConfigsArrayClazyChecksKey(), config.clazyChecks());
}
s->endArray();
diagnosticConfigsToSettings(s, m_clangCustomDiagnosticConfigs);
s->setValue(clangDiagnosticConfigKey(), clangDiagnosticConfigId().toSetting());
s->setValue(enableLowerClazyLevelsKey(), enableLowerClazyLevels());
@@ -229,7 +148,8 @@ void CppCodeModelSettings::resetClangDiagnosticConfigId()
const ClangDiagnosticConfig CppCodeModelSettings::clangDiagnosticConfig() const
{
const ClangDiagnosticConfigsModel configsModel(m_clangCustomDiagnosticConfigs);
const ClangDiagnosticConfigsModel configsModel = diagnosticConfigsModel(
m_clangCustomDiagnosticConfigs);
return configsModel.configWithId(clangDiagnosticConfigId());
}

View File

@@ -24,17 +24,15 @@
****************************************************************************/
#include "cppcodemodelsettingspage.h"
#include "ui_cppcodemodelsettingspage.h"
#include "clangdiagnosticconfigswidget.h"
#include "cppmodelmanager.h"
#include "cpptoolsconstants.h"
#include "cpptoolsreuse.h"
#include "ui_cppcodemodelsettingspage.h"
#include <clangtools/clangtoolsconstants.h> // for opening the respective options page
#include <coreplugin/icore.h>
#include <utils/algorithm.h>
#include <utils/utilsicons.h>
#include <QTextStream>
@@ -45,12 +43,6 @@ CppCodeModelSettingsWidget::CppCodeModelSettingsWidget()
: m_ui(new Ui::CppCodeModelSettingsPage)
{
m_ui->setupUi(this);
m_ui->expensiveChecksHintIcon->setPixmap(Utils::Icons::WARNING.pixmap());
m_ui->expensiveChecksHintIcon->setVisible(false);
m_ui->expensiveChecksHintText->setVisible(false);
connect(m_ui->expensiveChecksHintText, &QLabel::linkActivated, [](const QString &){
Core::ICore::showOptionsDialog(ClangTools::Constants::SETTINGS_PAGE_ID);
});
}
CppCodeModelSettingsWidget::~CppCodeModelSettingsWidget()
@@ -77,24 +69,30 @@ void CppCodeModelSettingsWidget::applyToSettings() const
m_settings->toSettings(Core::ICore::settings());
}
static bool hasConfigExpensiveChecks(const Core::Id &configId)
{
if (!configId.isValid())
return false;
const ClangDiagnosticConfig config
= ClangDiagnosticConfigsModel(
codeModelSettings()->clangCustomDiagnosticConfigs())
.configWithId(configId);
return !config.clazyChecks().isEmpty()
|| config.clangTidyMode() != ClangDiagnosticConfig::TidyMode::Disabled;
}
void CppCodeModelSettingsWidget::setupClangCodeModelWidgets()
{
const bool isClangActive = CppModelManager::instance()->isClangCodeModelActive();
m_ui->clangDiagnosticConfigsSelectionWidget->refresh(diagnosticConfigsModel(),
m_settings->clangDiagnosticConfigId(),
/*showTidyClazyUi=*/false);
connect(m_ui->clangDiagnosticConfigsSelectionWidget,
&ClangDiagnosticConfigsSelectionWidget::diagnosticConfigsEdited,
this,
[this](const ClangDiagnosticConfigs &configs) {
const ClangDiagnosticConfigsModel configsModel = diagnosticConfigsModel(configs);
if (!configsModel.hasConfigWithId(m_settings->clangDiagnosticConfigId()))
m_settings->resetClangDiagnosticConfigId();
m_settings->setClangCustomDiagnosticConfigs(configs);
applyClangCodeModelWidgetsToSettings();
m_settings->toSettings(Core::ICore::settings());
m_ui->clangDiagnosticConfigsSelectionWidget
->refresh(configsModel,
m_settings->clangDiagnosticConfigId(),
/*showTidyClazyUi=*/false);
});
const bool isClangActive = CppModelManager::instance()->isClangCodeModelActive();
m_ui->clangCodeModelIsDisabledHint->setVisible(!isClangActive);
m_ui->clangCodeModelIsEnabledHint->setVisible(isClangActive);
for (int i = 0; i < m_ui->clangDiagnosticConfigsSelectionWidget->layout()->count(); ++i) {
@@ -102,25 +100,6 @@ void CppCodeModelSettingsWidget::setupClangCodeModelWidgets()
if (widget)
widget->setEnabled(isClangActive);
}
connect(m_settings.data(), &CppCodeModelSettings::changed,
this, [this]() {
m_ui->clangDiagnosticConfigsSelectionWidget->refresh(
m_ui->clangDiagnosticConfigsSelectionWidget->currentConfigId());
if (applyClangCodeModelWidgetsToSettings())
m_settings->toSettings(Core::ICore::settings());
});
const auto checkForExpensiveChecks = [this](const Core::Id &configId) {
const bool visible = hasConfigExpensiveChecks(configId);
m_ui->expensiveChecksHintIcon->setVisible(visible);
m_ui->expensiveChecksHintText->setVisible(visible);
};
checkForExpensiveChecks(m_ui->clangDiagnosticConfigsSelectionWidget->currentConfigId());
connect(m_ui->clangDiagnosticConfigsSelectionWidget,
&ClangDiagnosticConfigsSelectionWidget::currentConfigChanged,
checkForExpensiveChecks);
}
void CppCodeModelSettingsWidget::setupGeneralWidgets()

View File

@@ -108,23 +108,6 @@
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="expensiveChecksHintIcon">
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="expensiveChecksHintText">
<property name="text">
<string>The selected configuration has potentially expensive Clang-Tidy or Clazy checks enabled.&lt;br/&gt;Consider to run these in a separate &lt;a href=&quot;target&quot;&gt;Clang-Tidy and Clazy analyzer&lt;/a&gt; run.</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">

View File

@@ -26,8 +26,9 @@
#include "cpptoolsreuse.h"
#include "cppcodemodelsettings.h"
#include "cpptoolsplugin.h"
#include "cpptools_clazychecks.h"
#include "cpptoolsconstants.h"
#include "cpptoolsplugin.h"
#include <coreplugin/documentmanager.h>
#include <coreplugin/editormanager/editormanager.h>
@@ -351,4 +352,76 @@ QString clazyChecksForLevel(int level)
return checks.join(',');
}
static void addBuiltinConfigs(ClangDiagnosticConfigsModel &model)
{
// Pedantic
ClangDiagnosticConfig config;
config.setId("Builtin.Pedantic");
config.setDisplayName(QCoreApplication::translate("ClangDiagnosticConfigsModel",
"Pedantic checks"));
config.setIsReadOnly(true);
config.setClangOptions(QStringList{QStringLiteral("-Wpedantic")});
model.appendOrUpdate(config);
// Questionable constructs
config = ClangDiagnosticConfig();
config.setId("Builtin.Questionable");
config.setDisplayName(QCoreApplication::translate(
"ClangDiagnosticConfigsModel",
"Checks for questionable constructs"));
config.setIsReadOnly(true);
config.setClangOptions(QStringList{
QStringLiteral("-Wall"),
QStringLiteral("-Wextra"),
});
model.appendOrUpdate(config);
// Everything with exceptions
config = ClangDiagnosticConfig();
config.setId(Constants::CPP_CLANG_BUILTIN_CONFIG_ID_EVERYTHING_WITH_EXCEPTIONS);
config.setDisplayName(QCoreApplication::translate(
"ClangDiagnosticConfigsModel",
"Checks for almost everything"));
config.setIsReadOnly(true);
config.setClangOptions(QStringList{
QStringLiteral("-Weverything"),
QStringLiteral("-Wno-c++98-compat"),
QStringLiteral("-Wno-c++98-compat-pedantic"),
QStringLiteral("-Wno-unused-macros"),
QStringLiteral("-Wno-newline-eof"),
QStringLiteral("-Wno-exit-time-destructors"),
QStringLiteral("-Wno-global-constructors"),
QStringLiteral("-Wno-gnu-zero-variadic-macro-arguments"),
QStringLiteral("-Wno-documentation"),
QStringLiteral("-Wno-shadow"),
QStringLiteral("-Wno-switch-enum"),
QStringLiteral("-Wno-missing-prototypes"), // Not optimal for C projects.
QStringLiteral("-Wno-used-but-marked-unused"), // e.g. QTest::qWait
});
model.appendOrUpdate(config);
// Build system
config = ClangDiagnosticConfig();
config.setId("Builtin.BuildSystem");
config.setDisplayName(QCoreApplication::translate("ClangDiagnosticConfigsModel",
"Build-system warnings"));
config.setIsReadOnly(true);
config.setUseBuildSystemWarnings(true);
model.appendOrUpdate(config);
}
ClangDiagnosticConfigsModel diagnosticConfigsModel(const ClangDiagnosticConfigs &customConfigs)
{
ClangDiagnosticConfigsModel model;
addBuiltinConfigs(model);
for (const ClangDiagnosticConfig &config : customConfigs)
model.appendOrUpdate(config);
return model;
}
ClangDiagnosticConfigsModel diagnosticConfigsModel()
{
return diagnosticConfigsModel(CppTools::codeModelSettings()->clangCustomDiagnosticConfigs());
}
} // CppTools

View File

@@ -29,6 +29,7 @@
#include <texteditor/texteditor.h>
#include <cpptools/clangdiagnosticconfig.h>
#include <cpptools/compileroptionsbuilder.h>
#include <cplusplus/CppDocument.h>
@@ -81,6 +82,11 @@ UsePrecompiledHeaders CPPTOOLS_EXPORT getPchUsage();
int indexerFileSizeLimitInMb();
bool fileSizeExceedsLimit(const QFileInfo &fileInfo, int sizeLimitInMb);
QString clazyChecksForLevel(int level);
QString CPPTOOLS_EXPORT clazyChecksForLevel(int level);
class ClangDiagnosticConfigsModel;
ClangDiagnosticConfigsModel CPPTOOLS_EXPORT diagnosticConfigsModel();
ClangDiagnosticConfigsModel CPPTOOLS_EXPORT
diagnosticConfigsModel(const CppTools::ClangDiagnosticConfigs &customConfigs);
} // CppTools