aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/clangcodemodel
diff options
context:
space:
mode:
authorNikolai Kosjar <nikolai.kosjar@qt.io>2019-01-28 12:40:03 +0100
committerNikolai Kosjar <nikolai.kosjar@qt.io>2019-02-05 15:22:20 +0000
commitf6c46ce35d9018335a19d8d75fda4dfd7adf69b3 (patch)
treed996bc810d2486bc2af3eb4bd57795c7195ce0d0 /src/plugins/clangcodemodel
parentb9d3055e7218e6dc202047c4a341df51c8e8cd67 (diff)
Clang: Add tooltip action to remove specific warnings/checks
...from the diagnostic configuration. If no custom diagnostic configuration is set in Projects Mode > Clang, one is created and set for the current project. Otherwise the current custom diagnostic set in the project settings is modified. Change-Id: I5c48280c90f0e807e7333122d504dda302a8b0a9 Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
Diffstat (limited to 'src/plugins/clangcodemodel')
-rw-r--r--src/plugins/clangcodemodel/clangdiagnostictooltipwidget.cpp50
-rw-r--r--src/plugins/clangcodemodel/clangtextmark.cpp123
-rw-r--r--src/plugins/clangcodemodel/clangutils.cpp46
-rw-r--r--src/plugins/clangcodemodel/clangutils.h17
4 files changed, 188 insertions, 48 deletions
diff --git a/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.cpp b/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.cpp
index 497af71993..5f85a2e226 100644
--- a/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.cpp
+++ b/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.cpp
@@ -25,6 +25,7 @@
#include "clangdiagnostictooltipwidget.h"
#include "clangfixitoperation.h"
+#include "clangutils.h"
#include <coreplugin/editormanager/editormanager.h>
@@ -149,7 +150,7 @@ public:
QTC_CHECK(!"Link target cannot be handled.");
if (hideToolTipAfterLinkActivation)
- Utils::ToolTip::hideImmediately();
+ ::Utils::ToolTip::hideImmediately();
});
return label;
@@ -171,50 +172,6 @@ public:
private:
enum class IndentMode { Indent, DoNotIndent };
- static bool isClazyOption(const QString &option) { return option.startsWith("-Wclazy"); }
-
- class DiagnosticTextInfo
- {
- public:
- DiagnosticTextInfo(const QString &text)
- : m_text(text)
- , m_squareBracketStartIndex(text.lastIndexOf('['))
- {}
-
- QString textWithoutOption() const
- {
- if (m_squareBracketStartIndex == -1)
- return m_text;
-
- return m_text.mid(0, m_squareBracketStartIndex - 1);
- }
-
- QString option() const
- {
- if (m_squareBracketStartIndex == -1)
- return QString();
-
- const int index = m_squareBracketStartIndex + 1;
- return m_text.mid(index, m_text.count() - index - 1);
- }
-
- QString category() const
- {
- if (m_squareBracketStartIndex == -1)
- return QString();
-
- const int index = m_squareBracketStartIndex + 1;
- if (isClazyOption(m_text.mid(index)))
- return QCoreApplication::translate("ClangDiagnosticWidget", "Clazy Issue");
- else
- return QCoreApplication::translate("ClangDiagnosticWidget", "Clang-Tidy Issue");
- }
-
- private:
- const QString m_text;
- const int m_squareBracketStartIndex;
- };
-
// Diagnostics from clazy/tidy do not have any category or option set but
// we will conclude them from the diagnostic message.
//
@@ -233,6 +190,7 @@ private:
ClangBackEnd::DiagnosticContainer supplementedDiagnostic = diagnostic;
+ using namespace ClangCodeModel::Utils;
DiagnosticTextInfo info(diagnostic.text);
supplementedDiagnostic.enableOption = info.option();
supplementedDiagnostic.category = info.category();
@@ -269,7 +227,7 @@ private:
QString option = optionAsUtf8String.toString();
// Clazy
- if (isClazyOption(option)) {
+ if (ClangCodeModel::Utils::DiagnosticTextInfo::isClazyOption(option)) {
option = optionAsUtf8String.mid(8); // Remove "-Wclazy-" prefix.
return QString::fromUtf8(CLAZY_DOCUMENTATION_URL_TEMPLATE).arg(option);
}
diff --git a/src/plugins/clangcodemodel/clangtextmark.cpp b/src/plugins/clangcodemodel/clangtextmark.cpp
index b8dc9a92a4..41ee4c1533 100644
--- a/src/plugins/clangcodemodel/clangtextmark.cpp
+++ b/src/plugins/clangcodemodel/clangtextmark.cpp
@@ -27,11 +27,20 @@
#include "clangconstants.h"
#include "clangdiagnostictooltipwidget.h"
+#include "clangeditordocumentprocessor.h"
+#include "clangmodelmanagersupport.h"
+#include "clangprojectsettings.h"
#include "clangutils.h"
-#include <utils/utilsicons.h>
+#include <coreplugin/icore.h>
+#include <cpptools/clangdiagnosticconfigsmodel.h>
+#include <cpptools/cpptoolsreuse.h>
+#include <cpptools/cppcodemodelsettings.h>
+
+#include <utils/fadingindicator.h>
#include <utils/qtcassert.h>
#include <utils/theme/theme.h>
+#include <utils/utilsicons.h>
#include <QAction>
#include <QApplication>
@@ -64,6 +73,102 @@ static Core::Id categoryForSeverity(ClangBackEnd::DiagnosticSeverity severity)
return isWarningOrNote(severity) ? Constants::CLANG_WARNING : Constants::CLANG_ERROR;
}
+ProjectExplorer::Project *projectForCurrentEditor()
+{
+ using namespace CppTools;
+ using namespace ClangCodeModel::Internal;
+
+ const QString filePath = Utils::currentCppEditorDocumentFilePath();
+ if (filePath.isEmpty())
+ return nullptr;
+
+ if (auto processor = ClangEditorDocumentProcessor::get(filePath)) {
+ if (ProjectPart::Ptr projectPart = processor->projectPart())
+ return projectPart->project;
+ }
+
+ return nullptr;
+}
+
+void disableDiagnosticInConfig(CppTools::ClangDiagnosticConfig &config,
+ const ClangBackEnd::DiagnosticContainer &diagnostic)
+{
+ // Clang check
+ if (!diagnostic.disableOption.isEmpty()) {
+ config.setClangOptions(config.clangOptions() + QStringList(diagnostic.disableOption));
+ return;
+ }
+
+ // Clazy check
+ using namespace ClangCodeModel::Utils;
+ DiagnosticTextInfo textInfo(diagnostic.text);
+ if (DiagnosticTextInfo::isClazyOption(textInfo.option())) {
+ const QString checkName = DiagnosticTextInfo::clazyCheckName(textInfo.option());
+ QStringList newChecks = config.clazyChecks().split(',');
+ newChecks.removeOne(checkName);
+ config.setClazyChecks(newChecks.join(','));
+ return;
+ }
+
+ // Tidy check
+ config.setClangTidyChecks(config.clangTidyChecks() + QString(",-") + textInfo.option());
+}
+
+void disableDiagnosticInCurrentProjectConfig(const ClangBackEnd::DiagnosticContainer &diagnostic)
+{
+ using namespace CppTools;
+ using namespace ClangCodeModel::Internal;
+
+ ProjectExplorer::Project *project = projectForCurrentEditor();
+ QTC_ASSERT(project, return );
+
+ // Get settings
+ ClangProjectSettings &projectSettings = ClangModelManagerSupport::instance()->projectSettings(
+ project);
+ const QSharedPointer<CppCodeModelSettings> globalSettings = codeModelSettings();
+
+ // Get config id
+ Core::Id currentConfigId = projectSettings.warningConfigId();
+ if (projectSettings.useGlobalConfig())
+ currentConfigId = globalSettings->clangDiagnosticConfigId();
+
+ // Get config
+ const ClangDiagnosticConfigs originalConfigs = globalSettings->clangCustomDiagnosticConfigs();
+ ClangDiagnosticConfigsModel configsModel(globalSettings->clangCustomDiagnosticConfigs());
+ QTC_ASSERT(configsModel.hasConfigWithId(currentConfigId), return );
+ ClangDiagnosticConfig config = configsModel.configWithId(currentConfigId);
+
+ // Create copy if needed
+ if (config.isReadOnly()) {
+ const QString name = QCoreApplication::translate("ClangDiagnosticConfig",
+ "Project: %1 (based on %2)")
+ .arg(project->displayName(), config.displayName());
+ config = ClangDiagnosticConfigsModel::createCustomConfig(config, name);
+ }
+
+ // Modify diagnostic config
+ disableDiagnosticInConfig(config, diagnostic);
+ configsModel.appendOrUpdate(config);
+
+ // Set global settings
+ globalSettings->setClangCustomDiagnosticConfigs(configsModel.customConfigs());
+ globalSettings->toSettings(Core::ICore::settings());
+
+ // Set project settings
+ if (projectSettings.useGlobalConfig())
+ projectSettings.setUseGlobalConfig(false);
+ projectSettings.setWarningConfigId(config.id());
+ projectSettings.store();
+
+ // Notify the user about changed project specific settings
+ const QString text
+ = QCoreApplication::translate("ClangDiagnosticConfig",
+ "Changes applied in Projects Mode > Clang Code Model");
+ ::Utils::FadingIndicator::showText(Core::ICore::mainWindow(),
+ text,
+ ::Utils::FadingIndicator::SmallText);
+}
+
} // anonymous namespace
ClangTextMark::ClangTextMark(const FileName &fileName,
@@ -88,6 +193,8 @@ ClangTextMark::ClangTextMark(const FileName &fileName,
: ::Utils::Theme::CodeModel_Error_TextMarkColor);
}
+ // Copy to clipboard action
+ QVector<QAction *> actions;
QAction *action = new QAction();
action->setIcon(QIcon::fromTheme("edit-copy", ::Utils::Icons::COPY.icon()));
QObject::connect(action, &QAction::triggered, [diagnostic]() {
@@ -96,7 +203,19 @@ ClangTextMark::ClangTextMark(const FileName &fileName,
ClangDiagnosticWidget::InfoBar);
QApplication::clipboard()->setText(text, QClipboard::Clipboard);
});
- setActions({action});
+ actions << action;
+
+ // Remove diagnostic warning action
+ if (projectForCurrentEditor()) {
+ action = new QAction();
+ action->setIcon(::Utils::Icons::BROKEN.icon());
+ QObject::connect(action, &QAction::triggered, [diagnostic]() {
+ disableDiagnosticInCurrentProjectConfig(diagnostic);
+ });
+ actions << action;
+ }
+
+ setActions(actions);
}
void ClangTextMark::updateIcon(bool valid)
diff --git a/src/plugins/clangcodemodel/clangutils.cpp b/src/plugins/clangcodemodel/clangutils.cpp
index 8a27a115a2..481b0774f8 100644
--- a/src/plugins/clangcodemodel/clangutils.cpp
+++ b/src/plugins/clangcodemodel/clangutils.cpp
@@ -373,5 +373,51 @@ QString currentCppEditorDocumentFilePath()
return filePath;
}
+DiagnosticTextInfo::DiagnosticTextInfo(const QString &text)
+ : m_text(text)
+ , m_squareBracketStartIndex(text.lastIndexOf('['))
+{}
+
+QString DiagnosticTextInfo::textWithoutOption() const
+{
+ if (m_squareBracketStartIndex == -1)
+ return m_text;
+
+ return m_text.mid(0, m_squareBracketStartIndex - 1);
+}
+
+QString DiagnosticTextInfo::option() const
+{
+ if (m_squareBracketStartIndex == -1)
+ return QString();
+
+ const int index = m_squareBracketStartIndex + 1;
+ return m_text.mid(index, m_text.count() - index - 1);
+}
+
+QString DiagnosticTextInfo::category() const
+{
+ if (m_squareBracketStartIndex == -1)
+ return QString();
+
+ const int index = m_squareBracketStartIndex + 1;
+ if (isClazyOption(m_text.mid(index)))
+ return QCoreApplication::translate("ClangDiagnosticWidget", "Clazy Issue");
+ else
+ return QCoreApplication::translate("ClangDiagnosticWidget", "Clang-Tidy Issue");
+}
+
+bool DiagnosticTextInfo::isClazyOption(const QString &option)
+{
+ return option.startsWith("-Wclazy");
+}
+
+QString DiagnosticTextInfo::clazyCheckName(const QString &option)
+{
+ if (option.startsWith("-Wclazy"))
+ return option.mid(8); // Chop "-Wclazy-"
+ return option;
+}
+
} // namespace Utils
} // namespace Clang
diff --git a/src/plugins/clangcodemodel/clangutils.h b/src/plugins/clangcodemodel/clangutils.h
index b7f705b57b..4db869896b 100644
--- a/src/plugins/clangcodemodel/clangutils.h
+++ b/src/plugins/clangcodemodel/clangutils.h
@@ -72,6 +72,23 @@ QString diagnosticCategoryPrefixRemoved(const QString &text);
void generateCompilationDB(::Utils::FileName projectDir, CppTools::ProjectInfo projectInfo);
+class DiagnosticTextInfo
+{
+public:
+ DiagnosticTextInfo(const QString &text);
+
+ QString textWithoutOption() const;
+ QString option() const;
+ QString category() const;
+
+ static bool isClazyOption(const QString &option);
+ static QString clazyCheckName(const QString &option);
+
+private:
+ const QString m_text;
+ const int m_squareBracketStartIndex;
+};
+
namespace Text {
template <class CharacterProvider>