ClangCodeModel: Make use of clangd's "switchSourceHeader" extension

This allows us to switch between headers and sources with different base
names and/or locations, using symbol matching heuristics.

Task-number: QTCREATORBUG-16385
Change-Id: I2d9c07f412d70b75322ed65d491982d78674483d
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Kandeler
2022-05-18 15:16:40 +02:00
parent 0422233af4
commit 70ec0cfff1
14 changed files with 71 additions and 30 deletions

View File

@@ -2255,6 +2255,28 @@ void ClangdClient::switchDeclDef(TextDocument *document, const QTextCursor &curs
documentSymbolCache()->requestSymbols(d->switchDeclDefData->uri, Schedule::Now);
}
void ClangdClient::switchHeaderSource(const Utils::FilePath &filePath, bool inNextSplit)
{
class SwitchSourceHeaderRequest : public Request<QJsonValue, std::nullptr_t, TextDocumentIdentifier>
{
public:
using Request::Request;
explicit SwitchSourceHeaderRequest(const Utils::FilePath &filePath)
: Request("textDocument/switchSourceHeader",
TextDocumentIdentifier(DocumentUri::fromFilePath(filePath))) {}
};
SwitchSourceHeaderRequest req(filePath);
req.setResponseCallback([inNextSplit](const SwitchSourceHeaderRequest::Response &response) {
if (const Utils::optional<QJsonValue> result = response.result()) {
const DocumentUri uri = DocumentUri::fromProtocol(result->toString());
const Utils::FilePath filePath = uri.toFilePath();
if (!filePath.isEmpty())
CppEditor::openEditor(filePath, inNextSplit);
}
});
sendContent(req);
}
void ClangdClient::findLocalUsages(TextDocument *document, const QTextCursor &cursor,
CppEditor::RenameCallback &&callback)
{

View File

@@ -75,6 +75,7 @@ public:
const QTextCursor &cursor,
CppEditor::CppEditorWidget *editorWidget,
Utils::ProcessLinkCallback &&callback);
void switchHeaderSource(const Utils::FilePath &filePath, bool inNextSplit);
void findLocalUsages(TextEditor::TextDocument *document, const QTextCursor &cursor,
CppEditor::RenameCallback &&callback);

View File

@@ -248,6 +248,21 @@ void ClangModelManagerSupport::findUsages(const CppEditor::CursorInEditor &curso
CppModelManager::findUsages(cursor, std::move(callback), CppModelManager::Backend::Builtin);
}
void ClangModelManagerSupport::switchHeaderSource(const Utils::FilePath &filePath, bool inNextSplit)
{
if (ClangdClient * const client = clientForFile(filePath)) {
// The fast, synchronous approach works most of the time, so let's try that one first.
const auto otherFile = Utils::FilePath::fromString(
correspondingHeaderOrSource(filePath.toString()));
if (!otherFile.isEmpty())
openEditor(otherFile, inNextSplit);
else
client->switchHeaderSource(filePath, inNextSplit);
return;
}
CppModelManager::switchHeaderSource(inNextSplit, CppModelManager::Backend::Builtin);
}
std::unique_ptr<CppEditor::AbstractOverviewModel> ClangModelManagerSupport::createOverviewModel()
{
return {};

View File

@@ -97,6 +97,7 @@ private:
const QString &replacement) override;
void findUsages(const CppEditor::CursorInEditor &cursor,
CppEditor::UsagesCallback &&callback) const override;
void switchHeaderSource(const Utils::FilePath &filePath, bool inNextSplit) override;
void onEditorOpened(Core::IEditor *editor);
void onCurrentEditorChanged(Core::IEditor *newCurrent);