Clang: Make clazy/tidy options part of the diagnostic config

As a side effect, clazy/tidy options become available for project
specific customization in the projects mode.

Change-Id: Id72762dedd857915139c15f532d2f1c6d1f43edb
Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
This commit is contained in:
Nikolai Kosjar
2018-01-26 10:27:58 +01:00
parent 5b1ae09fbf
commit 33b6fe812a
13 changed files with 212 additions and 191 deletions

View File

@@ -25,6 +25,8 @@
#include "clangdiagnosticconfigswidget.h"
#include "ui_clangdiagnosticconfigswidget.h"
#include "ui_clazychecks.h"
#include "ui_tidychecks.h"
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
@@ -45,6 +47,7 @@ ClangDiagnosticConfigsWidget::ClangDiagnosticConfigsWidget(
, m_diagnosticConfigsModel(diagnosticConfigsModel)
{
m_ui->setupUi(this);
setupPluginsWidgets();
connectConfigChooserCurrentIndex();
connect(m_ui->copyButton, &QPushButton::clicked,
@@ -108,6 +111,18 @@ void ClangDiagnosticConfigsWidget::onRemoveButtonClicked()
syncConfigChooserToModel();
}
void ClangDiagnosticConfigsWidget::onClangTidyItemChanged(QListWidgetItem *item)
{
const QString prefix = item->text();
ClangDiagnosticConfig config = currentConfig();
QString checks = config.clangTidyChecks();
item->checkState() == Qt::Checked
? checks.append(',' + prefix)
: checks.remove(',' + prefix);
config.setClangTidyChecks(checks);
updateConfig(config);
}
static bool isAcceptedWarningOption(const QString &option)
{
return option == "-w"
@@ -162,10 +177,8 @@ void ClangDiagnosticConfigsWidget::onDiagnosticOptionsEdited()
// Commit valid changes
ClangDiagnosticConfig updatedConfig = currentConfig();
updatedConfig.setCommandLineWarnings(normalizedOptions);
m_diagnosticConfigsModel.appendOrUpdate(updatedConfig);
emit customConfigsChanged(customConfigs());
updatedConfig.setClangOptions(normalizedOptions);
updateConfig(updatedConfig);
}
void ClangDiagnosticConfigsWidget::syncWidgetsToModel(const Core::Id &configToSelect)
@@ -213,12 +226,74 @@ void ClangDiagnosticConfigsWidget::syncOtherWidgetsToComboBox()
// Update main button row
m_ui->removeButton->setEnabled(!config.isReadOnly());
// Update child widgets
// Update Text Edit
const QString options = m_notAcceptedOptions.contains(config.id())
? m_notAcceptedOptions.value(config.id())
: config.commandLineWarnings().join(QLatin1Char(' '));
: config.clangOptions().join(QLatin1Char(' '));
setDiagnosticOptions(options);
m_ui->diagnosticOptionsTextEdit->setReadOnly(config.isReadOnly());
syncClangTidyWidgets(config);
syncClazyWidgets(config);
}
void ClangDiagnosticConfigsWidget::syncClangTidyWidgets(const ClangDiagnosticConfig &config)
{
disconnectClangTidyItemChanged();
const QString tidyChecks = config.clangTidyChecks();
for (int row = 0; row < m_tidyChecks->checksList->count(); ++row) {
QListWidgetItem *item = m_tidyChecks->checksList->item(row);
Qt::ItemFlags flags = item->flags();
flags |= Qt::ItemIsUserCheckable;
if (config.isReadOnly())
flags &= ~Qt::ItemIsEnabled;
else
flags |= Qt::ItemIsEnabled;
item->setFlags(flags);
if (tidyChecks.indexOf(item->text()) != -1)
item->setCheckState(Qt::Checked);
else
item->setCheckState(Qt::Unchecked);
}
connectClangTidyItemChanged();
}
void ClangDiagnosticConfigsWidget::syncClazyWidgets(const ClangDiagnosticConfig &config)
{
const QString clazyChecks = config.clazyChecks();
if (clazyChecks.isEmpty())
m_clazyChecks->clazyLevel->setCurrentIndex(0);
else
m_clazyChecks->clazyLevel->setCurrentText(clazyChecks);
m_clazyChecksWidget->setEnabled(!config.isReadOnly());
}
void ClangDiagnosticConfigsWidget::setClazyLevelDescription(int index)
{
// Levels descriptions are taken from https://github.com/KDE/clazy
static const QString levelDescriptions[] {
QString(),
tr("Very stable checks, 99.99% safe, no false-positives."),
tr("Similar to level 0, but sometimes (rarely) there might be\n"
"some false-positives."),
tr("Sometimes has false-positives (20-30%)."),
tr("Not always correct, possibly very noisy, might require\n"
"a knowledgeable developer to review, might have a very big\n"
"rate of false-positives, might have bugs.")
};
QTC_ASSERT(m_clazyChecks, return);
m_clazyChecks->levelDescription->setText(levelDescriptions[static_cast<unsigned>(index)]);
}
void ClangDiagnosticConfigsWidget::updateConfig(const ClangDiagnosticConfig &config)
{
m_diagnosticConfigsModel.appendOrUpdate(config);
emit customConfigsChanged(customConfigs());
}
bool ClangDiagnosticConfigsWidget::isConfigChooserEmpty() const
@@ -264,6 +339,18 @@ void ClangDiagnosticConfigsWidget::updateValidityWidgets(const QString &errorMes
m_ui->validationResultLabel->setStyleSheet(styleSheet);
}
void ClangDiagnosticConfigsWidget::connectClangTidyItemChanged()
{
connect(m_tidyChecks->checksList, &QListWidget::itemChanged,
this, &ClangDiagnosticConfigsWidget::onClangTidyItemChanged);
}
void ClangDiagnosticConfigsWidget::disconnectClangTidyItemChanged()
{
disconnect(m_tidyChecks->checksList, &QListWidget::itemChanged,
this, &ClangDiagnosticConfigsWidget::onClangTidyItemChanged);
}
void ClangDiagnosticConfigsWidget::connectConfigChooserCurrentIndex()
{
connect(m_ui->configChooserComboBox,
@@ -314,4 +401,31 @@ void ClangDiagnosticConfigsWidget::refresh(
syncWidgetsToModel(configToSelect);
}
void ClangDiagnosticConfigsWidget::setupPluginsWidgets()
{
m_clazyChecks.reset(new CppTools::Ui::ClazyChecks);
m_clazyChecksWidget = new QWidget();
m_clazyChecks->setupUi(m_clazyChecksWidget);
connect(m_clazyChecks->clazyLevel,
static_cast<void (QComboBox::*)(int index)>(&QComboBox::currentIndexChanged),
[this](int index) {
setClazyLevelDescription(index);
ClangDiagnosticConfig config = currentConfig();
if (index == 0)
config.setClazyChecks(QString());
else
config.setClazyChecks(m_clazyChecks->clazyLevel->itemText(index));
updateConfig(config);
});
m_tidyChecks.reset(new CppTools::Ui::TidyChecks);
m_tidyChecksWidget = new QWidget();
m_tidyChecks->setupUi(m_tidyChecksWidget);
connectClangTidyItemChanged();
m_ui->pluginChecksTabs->addTab(m_tidyChecksWidget, tr("Clang-Tidy"));
m_ui->pluginChecksTabs->addTab(m_clazyChecksWidget, tr("Clazy"));
m_ui->pluginChecksTabs->setCurrentIndex(0);
}
} // CppTools namespace