From 7be7d268148b84257c9626b53f58b5de4afb766c Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 12 Apr 2018 14:49:07 +0200 Subject: [PATCH] Clang: Show current editor diagnostics in issues pane This helps to deal with many diagnostics. Error diagnostics precede warning diagnostis to have them on top. If no CppEditor is active, no diagnostics are displayed. Previously one had to scroll the document up and down to locate the diagnostics. Now they are in a list and can be easily navigated with F6/Shift-F6. Also, at least for some diagnostics "Get Help Online" from the context menu seems to provide useful results. For example, triggering the action on clang tidy issues will open the web browser with some good hits explaining the issues. Change-Id: Idabe30b0961d893bee39ccee431e92aeeda1cc26 Reviewed-by: David Schulz --- .../clangcodemodel/clangcodemodelplugin.cpp | 4 ++ src/plugins/clangcodemodel/clangconstants.h | 2 + .../clangcodemodel/clangdiagnosticmanager.cpp | 57 +++++++++++++++++++ .../clangcodemodel/clangdiagnosticmanager.h | 3 + .../clangeditordocumentprocessor.cpp | 10 ++++ .../clangeditordocumentprocessor.h | 3 + .../clangmodelmanagersupport.cpp | 13 ++++- 7 files changed, 91 insertions(+), 1 deletion(-) diff --git a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp index cea921c3fed..b2c44f0e901 100644 --- a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp +++ b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include @@ -64,6 +65,9 @@ bool ClangCodeModelPlugin::initialize(const QStringList &arguments, QString *err Q_UNUSED(arguments); Q_UNUSED(errorMessage); + ProjectExplorer::TaskHub::addCategory(Constants::TASK_CATEGORY_DIAGNOSTICS, + tr("Clang Code Model")); + connect(ProjectExplorer::ProjectExplorerPlugin::instance(), &ProjectExplorer::ProjectExplorerPlugin::finishedInitialization, this, diff --git a/src/plugins/clangcodemodel/clangconstants.h b/src/plugins/clangcodemodel/clangconstants.h index 6197ba54128..294618aa88c 100644 --- a/src/plugins/clangcodemodel/clangconstants.h +++ b/src/plugins/clangcodemodel/clangconstants.h @@ -32,5 +32,7 @@ const char CLANG_MODELMANAGERSUPPORT_ID[] = "ClangCodeModel.ClangCodeModel"; const char CLANG_ERROR[] = "Clang.Error"; const char CLANG_WARNING[] = "Clang.Warning"; +const char TASK_CATEGORY_DIAGNOSTICS[] = "ClangCodeModel"; + } // namespace Constants } // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp b/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp index 3be5408f5a8..9923d849179 100644 --- a/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp +++ b/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp @@ -23,6 +23,7 @@ ** ****************************************************************************/ +#include "clangconstants.h" #include "clangdiagnosticfilter.h" #include "clangdiagnosticmanager.h" #include "clangisdiagnosticrelatedtolocation.h" @@ -33,6 +34,8 @@ #include +#include + #include #include #include @@ -42,6 +45,7 @@ #include #include #include +#include #include #include @@ -315,6 +319,56 @@ void ClangDiagnosticManager::generateFixItAvailableMarkers() addFixItAvailableMarker(m_errorDiagnostics, lineNumbersWithFixItMarker); } +static void addTask(const ClangBackEnd::DiagnosticContainer &diagnostic, bool isChild = false) +{ + using namespace ProjectExplorer; + using ::Utils::FileName; + + Task::TaskType taskType = ProjectExplorer::Task::TaskType::Unknown; + FileName iconPath; + QIcon icon; + + if (!isChild) { + switch (diagnostic.severity) { + case ClangBackEnd::DiagnosticSeverity::Fatal: + case ClangBackEnd::DiagnosticSeverity::Error: + taskType = Task::TaskType::Error; + icon = ::Utils::Icons::CODEMODEL_ERROR.icon(); + break; + case ClangBackEnd::DiagnosticSeverity::Warning: + taskType = Task::TaskType::Warning; + icon = ::Utils::Icons::CODEMODEL_WARNING.icon(); + break; + default: + break; + } + } + + TaskHub::addTask(Task(taskType, + diagnostic.text.toString(), + FileName::fromString(diagnostic.location.filePath.toString()), + diagnostic.location.line, + Constants::TASK_CATEGORY_DIAGNOSTICS, + icon, + /*addTextMark =*/ false)); +} + +void ClangDiagnosticManager::clearTaskHubIssues() +{ + ProjectExplorer::TaskHub::clearTasks(Constants::TASK_CATEGORY_DIAGNOSTICS); +} + +void ClangDiagnosticManager::generateTaskHubIssues() +{ + const QVector diagnostics = m_errorDiagnostics + + m_warningDiagnostics; + for (const ClangBackEnd::DiagnosticContainer &diagnostic : diagnostics) { + addTask(diagnostic); + for (const ClangBackEnd::DiagnosticContainer &child : diagnostic.children) + addTask(child, /*isChild = */ true); + } +} + QList ClangDiagnosticManager::takeExtraSelections() { auto extraSelections = m_extraSelections; @@ -401,6 +455,9 @@ void ClangDiagnosticManager::processNewDiagnostics( generateTextMarks(); }); } + + clearTaskHubIssues(); + generateTaskHubIssues(); } const QVector & diff --git a/src/plugins/clangcodemodel/clangdiagnosticmanager.h b/src/plugins/clangcodemodel/clangdiagnosticmanager.h index dff768a09d4..c895735e8d3 100644 --- a/src/plugins/clangcodemodel/clangdiagnosticmanager.h +++ b/src/plugins/clangcodemodel/clangdiagnosticmanager.h @@ -63,6 +63,9 @@ public: void invalidateDiagnostics(); void clearDiagnosticsWithFixIts(); + static void clearTaskHubIssues(); + void generateTaskHubIssues(); + private: void cleanMarks(); QString filePath() const; diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index 8a0e03deb38..a3f08b12c7c 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -241,6 +241,16 @@ const QVector return m_tokenInfos; } +void ClangEditorDocumentProcessor::clearTaskHubIssues() +{ + m_diagnosticManager.clearTaskHubIssues(); +} + +void ClangEditorDocumentProcessor::generateTaskHubIssues() +{ + m_diagnosticManager.generateTaskHubIssues(); +} + void ClangEditorDocumentProcessor::updateHighlighting( const QVector &tokenInfos, const QVector &skippedPreprocessorRanges, diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h index cd28c310cf3..018536be210 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h @@ -103,6 +103,9 @@ public: const QVector &tokenInfos() const; + void clearTaskHubIssues(); + void generateTaskHubIssues(); + public: static ClangEditorDocumentProcessor *get(const QString &filePath); diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index ce7505a3dcf..f0bb8d92981 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -160,9 +160,20 @@ CppTools::BaseEditorDocumentProcessor *ModelManagerSupportClang::createEditorDoc return new ClangEditorDocumentProcessor(m_communicator, baseTextDocument); } -void ModelManagerSupportClang::onCurrentEditorChanged(Core::IEditor *) +void ModelManagerSupportClang::onCurrentEditorChanged(Core::IEditor *editor) { m_communicator.updateTranslationUnitVisiblity(); + + // Update task hub issues for current CppEditorDocument + QTC_ASSERT(editor, return); + Core::IDocument *document = editor->document(); + QTC_ASSERT(document, return); + TextEditor::TextDocument *textDocument = qobject_cast(document); + + auto processor = ClangEditorDocumentProcessor::get(document->filePath().toString()); + processor->clearTaskHubIssues(); + if (textDocument && cppModelManager()->isCppEditor(editor)) + processor->generateTaskHubIssues(); } void ModelManagerSupportClang::connectTextDocumentToTranslationUnit(TextEditor::TextDocument *textDocument)