forked from qt-creator/qt-creator
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 <david.schulz@qt.io>
This commit is contained in:
@@ -455,7 +455,8 @@ void ClangDiagnosticManager::addClangTextMarks(
|
|||||||
auto textMark = new ClangTextMark(::Utils::FilePath::fromString(filePath()),
|
auto textMark = new ClangTextMark(::Utils::FilePath::fromString(filePath()),
|
||||||
diagnostic,
|
diagnostic,
|
||||||
onMarkRemoved,
|
onMarkRemoved,
|
||||||
m_fullVisualization);
|
m_fullVisualization,
|
||||||
|
this);
|
||||||
m_clangTextMarks.push_back(textMark);
|
m_clangTextMarks.push_back(textMark);
|
||||||
m_textDocument->addMark(textMark);
|
m_textDocument->addMark(textMark);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ public:
|
|||||||
TextEditor::RefactorMarkers takeFixItAvailableMarkers();
|
TextEditor::RefactorMarkers takeFixItAvailableMarkers();
|
||||||
|
|
||||||
QList<TextEditor::TextMark *> diagnosticTextMarksAt(uint line, uint column) const;
|
QList<TextEditor::TextMark *> diagnosticTextMarksAt(uint line, uint column) const;
|
||||||
|
bool diagnosticsInvalidated() const { return m_diagnosticsInvalidated; }
|
||||||
|
|
||||||
void invalidateDiagnostics();
|
void invalidateDiagnostics();
|
||||||
void clearDiagnosticsWithFixIts();
|
void clearDiagnosticsWithFixIts();
|
||||||
|
|||||||
@@ -24,6 +24,8 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "clangdiagnostictooltipwidget.h"
|
#include "clangdiagnostictooltipwidget.h"
|
||||||
|
|
||||||
|
#include "clangdiagnosticmanager.h"
|
||||||
#include "clangfixitoperation.h"
|
#include "clangfixitoperation.h"
|
||||||
#include "clangutils.h"
|
#include "clangutils.h"
|
||||||
|
|
||||||
@@ -101,7 +103,8 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *createWidget(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics)
|
QWidget *createWidget(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
||||||
|
const ClangDiagnosticManager *diagMgr)
|
||||||
{
|
{
|
||||||
const QString text = htmlText(diagnostics);
|
const QString text = htmlText(diagnostics);
|
||||||
|
|
||||||
@@ -129,18 +132,22 @@ public:
|
|||||||
|
|
||||||
const TargetIdToDiagnosticTable table = m_targetIdsToDiagnostics;
|
const TargetIdToDiagnosticTable table = m_targetIdsToDiagnostics;
|
||||||
const bool hideToolTipAfterLinkActivation = m_displayHints.hideTooltipAfterLinkActivation;
|
const bool hideToolTipAfterLinkActivation = m_displayHints.hideTooltipAfterLinkActivation;
|
||||||
QObject::connect(label, &QLabel::linkActivated, [table, hideToolTipAfterLinkActivation]
|
QObject::connect(label, &QLabel::linkActivated, [table, hideToolTipAfterLinkActivation,
|
||||||
(const QString &action) {
|
diagMgr](const QString &action) {
|
||||||
const ClangBackEnd::DiagnosticContainer diagnostic = table.value(action);
|
const ClangBackEnd::DiagnosticContainer diagnostic = table.value(action);
|
||||||
|
|
||||||
if (diagnostic == ClangBackEnd::DiagnosticContainer())
|
if (diagnostic == ClangBackEnd::DiagnosticContainer())
|
||||||
QDesktopServices::openUrl(QUrl(action));
|
QDesktopServices::openUrl(QUrl(action));
|
||||||
else if (action.startsWith(LINK_ACTION_GOTO_LOCATION))
|
else if (action.startsWith(LINK_ACTION_GOTO_LOCATION)) {
|
||||||
openEditorAt(diagnostic);
|
openEditorAt(diagnostic);
|
||||||
else if (action.startsWith(LINK_ACTION_APPLY_FIX))
|
} else if (action.startsWith(LINK_ACTION_APPLY_FIX)) {
|
||||||
applyFixit(diagnostic);
|
if (diagMgr && !diagMgr->diagnosticsInvalidated()
|
||||||
else
|
&& diagMgr->diagnosticsWithFixIts().contains(diagnostic)) {
|
||||||
|
applyFixit(diagnostic);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
QTC_CHECK(!"Link target cannot be handled.");
|
QTC_CHECK(!"Link target cannot be handled.");
|
||||||
|
}
|
||||||
|
|
||||||
if (hideToolTipAfterLinkActivation)
|
if (hideToolTipAfterLinkActivation)
|
||||||
::Utils::ToolTip::hideImmediately();
|
::Utils::ToolTip::hideImmediately();
|
||||||
@@ -394,14 +401,15 @@ private:
|
|||||||
QString m_mainFilePath;
|
QString m_mainFilePath;
|
||||||
};
|
};
|
||||||
|
|
||||||
WidgetFromDiagnostics::DisplayHints toHints(const ClangDiagnosticWidget::Destination &destination)
|
WidgetFromDiagnostics::DisplayHints toHints(const ClangDiagnosticWidget::Destination &destination,
|
||||||
|
const ClangDiagnosticManager *diagMgr = nullptr)
|
||||||
{
|
{
|
||||||
WidgetFromDiagnostics::DisplayHints hints;
|
WidgetFromDiagnostics::DisplayHints hints;
|
||||||
|
|
||||||
if (destination == ClangDiagnosticWidget::ToolTip) {
|
if (destination == ClangDiagnosticWidget::ToolTip) {
|
||||||
hints.showCategoryAndEnableOption = true;
|
hints.showCategoryAndEnableOption = true;
|
||||||
hints.showFileNameInMainDiagnostic = false;
|
hints.showFileNameInMainDiagnostic = false;
|
||||||
hints.enableClickableFixits = true;
|
hints.enableClickableFixits = diagMgr && !diagMgr->diagnosticsInvalidated();
|
||||||
hints.limitWidth = true;
|
hints.limitWidth = true;
|
||||||
hints.hideTooltipAfterLinkActivation = true;
|
hints.hideTooltipAfterLinkActivation = true;
|
||||||
hints.allowTextSelection = false;
|
hints.allowTextSelection = false;
|
||||||
@@ -438,10 +446,10 @@ QString ClangDiagnosticWidget::createText(
|
|||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *ClangDiagnosticWidget::createWidget(
|
QWidget *ClangDiagnosticWidget::createWidget(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
||||||
const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics, const Destination &destination)
|
const Destination &destination, const ClangDiagnosticManager *diagMgr)
|
||||||
{
|
{
|
||||||
return WidgetFromDiagnostics(toHints(destination)).createWidget(diagnostics);
|
return WidgetFromDiagnostics(toHints(destination, diagMgr)).createWidget(diagnostics, diagMgr);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ QT_END_NAMESPACE
|
|||||||
|
|
||||||
namespace ClangCodeModel {
|
namespace ClangCodeModel {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
class ClangDiagnosticManager;
|
||||||
|
|
||||||
class ClangDiagnosticWidget {
|
class ClangDiagnosticWidget {
|
||||||
public:
|
public:
|
||||||
@@ -41,8 +42,10 @@ public:
|
|||||||
|
|
||||||
static QString createText(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
static QString createText(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
||||||
const Destination &destination);
|
const Destination &destination);
|
||||||
|
|
||||||
static QWidget *createWidget(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
static QWidget *createWidget(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
||||||
const Destination &destination);
|
const Destination &destination,
|
||||||
|
const ClangDiagnosticManager *diagMgr = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -210,12 +210,13 @@ void disableDiagnosticInCurrentProjectConfig(const ClangBackEnd::DiagnosticConta
|
|||||||
ClangTextMark::ClangTextMark(const FilePath &fileName,
|
ClangTextMark::ClangTextMark(const FilePath &fileName,
|
||||||
const ClangBackEnd::DiagnosticContainer &diagnostic,
|
const ClangBackEnd::DiagnosticContainer &diagnostic,
|
||||||
const RemovedFromEditorHandler &removedHandler,
|
const RemovedFromEditorHandler &removedHandler,
|
||||||
bool fullVisualization)
|
bool fullVisualization, const ClangDiagnosticManager *diagMgr)
|
||||||
: TextEditor::TextMark(fileName,
|
: TextEditor::TextMark(fileName,
|
||||||
int(diagnostic.location.line),
|
int(diagnostic.location.line),
|
||||||
categoryForSeverity(diagnostic.severity))
|
categoryForSeverity(diagnostic.severity))
|
||||||
, m_diagnostic(diagnostic)
|
, m_diagnostic(diagnostic)
|
||||||
, m_removedFromEditorHandler(removedHandler)
|
, m_removedFromEditorHandler(removedHandler)
|
||||||
|
, m_diagMgr(diagMgr)
|
||||||
{
|
{
|
||||||
const bool warning = isWarningOrNote(diagnostic.severity);
|
const bool warning = isWarningOrNote(diagnostic.severity);
|
||||||
setDefaultToolTip(warning ? QApplication::translate("Clang Code Model Marks", "Code Model Warning")
|
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
|
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);
|
target->addWidget(widget);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -280,4 +283,3 @@ void ClangTextMark::removedFromEditor()
|
|||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace ClangCodeModel
|
} // namespace ClangCodeModel
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
namespace ClangCodeModel {
|
namespace ClangCodeModel {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
class ClangDiagnosticManager;
|
||||||
|
|
||||||
class ClangTextMark : public TextEditor::TextMark
|
class ClangTextMark : public TextEditor::TextMark
|
||||||
{
|
{
|
||||||
@@ -43,7 +44,8 @@ public:
|
|||||||
ClangTextMark(const ::Utils::FilePath &fileName,
|
ClangTextMark(const ::Utils::FilePath &fileName,
|
||||||
const ClangBackEnd::DiagnosticContainer &diagnostic,
|
const ClangBackEnd::DiagnosticContainer &diagnostic,
|
||||||
const RemovedFromEditorHandler &removedHandler,
|
const RemovedFromEditorHandler &removedHandler,
|
||||||
bool fullVisualization);
|
bool fullVisualization,
|
||||||
|
const ClangDiagnosticManager *diagMgr);
|
||||||
|
|
||||||
ClangBackEnd::DiagnosticContainer diagnostic() const { return m_diagnostic; }
|
ClangBackEnd::DiagnosticContainer diagnostic() const { return m_diagnostic; }
|
||||||
void updateIcon(bool valid = true);
|
void updateIcon(bool valid = true);
|
||||||
@@ -55,6 +57,7 @@ private:
|
|||||||
private:
|
private:
|
||||||
ClangBackEnd::DiagnosticContainer m_diagnostic;
|
ClangBackEnd::DiagnosticContainer m_diagnostic;
|
||||||
RemovedFromEditorHandler m_removedFromEditorHandler;
|
RemovedFromEditorHandler m_removedFromEditorHandler;
|
||||||
|
const ClangDiagnosticManager * const m_diagMgr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
Reference in New Issue
Block a user