diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index d353d06dbc7..2b33d44e578 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -496,7 +496,7 @@ private: m_diagnosticConfigId = diagnosticConfig.id(); m_options.append(diagnosticConfig.clangOptions()); - addClangTidyOptions(diagnosticConfig.clangTidyChecks()); + addClangTidyOptions(diagnosticConfig); addClazyOptions(diagnosticConfig.clazyChecks()); } @@ -510,13 +510,26 @@ private: } } - void addClangTidyOptions(const QString &checks) + void addClangTidyOptions(const CppTools::ClangDiagnosticConfig &diagnosticConfig) { - if (checks.isEmpty()) + using Mode = CppTools::ClangDiagnosticConfig::TidyMode; + Mode tidyMode = diagnosticConfig.clangTidyMode(); + if (tidyMode == Mode::Disabled) return; + QString checks; + if (tidyMode == Mode::ChecksPrefixList) { + checks = QStringLiteral("-*") + diagnosticConfig.clangTidyChecksPrefixes(); + } else if (tidyMode == Mode::ChecksString) { + checks = diagnosticConfig.clangTidyChecksString(); + checks = checks.simplified(); + checks.replace(" ", ""); + } + addXclangArg("-add-plugin", "clang-tidy"); - addXclangArg("-plugin-arg-clang-tidy", "-checks='-*" + checks + "'"); + + if (!checks.isEmpty()) + addXclangArg("-plugin-arg-clang-tidy", "-checks=" + checks); } void addClazyOptions(const QString &checks) diff --git a/src/plugins/cpptools/clangdiagnosticconfig.cpp b/src/plugins/cpptools/clangdiagnosticconfig.cpp index c605d128008..724f4404e52 100644 --- a/src/plugins/cpptools/clangdiagnosticconfig.cpp +++ b/src/plugins/cpptools/clangdiagnosticconfig.cpp @@ -72,7 +72,9 @@ bool ClangDiagnosticConfig::operator==(const ClangDiagnosticConfig &other) const return m_id == other.m_id && m_displayName == other.m_displayName && m_clangOptions == other.m_clangOptions - && m_clangTidyChecks == other.m_clangTidyChecks + && m_clangTidyMode == other.m_clangTidyMode + && m_clangTidyChecksPrefixes == other.m_clangTidyChecksPrefixes + && m_clangTidyChecksString == other.m_clangTidyChecksString && m_clazyChecks == other.m_clazyChecks && m_isReadOnly == other.m_isReadOnly; } @@ -82,14 +84,34 @@ bool ClangDiagnosticConfig::operator!=(const ClangDiagnosticConfig &other) const return !(*this == other); } -QString ClangDiagnosticConfig::clangTidyChecks() const +ClangDiagnosticConfig::TidyMode ClangDiagnosticConfig::clangTidyMode() const { - return m_clangTidyChecks; + return m_clangTidyMode; } -void ClangDiagnosticConfig::setClangTidyChecks(const QString &checks) +void ClangDiagnosticConfig::setClangTidyMode(TidyMode mode) { - m_clangTidyChecks = checks; + m_clangTidyMode = mode; +} + +QString ClangDiagnosticConfig::clangTidyChecksPrefixes() const +{ + return m_clangTidyChecksPrefixes; +} + +void ClangDiagnosticConfig::setClangTidyChecksPrefixes(const QString &checks) +{ + m_clangTidyChecksPrefixes = checks; +} + +QString ClangDiagnosticConfig::clangTidyChecksString() const +{ + return m_clangTidyChecksString; +} + +void ClangDiagnosticConfig::setClangTidyChecksString(const QString &checks) +{ + m_clangTidyChecksString = checks; } QString ClangDiagnosticConfig::clazyChecks() const diff --git a/src/plugins/cpptools/clangdiagnosticconfig.h b/src/plugins/cpptools/clangdiagnosticconfig.h index 327d2f504ea..536ce39606b 100644 --- a/src/plugins/cpptools/clangdiagnosticconfig.h +++ b/src/plugins/cpptools/clangdiagnosticconfig.h @@ -37,6 +37,14 @@ namespace CppTools { class CPPTOOLS_EXPORT ClangDiagnosticConfig { public: + enum class TidyMode + { + Disabled = 0, + ChecksPrefixList, + ChecksString, + File + }; + Core::Id id() const; void setId(const Core::Id &id); @@ -46,8 +54,14 @@ public: QStringList clangOptions() const; void setClangOptions(const QStringList &options); - QString clangTidyChecks() const; - void setClangTidyChecks(const QString &checks); + QString clangTidyChecksPrefixes() const; + void setClangTidyChecksPrefixes(const QString &checks); + + QString clangTidyChecksString() const; + void setClangTidyChecksString(const QString &checks); + + TidyMode clangTidyMode() const; + void setClangTidyMode(TidyMode mode); QString clazyChecks() const; void setClazyChecks(const QString &checks); @@ -62,7 +76,9 @@ private: Core::Id m_id; QString m_displayName; QStringList m_clangOptions; - QString m_clangTidyChecks; + TidyMode m_clangTidyMode; + QString m_clangTidyChecksPrefixes; + QString m_clangTidyChecksString; QString m_clazyChecks; bool m_isReadOnly = false; }; diff --git a/src/plugins/cpptools/clangdiagnosticconfigswidget.cpp b/src/plugins/cpptools/clangdiagnosticconfigswidget.cpp index e7705f7460b..bf6c0553661 100644 --- a/src/plugins/cpptools/clangdiagnosticconfigswidget.cpp +++ b/src/plugins/cpptools/clangdiagnosticconfigswidget.cpp @@ -112,15 +112,30 @@ void ClangDiagnosticConfigsWidget::onRemoveButtonClicked() syncConfigChooserToModel(); } +void ClangDiagnosticConfigsWidget::onClangTidyModeChanged(int index) +{ + ClangDiagnosticConfig config = currentConfig(); + config.setClangTidyMode(static_cast(index)); + updateConfig(config); + syncClangTidyWidgets(config); +} + void ClangDiagnosticConfigsWidget::onClangTidyItemChanged(QListWidgetItem *item) { const QString prefix = item->text(); ClangDiagnosticConfig config = currentConfig(); - QString checks = config.clangTidyChecks(); + QString checks = config.clangTidyChecksPrefixes(); item->checkState() == Qt::Checked ? checks.append(',' + prefix) : checks.remove(',' + prefix); - config.setClangTidyChecks(checks); + config.setClangTidyChecksPrefixes(checks); + updateConfig(config); +} + +void ClangDiagnosticConfigsWidget::onClangTidyLineEdited(const QString &text) +{ + ClangDiagnosticConfig config = currentConfig(); + config.setClangTidyChecksString(text); updateConfig(config); } @@ -271,9 +286,35 @@ void ClangDiagnosticConfigsWidget::syncClangTidyWidgets(const ClangDiagnosticCon { disconnectClangTidyItemChanged(); - const QString tidyChecks = config.clangTidyChecks(); - for (int row = 0; row < m_tidyChecks->checksList->count(); ++row) { - QListWidgetItem *item = m_tidyChecks->checksList->item(row); + ClangDiagnosticConfig::TidyMode tidyMode = config.clangTidyMode(); + + m_tidyChecks->tidyMode->setCurrentIndex(static_cast(tidyMode)); + switch (tidyMode) { + case ClangDiagnosticConfig::TidyMode::Disabled: + case ClangDiagnosticConfig::TidyMode::File: + m_tidyChecks->checksString->setVisible(false); + m_tidyChecks->checksListWrapper->setCurrentIndex(1); + break; + case ClangDiagnosticConfig::TidyMode::ChecksString: + m_tidyChecks->checksString->setVisible(true); + m_tidyChecks->checksListWrapper->setCurrentIndex(1); + m_tidyChecks->checksString->setText(config.clangTidyChecksString()); + break; + case ClangDiagnosticConfig::TidyMode::ChecksPrefixList: + m_tidyChecks->checksString->setVisible(false); + m_tidyChecks->checksListWrapper->setCurrentIndex(0); + syncTidyChecksList(config); + break; + } + + connectClangTidyItemChanged(); +} + +void ClangDiagnosticConfigsWidget::syncTidyChecksList(const ClangDiagnosticConfig &config) +{ + const QString tidyChecks = config.clangTidyChecksPrefixes(); + for (int row = 0; row < m_tidyChecks->checksPrefixesList->count(); ++row) { + QListWidgetItem *item = m_tidyChecks->checksPrefixesList->item(row); Qt::ItemFlags flags = item->flags(); flags |= Qt::ItemIsUserCheckable; @@ -288,8 +329,6 @@ void ClangDiagnosticConfigsWidget::syncClangTidyWidgets(const ClangDiagnosticCon else item->setCheckState(Qt::Unchecked); } - - connectClangTidyItemChanged(); } void ClangDiagnosticConfigsWidget::syncClazyWidgets(const ClangDiagnosticConfig &config) @@ -362,14 +401,26 @@ void ClangDiagnosticConfigsWidget::updateValidityWidgets(const QString &errorMes void ClangDiagnosticConfigsWidget::connectClangTidyItemChanged() { - connect(m_tidyChecks->checksList, &QListWidget::itemChanged, + connect(m_tidyChecks->tidyMode, + static_cast(&QComboBox::currentIndexChanged), + this, + &ClangDiagnosticConfigsWidget::onClangTidyModeChanged); + connect(m_tidyChecks->checksPrefixesList, &QListWidget::itemChanged, this, &ClangDiagnosticConfigsWidget::onClangTidyItemChanged); + connect(m_tidyChecks->checksString, &QLineEdit::textEdited, + this, &ClangDiagnosticConfigsWidget::onClangTidyLineEdited); } void ClangDiagnosticConfigsWidget::disconnectClangTidyItemChanged() { - disconnect(m_tidyChecks->checksList, &QListWidget::itemChanged, + disconnect(m_tidyChecks->tidyMode, + static_cast(&QComboBox::currentIndexChanged), + this, + &ClangDiagnosticConfigsWidget::onClangTidyModeChanged); + disconnect(m_tidyChecks->checksPrefixesList, &QListWidget::itemChanged, this, &ClangDiagnosticConfigsWidget::onClangTidyItemChanged); + disconnect(m_tidyChecks->checksString, &QLineEdit::textEdited, + this, &ClangDiagnosticConfigsWidget::onClangTidyLineEdited); } void ClangDiagnosticConfigsWidget::connectClazyRadioButtonClicked(QRadioButton *button) diff --git a/src/plugins/cpptools/clangdiagnosticconfigswidget.h b/src/plugins/cpptools/clangdiagnosticconfigswidget.h index 1d57797a561..e9d610f7796 100644 --- a/src/plugins/cpptools/clangdiagnosticconfigswidget.h +++ b/src/plugins/cpptools/clangdiagnosticconfigswidget.h @@ -76,7 +76,9 @@ private: void onCurrentConfigChanged(int); void onCopyButtonClicked(); void onRemoveButtonClicked(); + void onClangTidyModeChanged(int index); void onClangTidyItemChanged(QListWidgetItem *item); + void onClangTidyLineEdited(const QString &text); void onClazyRadioButtonChanged(bool checked); void onDiagnosticOptionsEdited(); @@ -86,6 +88,7 @@ private: void syncOtherWidgetsToComboBox(); void syncClangTidyWidgets(const ClangDiagnosticConfig &config); void syncClazyWidgets(const ClangDiagnosticConfig &config); + void syncTidyChecksList(const ClangDiagnosticConfig &config); void updateConfig(const CppTools::ClangDiagnosticConfig &config); diff --git a/src/plugins/cpptools/cppcodemodelsettings.cpp b/src/plugins/cpptools/cppcodemodelsettings.cpp index cc39f001299..6b54c266e0d 100644 --- a/src/plugins/cpptools/cppcodemodelsettings.cpp +++ b/src/plugins/cpptools/cppcodemodelsettings.cpp @@ -55,9 +55,15 @@ static QString clangDiagnosticConfigsArrayDisplayNameKey() static QString clangDiagnosticConfigsArrayWarningsKey() { return QLatin1String("diagnosticOptions"); } -static QString clangDiagnosticConfigsArrayClangTidyChecksKey() +static QString clangDiagnosticConfigsArrayClangTidyChecksPrefixesKey() { return QLatin1String("clangTidyChecks"); } +static QString clangDiagnosticConfigsArrayClangTidyChecksStringKey() +{ return QLatin1String("clangTidyChecksString"); } + +static QString clangDiagnosticConfigsArrayClangTidyModeKey() +{ return QLatin1String("clangTidyMode"); } + static QString clangDiagnosticConfigsArrayClazyChecksKey() { return QLatin1String("clazyChecks"); } @@ -88,7 +94,12 @@ static ClangDiagnosticConfigs customDiagnosticConfigsFromSettings(QSettings *s) config.setId(Core::Id::fromSetting(s->value(clangDiagnosticConfigsArrayIdKey()))); config.setDisplayName(s->value(clangDiagnosticConfigsArrayDisplayNameKey()).toString()); config.setClangOptions(s->value(clangDiagnosticConfigsArrayWarningsKey()).toStringList()); - config.setClangTidyChecks(s->value(clangDiagnosticConfigsArrayClangTidyChecksKey()).toString()); + config.setClangTidyMode(static_cast( + s->value(clangDiagnosticConfigsArrayClangTidyModeKey()).toInt())); + config.setClangTidyChecksPrefixes( + s->value(clangDiagnosticConfigsArrayClangTidyChecksPrefixesKey()).toString()); + config.setClangTidyChecksString( + s->value(clangDiagnosticConfigsArrayClangTidyChecksStringKey()).toString()); config.setClazyChecks(s->value(clangDiagnosticConfigsArrayClazyChecksKey()).toString()); configs.append(config); } @@ -144,7 +155,12 @@ void CppCodeModelSettings::toSettings(QSettings *s) s->setValue(clangDiagnosticConfigsArrayIdKey(), config.id().toSetting()); s->setValue(clangDiagnosticConfigsArrayDisplayNameKey(), config.displayName()); s->setValue(clangDiagnosticConfigsArrayWarningsKey(), config.clangOptions()); - s->setValue(clangDiagnosticConfigsArrayClangTidyChecksKey(), config.clangTidyChecks()); + s->setValue(clangDiagnosticConfigsArrayClangTidyModeKey(), + static_cast(config.clangTidyMode())); + s->setValue(clangDiagnosticConfigsArrayClangTidyChecksPrefixesKey(), + config.clangTidyChecksPrefixes()); + s->setValue(clangDiagnosticConfigsArrayClangTidyChecksStringKey(), + config.clangTidyChecksString()); s->setValue(clangDiagnosticConfigsArrayClazyChecksKey(), config.clazyChecks()); } s->endArray(); diff --git a/src/plugins/cpptools/tidychecks.ui b/src/plugins/cpptools/tidychecks.ui index a9190b894d6..0d144f956e5 100644 --- a/src/plugins/cpptools/tidychecks.ui +++ b/src/plugins/cpptools/tidychecks.ui @@ -15,99 +15,192 @@ - 0 + 9 - 0 + 9 - 0 + 9 - 0 + 9 - + - - android-* - + + + + Disable + + + + + Select Clang-Tidy prefixes + + + + + Provide Clang-Tidy checks string + + + + + Use .clang-tidy config file + + + - - boost-* - - - - - bugprone-* - - - - - cert-* - - - - - cppcoreguidelines-* - - - - - clang-analyzer-* - - - - - clang-diagnostic-* - - - - - google-* - - - - - hicpp-* - - - - - llvm-* - - - - - misc-* - - - - - modernize-* - - - - - mpi-* - - - - - objc-* - - - - - performance-* - - - - - readability-* - + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + android-* + + + + + boost-* + + + + + bugprone-* + + + + + cert-* + + + + + cppcoreguidelines-* + + + + + clang-analyzer-* + + + + + clang-diagnostic-* + + + + + google-* + + + + + hicpp-* + + + + + llvm-* + + + + + misc-* + + + + + modernize-* + + + + + mpi-* + + + + + objc-* + + + + + performance-* + + + + + readability-* + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Vertical + + + + 20 + 237 + + + + + +