forked from qt-creator/qt-creator
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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
|
||||
@@ -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 ¤tConfigId);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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.<br/>Consider to run these in a separate <a href="target">Clang-Tidy and Clazy analyzer</a> run.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user