forked from qt-creator/qt-creator
ClangCodeModel: Allow more than one in-flight "follow symbol"
The original code was written with only the interactive case in mind, but nowadays we also start "follow symbol" operations internally as part of e.g. quickfixes. Change-Id: I95928297fab16f9b0469bfd66ad687447b902fd9 Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -349,7 +349,7 @@ public:
|
||||
|
||||
ClangdClient * const q;
|
||||
const CppEditor::ClangdSettings::Data settings;
|
||||
ClangdFollowSymbol *followSymbol = nullptr;
|
||||
QList<ClangdFollowSymbol *> followSymbolOps;
|
||||
ClangdSwitchDeclDef *switchDeclDef = nullptr;
|
||||
ClangdFindLocalReferences *findLocalRefs = nullptr;
|
||||
std::optional<QVersionNumber> versionNumber;
|
||||
@@ -501,8 +501,8 @@ ClangdClient::ClangdClient(Project *project, const Utils::FilePath &jsonDbDir, c
|
||||
|
||||
ClangdClient::~ClangdClient()
|
||||
{
|
||||
if (d->followSymbol)
|
||||
d->followSymbol->clear();
|
||||
for (ClangdFollowSymbol * const followSymbol : std::as_const(d->followSymbolOps))
|
||||
followSymbol->clear();
|
||||
delete d;
|
||||
}
|
||||
|
||||
@@ -990,7 +990,7 @@ MessageId ClangdClient::requestSymbolInfo(const Utils::FilePath &filePath, const
|
||||
#ifdef WITH_TESTS
|
||||
ClangdFollowSymbol *ClangdClient::currentFollowSymbolOperation()
|
||||
{
|
||||
return d->followSymbol;
|
||||
return d->followSymbolOps.isEmpty() ? nullptr : d->followSymbolOps.first();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1005,8 +1005,20 @@ void ClangdClient::followSymbol(TextDocument *document,
|
||||
{
|
||||
QTC_ASSERT(documentOpen(document), openDocument(document));
|
||||
|
||||
if (d->followSymbol)
|
||||
d->followSymbol->cancel();
|
||||
const ClangdFollowSymbol::Origin origin
|
||||
= CppEditor::CppCodeModelSettings::isInteractiveFollowSymbol()
|
||||
? ClangdFollowSymbol::Origin::User
|
||||
: ClangdFollowSymbol::Origin::Code;
|
||||
if (origin == ClangdFollowSymbol::Origin::User) {
|
||||
for (auto it = d->followSymbolOps.begin(); it != d->followSymbolOps.end(); ) {
|
||||
if ((*it)->isInteractive()) {
|
||||
(*it)->cancel();
|
||||
it = d->followSymbolOps.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const QTextCursor adjustedCursor = d->adjustedCursor(cursor, document);
|
||||
if (followTo == FollowTo::SymbolDef && !resolveTarget) {
|
||||
@@ -1020,14 +1032,13 @@ void ClangdClient::followSymbol(TextDocument *document,
|
||||
|
||||
qCDebug(clangdLog) << "follow symbol requested" << document->filePath()
|
||||
<< adjustedCursor.blockNumber() << adjustedCursor.positionInBlock();
|
||||
auto clangdFollowSymbol = new ClangdFollowSymbol(this, adjustedCursor, editorWidget, document,
|
||||
callback, followTo, openInSplit);
|
||||
auto clangdFollowSymbol = new ClangdFollowSymbol(this, origin, adjustedCursor, editorWidget,
|
||||
document, callback, followTo, openInSplit);
|
||||
connect(clangdFollowSymbol, &ClangdFollowSymbol::done, this, [this, clangdFollowSymbol] {
|
||||
clangdFollowSymbol->deleteLater();
|
||||
if (clangdFollowSymbol == d->followSymbol)
|
||||
d->followSymbol = nullptr;
|
||||
d->followSymbolOps.removeOne(clangdFollowSymbol);
|
||||
});
|
||||
d->followSymbol = clangdFollowSymbol;
|
||||
d->followSymbolOps << clangdFollowSymbol;
|
||||
}
|
||||
|
||||
void ClangdClient::switchDeclDef(TextDocument *document, const QTextCursor &cursor,
|
||||
|
||||
@@ -73,10 +73,10 @@ private:
|
||||
class ClangdFollowSymbol::Private
|
||||
{
|
||||
public:
|
||||
Private(ClangdFollowSymbol *q, ClangdClient *client, const QTextCursor &cursor,
|
||||
Private(ClangdFollowSymbol *q, ClangdClient *client, Origin origin, const QTextCursor &cursor,
|
||||
CppEditorWidget *editorWidget, const FilePath &filePath, const LinkHandler &callback,
|
||||
bool openInSplit)
|
||||
: q(q), client(client), cursor(cursor), editorWidget(editorWidget),
|
||||
: q(q), client(client), origin(origin), cursor(cursor), editorWidget(editorWidget),
|
||||
uri(client->hostPathToServerUri(filePath)), callback(callback),
|
||||
virtualFuncAssistProvider(q),
|
||||
docRevision(editorWidget ? editorWidget->textDocument()->document()->revision() : -1),
|
||||
@@ -94,6 +94,7 @@ public:
|
||||
|
||||
ClangdFollowSymbol * const q;
|
||||
ClangdClient * const client;
|
||||
const Origin origin;
|
||||
const QTextCursor cursor;
|
||||
const QPointer<CppEditor::CppEditorWidget> editorWidget;
|
||||
const DocumentUri uri;
|
||||
@@ -117,11 +118,11 @@ public:
|
||||
bool done = false;
|
||||
};
|
||||
|
||||
ClangdFollowSymbol::ClangdFollowSymbol(ClangdClient *client, const QTextCursor &cursor,
|
||||
CppEditorWidget *editorWidget, TextDocument *document, const LinkHandler &callback,
|
||||
FollowTo followTo, bool openInSplit)
|
||||
ClangdFollowSymbol::ClangdFollowSymbol(ClangdClient *client, Origin origin,
|
||||
const QTextCursor &cursor, CppEditorWidget *editorWidget, TextDocument *document,
|
||||
const LinkHandler &callback, FollowTo followTo, bool openInSplit)
|
||||
: QObject(client),
|
||||
d(new Private(this, client, cursor, editorWidget, document->filePath(), callback,
|
||||
d(new Private(this, client, origin, cursor, editorWidget, document->filePath(), callback,
|
||||
openInSplit))
|
||||
{
|
||||
// Abort if the user does something else with the document in the meantime.
|
||||
@@ -193,6 +194,11 @@ void ClangdFollowSymbol::clear()
|
||||
d->pendingGotoDefRequests.clear();
|
||||
}
|
||||
|
||||
bool ClangdFollowSymbol::isInteractive() const
|
||||
{
|
||||
return d->origin == Origin::User;
|
||||
}
|
||||
|
||||
void ClangdFollowSymbol::emitDone(const Link &link)
|
||||
{
|
||||
if (d->done)
|
||||
|
||||
@@ -23,7 +23,9 @@ class ClangdFollowSymbol : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ClangdFollowSymbol(ClangdClient *client, const QTextCursor &cursor,
|
||||
enum class Origin { User, Code };
|
||||
|
||||
ClangdFollowSymbol(ClangdClient *client, Origin origin, const QTextCursor &cursor,
|
||||
CppEditor::CppEditorWidget *editorWidget,
|
||||
TextEditor::TextDocument *document, const Utils::LinkHandler &callback,
|
||||
FollowTo followTo, bool openInSplit);
|
||||
@@ -31,6 +33,8 @@ public:
|
||||
void cancel();
|
||||
void clear();
|
||||
|
||||
bool isInteractive() const;
|
||||
|
||||
signals:
|
||||
void done();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user