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 <christian.stenger@qt.io>
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Kandeler
2023-11-07 11:05:48 +01:00
parent 5334154ecb
commit 09e495f01a
11 changed files with 40 additions and 15 deletions

View File

@@ -199,7 +199,6 @@ void ClangdFollowSymbol::emitDone(const Link &link)
return; return;
d->done = true; d->done = true;
if (link.hasValidTarget())
d->callback(link); d->callback(link);
emit done(); emit done();
} }

View File

@@ -53,6 +53,7 @@
#include <QLabel> #include <QLabel>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QMenu> #include <QMenu>
#include <QPointer>
#include <QTextBlock> #include <QTextBlock>
#include <QTimer> #include <QTimer>
#include <QtDebug> #include <QtDebug>
@@ -299,17 +300,27 @@ ClangModelManagerSupport::~ClangModelManagerSupport()
void ClangModelManagerSupport::followSymbol(const CursorInEditor &data, void ClangModelManagerSupport::followSymbol(const CursorInEditor &data,
const LinkHandler &processLinkCallback, const LinkHandler &processLinkCallback,
FollowSymbolMode mode,
bool resolveTarget, bool inNextSplit) bool resolveTarget, bool inNextSplit)
{ {
if (ClangdClient * const client = clientForFile(data.filePath()); if (ClangdClient * const client = clientForFile(data.filePath());
client && client->isFullyIndexed()) { 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(), client->followSymbol(data.textDocument(), data.cursor(), data.editorWidget(),
processLinkCallback, resolveTarget, FollowTo::SymbolDef, inNextSplit); extendedCallback, resolveTarget, FollowTo::SymbolDef, inNextSplit);
return; return;
} }
CppModelManager::followSymbol(data, processLinkCallback, resolveTarget, inNextSplit, CppModelManager::followSymbol(data, processLinkCallback, resolveTarget, inNextSplit,
CppModelManager::Backend::Builtin); mode, CppModelManager::Backend::Builtin);
} }
void ClangModelManagerSupport::followSymbolToType(const CursorInEditor &data, void ClangModelManagerSupport::followSymbolToType(const CursorInEditor &data,

View File

@@ -52,8 +52,9 @@ public:
private: private:
void followSymbol(const CppEditor::CursorInEditor &data, void followSymbol(const CppEditor::CursorInEditor &data,
const Utils::LinkHandler &processLinkCallback, bool resolveTarget, const Utils::LinkHandler &processLinkCallback,
bool inNextSplit) override; CppEditor::FollowSymbolMode mode,
bool resolveTarget, bool inNextSplit) override;
void followSymbolToType(const CppEditor::CursorInEditor &data, void followSymbolToType(const CppEditor::CursorInEditor &data,
const Utils::LinkHandler &processLinkCallback, const Utils::LinkHandler &processLinkCallback,
bool inNextSplit) override; bool inNextSplit) override;

View File

@@ -101,8 +101,13 @@ TextEditor::BaseHoverHandler *BuiltinModelManagerSupport::createHoverHandler()
void BuiltinModelManagerSupport::followSymbol(const CursorInEditor &data, void BuiltinModelManagerSupport::followSymbol(const CursorInEditor &data,
const Utils::LinkHandler &processLinkCallback, const Utils::LinkHandler &processLinkCallback,
FollowSymbolMode mode,
bool resolveTarget, bool inNextSplit) 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; SymbolFinder finder;
m_followSymbol->findLink(data, processLinkCallback, m_followSymbol->findLink(data, processLinkCallback,
resolveTarget, CppModelManager::snapshot(), resolveTarget, CppModelManager::snapshot(),

View File

@@ -29,7 +29,7 @@ public:
private: private:
void followSymbol(const CursorInEditor &data, const Utils::LinkHandler &processLinkCallback, 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, void followSymbolToType(const CursorInEditor &data,
const Utils::LinkHandler &processLinkCallback, const Utils::LinkHandler &processLinkCallback,
bool inNextSplit) override; bool inNextSplit) override;

View File

@@ -625,7 +625,7 @@ void CppEditorWidget::renameUsages(const QString &replacement, QTextCursor curso
}; };
CppModelManager::followSymbol( CppModelManager::followSymbol(
CursorInEditor{cursor, textDocument()->filePath(), this, textDocument()}, CursorInEditor{cursor, textDocument()->filePath(), this, textDocument()},
continuation, true, false); continuation, true, false, FollowSymbolMode::Exact);
} }
void CppEditorWidget::renameUsages(const Utils::FilePath &filePath, const QString &replacement, 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()}, CppModelManager::followSymbol(CursorInEditor{cursor, filePath, this, textDocument()},
callbackWrapper, callbackWrapper,
resolveTarget, resolveTarget,
inNextSplit); inNextSplit,
FollowSymbolMode::Fuzzy);
} }
void CppEditorWidget::findTypeAt(const QTextCursor &cursor, void CppEditorWidget::findTypeAt(const QTextCursor &cursor,

View File

@@ -2065,9 +2065,10 @@ TextEditor::BaseHoverHandler *CppModelManager::createHoverHandler()
void CppModelManager::followSymbol(const CursorInEditor &data, void CppModelManager::followSymbol(const CursorInEditor &data,
const LinkHandler &processLinkCallback, const LinkHandler &processLinkCallback,
bool resolveTarget, bool inNextSplit, Backend backend) bool resolveTarget, bool inNextSplit,
FollowSymbolMode mode, Backend backend)
{ {
modelManagerSupport(backend)->followSymbol(data, processLinkCallback, modelManagerSupport(backend)->followSymbol(data, processLinkCallback, mode,
resolveTarget, inNextSplit); resolveTarget, inNextSplit);
} }

View File

@@ -5,6 +5,7 @@
#include "cppeditor_global.h" #include "cppeditor_global.h"
#include "cpptoolsreuse.h"
#include "cursorineditor.h" #include "cursorineditor.h"
#include "projectinfo.h" #include "projectinfo.h"
#include "projectpart.h" #include "projectpart.h"
@@ -174,7 +175,8 @@ public:
enum class Backend { Builtin, Best }; enum class Backend { Builtin, Best };
static void followSymbol(const CursorInEditor &data, static void followSymbol(const CursorInEditor &data,
const Utils::LinkHandler &processLinkCallback, 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, static void followSymbolToType(const CursorInEditor &data,
const Utils::LinkHandler &processLinkCallback, bool inNextSplit, const Utils::LinkHandler &processLinkCallback, bool inNextSplit,
Backend backend = Backend::Best); Backend backend = Backend::Best);

View File

@@ -4,6 +4,7 @@
#pragma once #pragma once
#include "cppeditor_global.h" #include "cppeditor_global.h"
#include "cpptoolsreuse.h"
#include "cursorineditor.h" #include "cursorineditor.h"
#include <utils/link.h> #include <utils/link.h>
@@ -12,7 +13,6 @@
#include <QString> #include <QString>
#include <functional> #include <functional>
#include <memory>
namespace Core { class SearchResult; } namespace Core { class SearchResult; }
namespace TextEditor { namespace TextEditor {
@@ -41,6 +41,7 @@ public:
virtual void followSymbol(const CursorInEditor &data, virtual void followSymbol(const CursorInEditor &data,
const Utils::LinkHandler &processLinkCallback, const Utils::LinkHandler &processLinkCallback,
FollowSymbolMode mode,
bool resolveTarget, bool inNextSplit) = 0; bool resolveTarget, bool inNextSplit) = 0;
virtual void followSymbolToType(const CursorInEditor &data, virtual void followSymbolToType(const CursorInEditor &data,
const Utils::LinkHandler &processLinkCallback, const Utils::LinkHandler &processLinkCallback,

View File

@@ -3017,6 +3017,7 @@ void AddDeclarationForUndeclaredIdentifier::match(const CppQuickFixInterface &in
collectOperations(interface, result); collectOperations(interface, result);
}; };
CppModelManager::followSymbol(cursorInEditor, followSymbolFallback, false, false, CppModelManager::followSymbol(cursorInEditor, followSymbolFallback, false, false,
FollowSymbolMode::Exact,
CppModelManager::Backend::Builtin); CppModelManager::Backend::Builtin);
} }
@@ -9649,7 +9650,8 @@ private:
(const Link &link) { (const Link &link) {
moveComments(link, symbolLoc, comments); 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, static void moveComments(const Link &targetLoc, const Link &symbolLoc,

View File

@@ -33,6 +33,8 @@ class CppRefactoringFile;
class ProjectInfo; class ProjectInfo;
class CppCompletionAssistProcessor; class CppCompletionAssistProcessor;
enum class FollowSymbolMode { Exact, Fuzzy };
void CPPEDITOR_EXPORT moveCursorToEndOfIdentifier(QTextCursor *tc); void CPPEDITOR_EXPORT moveCursorToEndOfIdentifier(QTextCursor *tc);
void CPPEDITOR_EXPORT moveCursorToStartOfIdentifier(QTextCursor *tc); void CPPEDITOR_EXPORT moveCursorToStartOfIdentifier(QTextCursor *tc);