forked from qt-creator/qt-creator
ClangClient: Receive done() signal only once
Before this change the done() signal was emitted 3 times
in a row. The reason was that first one was coming
synchonously from handleGotoDefinitionResult(), while
2 others were scheluded with queued connections.
So, the handler for done() signal was called 3 times.
The first invocation calls deleteLater() and clears
the pointer, while the object is still alive.
Before the request to delete later gets dispatched,
the 2 remaining done() emissions are dispatched,
so the handler is still called 2 times.
One possible solution would be to disconnect from
done() signal inside a handler. However, the done()
signal shouldn't be called many times, so this fix
ensures the done() is emitted only once.
This fixes the following prinouts:
"QCoreApplication::postEvent: Unexpected null receiver"
issued twice on every follow symbol interaction.
Amends 650bc260c6
Change-Id: I9b440a80386aca3462eda323e51a76696e53fa6b
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
@@ -68,6 +68,7 @@ public:
|
||||
const LinkHandler callback;
|
||||
optional<ClangdAstNode> ast;
|
||||
optional<DocumentSymbolsResult> docSymbols;
|
||||
bool done = false;
|
||||
};
|
||||
|
||||
ClangdSwitchDeclDef::ClangdSwitchDeclDef(ClangdClient *client, TextDocument *doc,
|
||||
@@ -75,14 +76,14 @@ ClangdSwitchDeclDef::ClangdSwitchDeclDef(ClangdClient *client, TextDocument *doc
|
||||
: QObject(client), d(new Private(this, client, doc, cursor, editorWidget, callback))
|
||||
{
|
||||
// Abort if the user does something else with the document in the meantime.
|
||||
connect(doc, &TextDocument::contentsChanged, this, &ClangdSwitchDeclDef::done,
|
||||
connect(doc, &TextDocument::contentsChanged, this, &ClangdSwitchDeclDef::emitDone,
|
||||
Qt::QueuedConnection);
|
||||
if (editorWidget) {
|
||||
connect(editorWidget, &CppEditorWidget::cursorPositionChanged,
|
||||
this, &ClangdSwitchDeclDef::done, Qt::QueuedConnection);
|
||||
this, &ClangdSwitchDeclDef::emitDone, Qt::QueuedConnection);
|
||||
}
|
||||
connect(qApp, &QApplication::focusChanged,
|
||||
this, &ClangdSwitchDeclDef::done, Qt::QueuedConnection);
|
||||
this, &ClangdSwitchDeclDef::emitDone, Qt::QueuedConnection);
|
||||
|
||||
connect(client->documentSymbolCache(), &DocumentSymbolCache::gotSymbols, this,
|
||||
[this](const DocumentUri &uri, const DocumentSymbolsResult &symbols) {
|
||||
@@ -101,11 +102,11 @@ ClangdSwitchDeclDef::ClangdSwitchDeclDef(ClangdClient *client, TextDocument *doc
|
||||
if (!self)
|
||||
return;
|
||||
if (!d->document) {
|
||||
emit done();
|
||||
emitDone();
|
||||
return;
|
||||
}
|
||||
if (!ast.isValid()) {
|
||||
emit done();
|
||||
emitDone();
|
||||
return;
|
||||
}
|
||||
d->ast = ast;
|
||||
@@ -122,6 +123,15 @@ ClangdSwitchDeclDef::~ClangdSwitchDeclDef()
|
||||
delete d;
|
||||
}
|
||||
|
||||
void ClangdSwitchDeclDef::emitDone()
|
||||
{
|
||||
if (d->done)
|
||||
return;
|
||||
|
||||
d->done = true;
|
||||
emit done();
|
||||
}
|
||||
|
||||
optional<ClangdAstNode> ClangdSwitchDeclDef::Private::getFunctionNode() const
|
||||
{
|
||||
QTC_ASSERT(ast, return {});
|
||||
@@ -160,7 +170,7 @@ QTextCursor ClangdSwitchDeclDef::Private::cursorForFunctionName(const ClangdAstN
|
||||
void ClangdSwitchDeclDef::Private::handleDeclDefSwitchReplies()
|
||||
{
|
||||
if (!document) {
|
||||
emit q->done();
|
||||
q->emitDone();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -171,7 +181,7 @@ void ClangdSwitchDeclDef::Private::handleDeclDefSwitchReplies()
|
||||
ast->print(0);
|
||||
const Utils::optional<ClangdAstNode> functionNode = getFunctionNode();
|
||||
if (!functionNode) {
|
||||
emit q->done();
|
||||
q->emitDone();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -182,7 +192,7 @@ void ClangdSwitchDeclDef::Private::handleDeclDefSwitchReplies()
|
||||
client->followSymbol(document.data(), funcNameCursor, editorWidget, callback,
|
||||
true, false);
|
||||
}
|
||||
emit q->done();
|
||||
q->emitDone();
|
||||
}
|
||||
|
||||
} // namespace ClangCodeModel::Internal
|
||||
|
||||
Reference in New Issue
Block a user