diff options
author | David Schulz <david.schulz@qt.io> | 2020-04-06 10:09:30 +0200 |
---|---|---|
committer | David Schulz <david.schulz@qt.io> | 2020-04-08 08:56:14 +0000 |
commit | ad1f79075dec8ed6b2e9da7eb250e8865214a88e (patch) | |
tree | 080d3509e3292cf66e06e651bcce4e7665a035a8 /src/plugins/clangtools | |
parent | 7c1f7dd431e864cb841afbc7e994d831034c1ec2 (diff) |
ClangTools: Add text marks for analyzer diagnostics
Bring back the text marks with annotations for diagnostics generated by
clang-tidy and clazy. They are visible as long as the file isn't
modified.
Task-number: QTCREATORBUG-23349
Change-Id: Idf6d01c67c1cc9d1e000a339441f9cf948cdc2b7
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Diffstat (limited to 'src/plugins/clangtools')
-rw-r--r-- | src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp | 86 | ||||
-rw-r--r-- | src/plugins/clangtools/clangtoolsdiagnosticmodel.h | 3 |
2 files changed, 70 insertions, 19 deletions
diff --git a/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp b/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp index b04db2da3b..fdb113f7e3 100644 --- a/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp +++ b/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp @@ -32,6 +32,7 @@ #include <coreplugin/fileiconprovider.h> #include <projectexplorer/project.h> #include <projectexplorer/session.h> +#include <texteditor/textmark.h> #include <utils/qtcassert.h> #include <utils/utilsicons.h> @@ -217,7 +218,15 @@ static QString fixitStatus(FixitStatus status) return QString(); } -static QString createDiagnosticToolTipString(const Diagnostic &diagnostic, FixitStatus fixItStatus) +static QString lineColumnString(const Debugger::DiagnosticLocation &location) +{ + return QString("%1:%2").arg(QString::number(location.line), QString::number(location.column)); +} + +static QString createDiagnosticToolTipString( + const Diagnostic &diagnostic, + Utils::optional<FixitStatus> fixItStatus = Utils::nullopt, + bool showSteps = true) { using StringPair = QPair<QString, QString>; QList<StringPair> lines; @@ -244,9 +253,24 @@ static QString createDiagnosticToolTipString(const Diagnostic &diagnostic, Fixit QCoreApplication::translate("ClangTools::Diagnostic", "Location:"), createFullLocationString(diagnostic.location)); - lines << qMakePair( - QCoreApplication::translate("ClangTools::Diagnostic", "Fixit status:"), - fixitStatus(fixItStatus)); + if (fixItStatus.has_value()) { + lines << qMakePair(QCoreApplication::translate("ClangTools::Diagnostic", "Fixit status:"), + fixitStatus(fixItStatus.value())); + } + + if (showSteps && !diagnostic.explainingSteps.isEmpty()) { + StringPair steps; + steps.first = QCoreApplication::translate("ClangTools::Diagnostic", "Steps:"); + for (const ExplainingStep &step : diagnostic.explainingSteps) { + if (!steps.second.isEmpty()) + steps.second += "<br>"; + steps.second += QString("%1:%2: %3") + .arg(step.location.filePath, + lineColumnString(step.location), + step.message); + } + lines << steps; + } QString html = QLatin1String("<html>" "<head>" @@ -319,11 +343,6 @@ static QString createExplainingStepString(const ExplainingStep &explainingStep, } -static QString lineColumnString(const Debugger::DiagnosticLocation &location) -{ - return QString("%1:%2").arg(QString::number(location.line), QString::number(location.column)); -} - static QString fullText(const Diagnostic &diagnostic) { QString text = diagnostic.location.filePath + QLatin1Char(':'); @@ -346,6 +365,35 @@ static QString fullText(const Diagnostic &diagnostic) return text; } +static Utils::optional<QIcon> iconForType(const QString &type) +{ + if (type == "warning") + return Utils::Icons::CODEMODEL_WARNING.icon(); + if (type == "error" || type == "fatal") + return Utils::Icons::CODEMODEL_ERROR.icon(); + if (type == "note") + return Utils::Icons::INFO.icon(); + if (type == "fix-it") + return Utils::Icons::CODEMODEL_FIXIT.icon(); + return Utils::nullopt; +} + +static TextEditor::TextMark *generateDiagnosticTextMark(const Diagnostic &diag) +{ + auto mark = new TextEditor::TextMark(Utils::FilePath::fromString(diag.location.filePath), + diag.location.line, + Core::Id("ClangTool.DiagnosticMark")); + if (diag.type == "error" || diag.type == "fatal") + mark->setColor(Utils::Theme::CodeModel_Error_TextMarkColor); + else + mark->setColor(Utils::Theme::CodeModel_Warning_TextMarkColor); + mark->setPriority(TextEditor::TextMark::HighPriority); + mark->setIcon(iconForType(diag.type).value_or(Utils::Icons::CODEMODEL_WARNING.icon())); + mark->setToolTip(createDiagnosticToolTipString(diag)); + mark->setLineAnnotation(diag.description); + return mark; +} + DiagnosticItem::DiagnosticItem(const Diagnostic &diag, const OnFixitStatusChanged &onFixitStatusChanged, ClangToolsDiagnosticModel *parent) @@ -356,6 +404,8 @@ DiagnosticItem::DiagnosticItem(const Diagnostic &diag, if (diag.hasFixits) m_fixitStatus = FixitStatus::NotScheduled; + m_mark = generateDiagnosticTextMark(diag); + // Don't show explaining steps if they add no information. if (diag.explainingSteps.count() == 1) { const ExplainingStep &step = diag.explainingSteps.first(); @@ -373,6 +423,7 @@ DiagnosticItem::DiagnosticItem(const Diagnostic &diag, DiagnosticItem::~DiagnosticItem() { setFixitOperations(ReplacementOperations()); + delete m_mark; } Qt::ItemFlags DiagnosticItem::flags(int column) const @@ -385,15 +436,8 @@ Qt::ItemFlags DiagnosticItem::flags(int column) const static QVariant iconData(const QString &type) { - if (type == "warning") - return Utils::Icons::CODEMODEL_WARNING.icon(); - if (type == "error" || type == "fatal") - return Utils::Icons::CODEMODEL_ERROR.icon(); - if (type == "note") - return Utils::Icons::INFO.icon(); - if (type == "fix-it") - return Utils::Icons::CODEMODEL_FIXIT.icon(); - return QVariant(); + Utils::optional<QIcon> icon = iconForType(type); + return icon.has_value() ? QVariant(*icon) : QVariant(); } QVariant DiagnosticItem::data(int column, int role) const @@ -439,7 +483,7 @@ QVariant DiagnosticItem::data(int column, int role) const return QString("%1: %2").arg(lineColumnString(m_diagnostic.location), m_diagnostic.description); case Qt::ToolTipRole: - return createDiagnosticToolTipString(m_diagnostic, m_fixitStatus); + return createDiagnosticToolTipString(m_diagnostic, m_fixitStatus, false); case Qt::DecorationRole: return iconData(m_diagnostic.type); default: @@ -475,6 +519,10 @@ void DiagnosticItem::setFixItStatus(const FixitStatus &status) update(); if (m_onFixitStatusChanged && status != oldStatus) m_onFixitStatusChanged(index(), oldStatus, status); + if (status == FixitStatus::Applied || status == FixitStatus::Invalidated) { + delete m_mark; + m_mark = nullptr; + } } void DiagnosticItem::setFixitOperations(const ReplacementOperations &replacements) diff --git a/src/plugins/clangtools/clangtoolsdiagnosticmodel.h b/src/plugins/clangtools/clangtoolsdiagnosticmodel.h index b27e01b383..fe93a6e1ce 100644 --- a/src/plugins/clangtools/clangtoolsdiagnosticmodel.h +++ b/src/plugins/clangtools/clangtoolsdiagnosticmodel.h @@ -69,6 +69,8 @@ private: const QString m_filePath; }; +class DiagnosticMark; + class DiagnosticItem : public Utils::TreeItem { public: @@ -101,6 +103,7 @@ private: ReplacementOperations m_fixitOperations; FixitStatus m_fixitStatus = FixitStatus::NotAvailable; ClangToolsDiagnosticModel *m_parentModel = nullptr; + TextEditor::TextMark *m_mark = nullptr; }; class ExplainingStepItem; |