forked from qt-creator/qt-creator
ClangCodeModel: Fix callback handling when following symbols
Make sure emitDone() is atomic with running the callback, so in case the latter starts an event loop of its own, we won't be overtaken by incoming signals, deleting the object from under us. Task-number: QTCREATORBUG-27910 Change-Id: I586d7609974662bf391b12041f416aaa2a973ecb Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
committed by
Eike Ziller
parent
b2407dbde5
commit
5c341854e0
@@ -146,14 +146,14 @@ ClangdFollowSymbol::ClangdFollowSymbol(ClangdClient *client, const QTextCursor &
|
|||||||
openInSplit))
|
openInSplit))
|
||||||
{
|
{
|
||||||
// Abort if the user does something else with the document in the meantime.
|
// Abort if the user does something else with the document in the meantime.
|
||||||
connect(document, &TextDocument::contentsChanged, this, &ClangdFollowSymbol::emitDone,
|
connect(document, &TextDocument::contentsChanged, this, [this] { emitDone(); },
|
||||||
Qt::QueuedConnection);
|
Qt::QueuedConnection);
|
||||||
if (editorWidget) {
|
if (editorWidget) {
|
||||||
connect(editorWidget, &CppEditorWidget::cursorPositionChanged,
|
connect(editorWidget, &CppEditorWidget::cursorPositionChanged,
|
||||||
this, &ClangdFollowSymbol::emitDone, Qt::QueuedConnection);
|
this, [this] { emitDone(); }, Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
d->focusChangedConnection = connect(qApp, &QApplication::focusChanged,
|
d->focusChangedConnection = connect(qApp, &QApplication::focusChanged,
|
||||||
this, &ClangdFollowSymbol::emitDone, Qt::QueuedConnection);
|
this, [this] { emitDone(); }, Qt::QueuedConnection);
|
||||||
|
|
||||||
// Step 1: Follow the symbol via "Go to Definition". At the same time, request the
|
// Step 1: Follow the symbol via "Go to Definition". At the same time, request the
|
||||||
// AST node corresponding to the cursor position, so we can find out whether
|
// AST node corresponding to the cursor position, so we can find out whether
|
||||||
@@ -205,12 +205,14 @@ void ClangdFollowSymbol::clear()
|
|||||||
d->pendingGotoDefRequests.clear();
|
d->pendingGotoDefRequests.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangdFollowSymbol::emitDone()
|
void ClangdFollowSymbol::emitDone(const Link &link)
|
||||||
{
|
{
|
||||||
if (d->done)
|
if (d->done)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
d->done = true;
|
d->done = true;
|
||||||
|
if (link.hasValidTarget())
|
||||||
|
d->callback(link);
|
||||||
emit done();
|
emit done();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,14 +248,12 @@ void ClangdFollowSymbol::Private::handleDocumentInfoResults()
|
|||||||
|
|
||||||
// If something went wrong, we just follow the original link.
|
// If something went wrong, we just follow the original link.
|
||||||
if (symbolsToDisplay.isEmpty()) {
|
if (symbolsToDisplay.isEmpty()) {
|
||||||
callback(defLink);
|
q->emitDone(defLink);
|
||||||
q->emitDone();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (symbolsToDisplay.size() == 1) {
|
if (symbolsToDisplay.size() == 1) {
|
||||||
callback(symbolsToDisplay.first().second);
|
q->emitDone(symbolsToDisplay.first().second);
|
||||||
q->emitDone();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,8 +382,7 @@ void ClangdFollowSymbol::Private::handleGotoDefinitionResult()
|
|||||||
|
|
||||||
// No dis-ambiguation necessary. Call back with the link and finish.
|
// No dis-ambiguation necessary. Call back with the link and finish.
|
||||||
if (!defLinkIsAmbiguous()) {
|
if (!defLinkIsAmbiguous()) {
|
||||||
callback(defLink);
|
q->emitDone(defLink);
|
||||||
q->emitDone();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -416,8 +415,7 @@ void ClangdFollowSymbol::Private::handleGotoImplementationResult(
|
|||||||
|
|
||||||
// We didn't find any further candidates, so jump to the original definition link.
|
// We didn't find any further candidates, so jump to the original definition link.
|
||||||
if (allLinks.size() == 1 && pendingGotoImplRequests.isEmpty()) {
|
if (allLinks.size() == 1 && pendingGotoImplRequests.isEmpty()) {
|
||||||
callback(allLinks.first());
|
q->emitDone(allLinks.first());
|
||||||
q->emitDone();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -55,7 +55,7 @@ signals:
|
|||||||
void done();
|
void done();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void emitDone();
|
void emitDone(const Utils::Link &link = {});
|
||||||
class VirtualFunctionAssistProcessor;
|
class VirtualFunctionAssistProcessor;
|
||||||
class VirtualFunctionAssistProvider;
|
class VirtualFunctionAssistProvider;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user