From bcf900e29b6ceeb475e11881d5015055db0116f9 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 20 Nov 2020 17:26:26 +0100 Subject: [PATCH] ClangCodeModel: Prevent outdated fix-its from getting applied The code locations might no longer be correct. Fixes: QTCREATORBUG-21818 Change-Id: I866a29d2fd63ff65cf33168024f7788c5f6e3547 Reviewed-by: David Schulz --- .../clangcodemodel/clangdiagnosticmanager.cpp | 3 +- .../clangcodemodel/clangdiagnosticmanager.h | 1 + .../clangdiagnostictooltipwidget.cpp | 32 ++++++++++++------- .../clangdiagnostictooltipwidget.h | 5 ++- src/plugins/clangcodemodel/clangtextmark.cpp | 10 +++--- src/plugins/clangcodemodel/clangtextmark.h | 5 ++- 6 files changed, 37 insertions(+), 19 deletions(-) diff --git a/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp b/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp index c176f084342..4cc9cd7f8fe 100644 --- a/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp +++ b/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp @@ -455,7 +455,8 @@ void ClangDiagnosticManager::addClangTextMarks( auto textMark = new ClangTextMark(::Utils::FilePath::fromString(filePath()), diagnostic, onMarkRemoved, - m_fullVisualization); + m_fullVisualization, + this); m_clangTextMarks.push_back(textMark); m_textDocument->addMark(textMark); } diff --git a/src/plugins/clangcodemodel/clangdiagnosticmanager.h b/src/plugins/clangcodemodel/clangdiagnosticmanager.h index 2996936ed08..9d5b7a6571c 100644 --- a/src/plugins/clangcodemodel/clangdiagnosticmanager.h +++ b/src/plugins/clangcodemodel/clangdiagnosticmanager.h @@ -58,6 +58,7 @@ public: TextEditor::RefactorMarkers takeFixItAvailableMarkers(); QList diagnosticTextMarksAt(uint line, uint column) const; + bool diagnosticsInvalidated() const { return m_diagnosticsInvalidated; } void invalidateDiagnostics(); void clearDiagnosticsWithFixIts(); diff --git a/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.cpp b/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.cpp index ad2f38a78ae..499ae623f6b 100644 --- a/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.cpp +++ b/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.cpp @@ -24,6 +24,8 @@ ****************************************************************************/ #include "clangdiagnostictooltipwidget.h" + +#include "clangdiagnosticmanager.h" #include "clangfixitoperation.h" #include "clangutils.h" @@ -101,7 +103,8 @@ public: { } - QWidget *createWidget(const QVector &diagnostics) + QWidget *createWidget(const QVector &diagnostics, + const ClangDiagnosticManager *diagMgr) { const QString text = htmlText(diagnostics); @@ -129,18 +132,22 @@ public: const TargetIdToDiagnosticTable table = m_targetIdsToDiagnostics; const bool hideToolTipAfterLinkActivation = m_displayHints.hideTooltipAfterLinkActivation; - QObject::connect(label, &QLabel::linkActivated, [table, hideToolTipAfterLinkActivation] - (const QString &action) { + QObject::connect(label, &QLabel::linkActivated, [table, hideToolTipAfterLinkActivation, + diagMgr](const QString &action) { const ClangBackEnd::DiagnosticContainer diagnostic = table.value(action); if (diagnostic == ClangBackEnd::DiagnosticContainer()) QDesktopServices::openUrl(QUrl(action)); - else if (action.startsWith(LINK_ACTION_GOTO_LOCATION)) + else if (action.startsWith(LINK_ACTION_GOTO_LOCATION)) { openEditorAt(diagnostic); - else if (action.startsWith(LINK_ACTION_APPLY_FIX)) - applyFixit(diagnostic); - else + } else if (action.startsWith(LINK_ACTION_APPLY_FIX)) { + if (diagMgr && !diagMgr->diagnosticsInvalidated() + && diagMgr->diagnosticsWithFixIts().contains(diagnostic)) { + applyFixit(diagnostic); + } + } else { QTC_CHECK(!"Link target cannot be handled."); + } if (hideToolTipAfterLinkActivation) ::Utils::ToolTip::hideImmediately(); @@ -394,14 +401,15 @@ private: QString m_mainFilePath; }; -WidgetFromDiagnostics::DisplayHints toHints(const ClangDiagnosticWidget::Destination &destination) +WidgetFromDiagnostics::DisplayHints toHints(const ClangDiagnosticWidget::Destination &destination, + const ClangDiagnosticManager *diagMgr = nullptr) { WidgetFromDiagnostics::DisplayHints hints; if (destination == ClangDiagnosticWidget::ToolTip) { hints.showCategoryAndEnableOption = true; hints.showFileNameInMainDiagnostic = false; - hints.enableClickableFixits = true; + hints.enableClickableFixits = diagMgr && !diagMgr->diagnosticsInvalidated(); hints.limitWidth = true; hints.hideTooltipAfterLinkActivation = true; hints.allowTextSelection = false; @@ -438,10 +446,10 @@ QString ClangDiagnosticWidget::createText( return text; } -QWidget *ClangDiagnosticWidget::createWidget( - const QVector &diagnostics, const Destination &destination) +QWidget *ClangDiagnosticWidget::createWidget(const QVector &diagnostics, + const Destination &destination, const ClangDiagnosticManager *diagMgr) { - return WidgetFromDiagnostics(toHints(destination)).createWidget(diagnostics); + return WidgetFromDiagnostics(toHints(destination, diagMgr)).createWidget(diagnostics, diagMgr); } } // namespace Internal diff --git a/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.h b/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.h index c5f8bb607ee..48fa0726952 100644 --- a/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.h +++ b/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.h @@ -34,6 +34,7 @@ QT_END_NAMESPACE namespace ClangCodeModel { namespace Internal { +class ClangDiagnosticManager; class ClangDiagnosticWidget { public: @@ -41,8 +42,10 @@ public: static QString createText(const QVector &diagnostics, const Destination &destination); + static QWidget *createWidget(const QVector &diagnostics, - const Destination &destination); + const Destination &destination, + const ClangDiagnosticManager *diagMgr = nullptr); }; } // namespace Internal diff --git a/src/plugins/clangcodemodel/clangtextmark.cpp b/src/plugins/clangcodemodel/clangtextmark.cpp index b81b9fc68f8..aee11cb62a1 100644 --- a/src/plugins/clangcodemodel/clangtextmark.cpp +++ b/src/plugins/clangcodemodel/clangtextmark.cpp @@ -210,12 +210,13 @@ void disableDiagnosticInCurrentProjectConfig(const ClangBackEnd::DiagnosticConta ClangTextMark::ClangTextMark(const FilePath &fileName, const ClangBackEnd::DiagnosticContainer &diagnostic, const RemovedFromEditorHandler &removedHandler, - bool fullVisualization) + bool fullVisualization, const ClangDiagnosticManager *diagMgr) : TextEditor::TextMark(fileName, int(diagnostic.location.line), categoryForSeverity(diagnostic.severity)) , m_diagnostic(diagnostic) , m_removedFromEditorHandler(removedHandler) + , m_diagMgr(diagMgr) { const bool warning = isWarningOrNote(diagnostic.severity); setDefaultToolTip(warning ? QApplication::translate("Clang Code Model Marks", "Code Model Warning") @@ -265,8 +266,10 @@ void ClangTextMark::updateIcon(bool valid) bool ClangTextMark::addToolTipContent(QLayout *target) const { - QWidget *widget = ClangDiagnosticWidget::createWidget({m_diagnostic}, - ClangDiagnosticWidget::ToolTip); + + QWidget *widget = ClangDiagnosticWidget::createWidget( + {m_diagnostic}, ClangDiagnosticWidget::ToolTip, + color() == Utils::Theme::Color::IconsDisabledColor ? nullptr : m_diagMgr); target->addWidget(widget); return true; @@ -280,4 +283,3 @@ void ClangTextMark::removedFromEditor() } // namespace Internal } // namespace ClangCodeModel - diff --git a/src/plugins/clangcodemodel/clangtextmark.h b/src/plugins/clangcodemodel/clangtextmark.h index 2ac2df1e916..a7fbdc65268 100644 --- a/src/plugins/clangcodemodel/clangtextmark.h +++ b/src/plugins/clangcodemodel/clangtextmark.h @@ -34,6 +34,7 @@ namespace ClangCodeModel { namespace Internal { +class ClangDiagnosticManager; class ClangTextMark : public TextEditor::TextMark { @@ -43,7 +44,8 @@ public: ClangTextMark(const ::Utils::FilePath &fileName, const ClangBackEnd::DiagnosticContainer &diagnostic, const RemovedFromEditorHandler &removedHandler, - bool fullVisualization); + bool fullVisualization, + const ClangDiagnosticManager *diagMgr); ClangBackEnd::DiagnosticContainer diagnostic() const { return m_diagnostic; } void updateIcon(bool valid = true); @@ -55,6 +57,7 @@ private: private: ClangBackEnd::DiagnosticContainer m_diagnostic; RemovedFromEditorHandler m_removedFromEditorHandler; + const ClangDiagnosticManager * const m_diagMgr; }; } // namespace Internal