From 09e495f01a6ef1592b51dde08f459fadafaa9e05 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Tue, 7 Nov 2023 11:05:48 +0100 Subject: [PATCH] ClangCodeModel: Fall back to built-in code model when following symbols In normal interactive mode, users likely want fuzzy look-up, e.g. to a non-matching overload if no exact match is present. Fixes: QTCREATORBUG-29814 Change-Id: I55ca32c001e619d374cc015a7dd2f1564ed2a2c9 Reviewed-by: Christian Stenger Reviewed-by: David Schulz --- src/plugins/clangcodemodel/clangdfollowsymbol.cpp | 3 +-- .../clangcodemodel/clangmodelmanagersupport.cpp | 15 +++++++++++++-- .../clangcodemodel/clangmodelmanagersupport.h | 5 +++-- .../cppeditor/cppbuiltinmodelmanagersupport.cpp | 5 +++++ .../cppeditor/cppbuiltinmodelmanagersupport.h | 2 +- src/plugins/cppeditor/cppeditorwidget.cpp | 5 +++-- src/plugins/cppeditor/cppmodelmanager.cpp | 7 ++++--- src/plugins/cppeditor/cppmodelmanager.h | 4 +++- src/plugins/cppeditor/cppmodelmanagersupport.h | 3 ++- src/plugins/cppeditor/cppquickfixes.cpp | 4 +++- src/plugins/cppeditor/cpptoolsreuse.h | 2 ++ 11 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/plugins/clangcodemodel/clangdfollowsymbol.cpp b/src/plugins/clangcodemodel/clangdfollowsymbol.cpp index 8be15c7327d..aa3f2e69abe 100644 --- a/src/plugins/clangcodemodel/clangdfollowsymbol.cpp +++ b/src/plugins/clangcodemodel/clangdfollowsymbol.cpp @@ -199,8 +199,7 @@ void ClangdFollowSymbol::emitDone(const Link &link) return; d->done = true; - if (link.hasValidTarget()) - d->callback(link); + d->callback(link); emit done(); } diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index caefe586308..6ffd946bafe 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -299,17 +300,27 @@ ClangModelManagerSupport::~ClangModelManagerSupport() void ClangModelManagerSupport::followSymbol(const CursorInEditor &data, const LinkHandler &processLinkCallback, + FollowSymbolMode mode, bool resolveTarget, bool inNextSplit) { if (ClangdClient * const client = clientForFile(data.filePath()); client && client->isFullyIndexed()) { + LinkHandler extendedCallback = [editor = QPointer(data.editorWidget()), data, + processLinkCallback, mode, resolveTarget, inNextSplit] + (const Link &link) { + if (link.hasValidTarget() || mode == FollowSymbolMode::Exact || !editor) + return processLinkCallback(link); + CppModelManager::followSymbol(data, processLinkCallback, resolveTarget, inNextSplit, + mode, CppModelManager::Backend::Builtin); + + }; client->followSymbol(data.textDocument(), data.cursor(), data.editorWidget(), - processLinkCallback, resolveTarget, FollowTo::SymbolDef, inNextSplit); + extendedCallback, resolveTarget, FollowTo::SymbolDef, inNextSplit); return; } CppModelManager::followSymbol(data, processLinkCallback, resolveTarget, inNextSplit, - CppModelManager::Backend::Builtin); + mode, CppModelManager::Backend::Builtin); } void ClangModelManagerSupport::followSymbolToType(const CursorInEditor &data, diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.h b/src/plugins/clangcodemodel/clangmodelmanagersupport.h index 595bfdd7950..a598bea8bbd 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.h +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.h @@ -52,8 +52,9 @@ public: private: void followSymbol(const CppEditor::CursorInEditor &data, - const Utils::LinkHandler &processLinkCallback, bool resolveTarget, - bool inNextSplit) override; + const Utils::LinkHandler &processLinkCallback, + CppEditor::FollowSymbolMode mode, + bool resolveTarget, bool inNextSplit) override; void followSymbolToType(const CppEditor::CursorInEditor &data, const Utils::LinkHandler &processLinkCallback, bool inNextSplit) override; diff --git a/src/plugins/cppeditor/cppbuiltinmodelmanagersupport.cpp b/src/plugins/cppeditor/cppbuiltinmodelmanagersupport.cpp index 01a208f7032..4d20932e3c0 100644 --- a/src/plugins/cppeditor/cppbuiltinmodelmanagersupport.cpp +++ b/src/plugins/cppeditor/cppbuiltinmodelmanagersupport.cpp @@ -101,8 +101,13 @@ TextEditor::BaseHoverHandler *BuiltinModelManagerSupport::createHoverHandler() void BuiltinModelManagerSupport::followSymbol(const CursorInEditor &data, const Utils::LinkHandler &processLinkCallback, + FollowSymbolMode mode, bool resolveTarget, bool inNextSplit) { + // findMatchingDefinition() has an "strict" parameter, but it doesn't seem worth to + // pass the mode down all the way. In practice, we are always fuzzy. + Q_UNUSED(mode) + SymbolFinder finder; m_followSymbol->findLink(data, processLinkCallback, resolveTarget, CppModelManager::snapshot(), diff --git a/src/plugins/cppeditor/cppbuiltinmodelmanagersupport.h b/src/plugins/cppeditor/cppbuiltinmodelmanagersupport.h index 04de866d5ce..8ecbe856b65 100644 --- a/src/plugins/cppeditor/cppbuiltinmodelmanagersupport.h +++ b/src/plugins/cppeditor/cppbuiltinmodelmanagersupport.h @@ -29,7 +29,7 @@ public: private: void followSymbol(const CursorInEditor &data, const Utils::LinkHandler &processLinkCallback, - bool resolveTarget, bool inNextSplit) override; + FollowSymbolMode mode, bool resolveTarget, bool inNextSplit) override; void followSymbolToType(const CursorInEditor &data, const Utils::LinkHandler &processLinkCallback, bool inNextSplit) override; diff --git a/src/plugins/cppeditor/cppeditorwidget.cpp b/src/plugins/cppeditor/cppeditorwidget.cpp index 9666dc48a7d..d215d2ba4e6 100644 --- a/src/plugins/cppeditor/cppeditorwidget.cpp +++ b/src/plugins/cppeditor/cppeditorwidget.cpp @@ -625,7 +625,7 @@ void CppEditorWidget::renameUsages(const QString &replacement, QTextCursor curso }; CppModelManager::followSymbol( CursorInEditor{cursor, textDocument()->filePath(), this, textDocument()}, - continuation, true, false); + continuation, true, false, FollowSymbolMode::Exact); } void CppEditorWidget::renameUsages(const Utils::FilePath &filePath, const QString &replacement, @@ -986,7 +986,8 @@ void CppEditorWidget::findLinkAt(const QTextCursor &cursor, CppModelManager::followSymbol(CursorInEditor{cursor, filePath, this, textDocument()}, callbackWrapper, resolveTarget, - inNextSplit); + inNextSplit, + FollowSymbolMode::Fuzzy); } void CppEditorWidget::findTypeAt(const QTextCursor &cursor, diff --git a/src/plugins/cppeditor/cppmodelmanager.cpp b/src/plugins/cppeditor/cppmodelmanager.cpp index 52f0ea89845..7ff5a2522f4 100644 --- a/src/plugins/cppeditor/cppmodelmanager.cpp +++ b/src/plugins/cppeditor/cppmodelmanager.cpp @@ -2065,10 +2065,11 @@ TextEditor::BaseHoverHandler *CppModelManager::createHoverHandler() void CppModelManager::followSymbol(const CursorInEditor &data, const LinkHandler &processLinkCallback, - bool resolveTarget, bool inNextSplit, Backend backend) + bool resolveTarget, bool inNextSplit, + FollowSymbolMode mode, Backend backend) { - modelManagerSupport(backend)->followSymbol(data, processLinkCallback, - resolveTarget, inNextSplit); + modelManagerSupport(backend)->followSymbol(data, processLinkCallback, mode, + resolveTarget, inNextSplit); } void CppModelManager::followSymbolToType(const CursorInEditor &data, diff --git a/src/plugins/cppeditor/cppmodelmanager.h b/src/plugins/cppeditor/cppmodelmanager.h index bdda63ee550..8867d5cd0f2 100644 --- a/src/plugins/cppeditor/cppmodelmanager.h +++ b/src/plugins/cppeditor/cppmodelmanager.h @@ -5,6 +5,7 @@ #include "cppeditor_global.h" +#include "cpptoolsreuse.h" #include "cursorineditor.h" #include "projectinfo.h" #include "projectpart.h" @@ -174,7 +175,8 @@ public: enum class Backend { Builtin, Best }; static void followSymbol(const CursorInEditor &data, const Utils::LinkHandler &processLinkCallback, - bool resolveTarget, bool inNextSplit, Backend backend = Backend::Best); + bool resolveTarget, bool inNextSplit, + FollowSymbolMode mode, Backend backend = Backend::Best); static void followSymbolToType(const CursorInEditor &data, const Utils::LinkHandler &processLinkCallback, bool inNextSplit, Backend backend = Backend::Best); diff --git a/src/plugins/cppeditor/cppmodelmanagersupport.h b/src/plugins/cppeditor/cppmodelmanagersupport.h index 392712d86ae..a43a1e0b02b 100644 --- a/src/plugins/cppeditor/cppmodelmanagersupport.h +++ b/src/plugins/cppeditor/cppmodelmanagersupport.h @@ -4,6 +4,7 @@ #pragma once #include "cppeditor_global.h" +#include "cpptoolsreuse.h" #include "cursorineditor.h" #include @@ -12,7 +13,6 @@ #include #include -#include namespace Core { class SearchResult; } namespace TextEditor { @@ -41,6 +41,7 @@ public: virtual void followSymbol(const CursorInEditor &data, const Utils::LinkHandler &processLinkCallback, + FollowSymbolMode mode, bool resolveTarget, bool inNextSplit) = 0; virtual void followSymbolToType(const CursorInEditor &data, const Utils::LinkHandler &processLinkCallback, diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index d3d244b81c0..088449002ca 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -3017,6 +3017,7 @@ void AddDeclarationForUndeclaredIdentifier::match(const CppQuickFixInterface &in collectOperations(interface, result); }; CppModelManager::followSymbol(cursorInEditor, followSymbolFallback, false, false, + FollowSymbolMode::Exact, CppModelManager::Backend::Builtin); } @@ -9649,7 +9650,8 @@ private: (const Link &link) { moveComments(link, symbolLoc, comments); }; - CppModelManager::followSymbol(cursorInEditor, callback, true, false); + CppModelManager::followSymbol(cursorInEditor, callback, true, false, + FollowSymbolMode::Exact); } static void moveComments(const Link &targetLoc, const Link &symbolLoc, diff --git a/src/plugins/cppeditor/cpptoolsreuse.h b/src/plugins/cppeditor/cpptoolsreuse.h index d40e00d994c..50078bdd791 100644 --- a/src/plugins/cppeditor/cpptoolsreuse.h +++ b/src/plugins/cppeditor/cpptoolsreuse.h @@ -33,6 +33,8 @@ class CppRefactoringFile; class ProjectInfo; class CppCompletionAssistProcessor; +enum class FollowSymbolMode { Exact, Fuzzy }; + void CPPEDITOR_EXPORT moveCursorToEndOfIdentifier(QTextCursor *tc); void CPPEDITOR_EXPORT moveCursorToStartOfIdentifier(QTextCursor *tc);