Clangd: Make "Follow Symbol" more robust

The AST is only needed for virtual function disambiguation, while the
basic functionality works fine without it. So in case clangd fails to
retrieve the AST node for some reason, just use the original "go to
definition" result.
This also makes "Follow Symbol" work with clangd < 12.

Change-Id: I2c110e9a51b01dc912fcdf6f4ed45fce766df374
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Kandeler
2021-06-29 11:01:50 +02:00
parent d857e17b13
commit 4e777fcf90

View File

@@ -526,7 +526,7 @@ public:
Utils::Link defLink;
QList<Utils::Link> allLinks;
QHash<Utils::Link, Utils::Link> declDefMap;
AstNode cursorNode;
Utils::optional<AstNode> cursorNode;
AstNode defLinkNode;
SymbolDataList symbolsToDisplay;
std::set<Utils::FilePath> openedFiles;
@@ -1074,11 +1074,16 @@ void ClangdClient::followSymbol(
if (!d->followSymbolData || id != d->followSymbolData->id)
return;
d->followSymbolData->defLink = link;
if (d->followSymbolData->cursorNode.isValid())
if (d->followSymbolData->cursorNode)
d->handleGotoDefinitionResult();
};
symbolSupport().findLinkAt(document, cursor, std::move(gotoDefCallback), true);
if (versionNumber() < QVersionNumber(12)) {
d->followSymbolData->cursorNode.emplace(AstNode());
return;
}
AstRequest astRequest(AstParams(TextDocumentIdentifier(d->followSymbolData->uri),
Range(cursor)));
astRequest.setResponseCallback([this, id = d->followSymbolData->id](
@@ -1087,11 +1092,10 @@ void ClangdClient::followSymbol(
if (!d->followSymbolData || d->followSymbolData->id != id)
return;
const auto result = response.result();
if (!result) {
d->followSymbolData.reset();
return;
}
d->followSymbolData->cursorNode = *result;
if (result)
d->followSymbolData->cursorNode = *result;
else
d->followSymbolData->cursorNode.emplace(AstNode());
if (d->followSymbolData->defLink.hasValidTarget())
d->handleGotoDefinitionResult();
});
@@ -1229,8 +1233,8 @@ void ClangdClient::Private::handleGotoDefinitionResult()
qCDebug(clangdLog) << "handling go to definition result";
// No dis-ambiguation necessary. Call back with the link and finish.
if (!followSymbolData->cursorNode.mightBeAmbiguousVirtualCall()
&& !followSymbolData->cursorNode.isPureVirtualDeclaration()) {
if (!followSymbolData->cursorNode->mightBeAmbiguousVirtualCall()
&& !followSymbolData->cursorNode->isPureVirtualDeclaration()) {
followSymbolData->callback(followSymbolData->defLink);
followSymbolData.reset();
return;