aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/languageclient
diff options
context:
space:
mode:
authorDavid Schulz <david.schulz@qt.io>2019-04-04 14:36:28 +0200
committerDavid Schulz <david.schulz@qt.io>2019-04-25 10:54:23 +0000
commitb79eabd4d2e65fd5b84c4bccc94e38d2a3b4cf85 (patch)
tree754c1f54583ba6295f0c36a94d982ccdfd01efb5 /src/plugins/languageclient
parentdfeb0245838f0709e845ed264f343e4ac0bb2bfe (diff)
LanguageClient: add cache for document symbols
Change-Id: Ia4c4061258c74d839edbd472c2087be74ac30113 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Diffstat (limited to 'src/plugins/languageclient')
-rw-r--r--src/plugins/languageclient/client.cpp6
-rw-r--r--src/plugins/languageclient/client.h3
-rw-r--r--src/plugins/languageclient/documentsymbolcache.cpp81
-rw-r--r--src/plugins/languageclient/documentsymbolcache.h58
-rw-r--r--src/plugins/languageclient/languageclient.pro2
-rw-r--r--src/plugins/languageclient/languageclient.qbs2
-rw-r--r--src/plugins/languageclient/languageclientoutline.cpp42
7 files changed, 170 insertions, 24 deletions
diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp
index 12c8f86531d..dd544f37e9f 100644
--- a/src/plugins/languageclient/client.cpp
+++ b/src/plugins/languageclient/client.cpp
@@ -94,6 +94,7 @@ Client::Client(BaseClientInterface *clientInterface)
, m_completionProvider(this)
, m_quickFixProvider(this)
, m_clientInterface(clientInterface)
+ , m_documentSymbolCache(this)
{
m_contentHandler.insert(JsonRpcMessageHandler::jsonRpcMimeType(),
&JsonRpcMessageHandler::parseContent);
@@ -859,6 +860,11 @@ const BaseClientInterface *Client::clientInterface() const
return m_clientInterface.data();
}
+DocumentSymbolCache *Client::documentSymbolCache()
+{
+ return &m_documentSymbolCache;
+}
+
void Client::log(const ShowMessageParams &message,
Core::MessageManager::PrintToOutputPaneFlag flag)
{
diff --git a/src/plugins/languageclient/client.h b/src/plugins/languageclient/client.h
index d29c4f6a888..f2f92cbfe6a 100644
--- a/src/plugins/languageclient/client.h
+++ b/src/plugins/languageclient/client.h
@@ -25,6 +25,7 @@
#pragma once
+#include "documentsymbolcache.h"
#include "dynamiccapabilities.h"
#include "languageclientcompletionassist.h"
#include "languageclientquickfix.h"
@@ -148,6 +149,7 @@ public:
const LanguageServerProtocol::ServerCapabilities &capabilities() const;
const DynamicCapabilities &dynamicCapabilities() const;
const BaseClientInterface *clientInterface() const;
+ DocumentSymbolCache *documentSymbolCache();
signals:
void initialized(LanguageServerProtocol::ServerCapabilities capabilities);
@@ -197,6 +199,7 @@ private:
int m_restartsLeft = 5;
QScopedPointer<BaseClientInterface> m_clientInterface;
QMap<LanguageServerProtocol::DocumentUri, QList<TextMark *>> m_diagnostics;
+ DocumentSymbolCache m_documentSymbolCache;
};
} // namespace LanguageClient
diff --git a/src/plugins/languageclient/documentsymbolcache.cpp b/src/plugins/languageclient/documentsymbolcache.cpp
new file mode 100644
index 00000000000..b922486d56e
--- /dev/null
+++ b/src/plugins/languageclient/documentsymbolcache.cpp
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "documentsymbolcache.h"
+
+#include "client.h"
+
+#include <coreplugin/editormanager/editormanager.h>
+#include <texteditor/textdocument.h>
+
+using namespace LanguageServerProtocol;
+
+namespace LanguageClient {
+
+DocumentSymbolCache::DocumentSymbolCache(Client *client)
+ : QObject(client)
+ , m_client(client)
+{
+ connect(Core::EditorManager::instance(),
+ &Core::EditorManager::documentOpened,
+ this,
+ [this](Core::IDocument *document) {
+ connect(document, &Core::IDocument::contentsChanged, this, [this, document]() {
+ m_cache.remove(DocumentUri::fromFileName(document->filePath()));
+ });
+ });
+}
+
+void DocumentSymbolCache::requestSymbols(const DocumentUri &uri)
+{
+ auto entry = m_cache.find(uri);
+ if (entry != m_cache.end()) {
+ emit gotSymbols(uri, entry.value());
+ return;
+ }
+
+ const DocumentSymbolParams params((TextDocumentIdentifier(uri)));
+ DocumentSymbolsRequest request(params);
+ request.setResponseCallback([uri, self = QPointer<DocumentSymbolCache>(this)](
+ const DocumentSymbolsRequest::Response &response) {
+ if (self)
+ self->handleResponse(uri, response);
+ });
+ m_client->sendContent(request);
+}
+
+void DocumentSymbolCache::handleResponse(const DocumentUri &uri,
+ const DocumentSymbolsRequest::Response &response)
+{
+ if (Utils::optional<DocumentSymbolsRequest::Response::Error> error = response.error()) {
+ if (m_client)
+ m_client->log(error.value());
+ }
+ const DocumentSymbolsResult &symbols = response.result().value_or(DocumentSymbolsResult());
+ m_cache[uri] = symbols;
+ emit gotSymbols(uri, symbols);
+}
+
+} // namespace LanguageClient
diff --git a/src/plugins/languageclient/documentsymbolcache.h b/src/plugins/languageclient/documentsymbolcache.h
new file mode 100644
index 00000000000..2f0b2376bc3
--- /dev/null
+++ b/src/plugins/languageclient/documentsymbolcache.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "utils/optional.h"
+
+#include <languageserverprotocol/languagefeatures.h>
+
+#include <QObject>
+
+namespace LanguageClient {
+
+class Client;
+
+class DocumentSymbolCache : public QObject
+{
+ Q_OBJECT
+public:
+ DocumentSymbolCache(Client *client);
+
+ void requestSymbols(const LanguageServerProtocol::DocumentUri &uri);
+
+signals:
+ void gotSymbols(const LanguageServerProtocol::DocumentUri &uri,
+ const LanguageServerProtocol::DocumentSymbolsResult &symbols);
+
+private:
+ void handleResponse(const LanguageServerProtocol::DocumentUri &uri,
+ const LanguageServerProtocol::DocumentSymbolsRequest::Response &response);
+
+ QMap<LanguageServerProtocol::DocumentUri, LanguageServerProtocol::DocumentSymbolsResult> m_cache;
+ Client *m_client = nullptr;
+};
+
+} // namespace LanguageClient
diff --git a/src/plugins/languageclient/languageclient.pro b/src/plugins/languageclient/languageclient.pro
index dbae20e1098..912873134b7 100644
--- a/src/plugins/languageclient/languageclient.pro
+++ b/src/plugins/languageclient/languageclient.pro
@@ -4,6 +4,7 @@ DEFINES += LANGUAGECLIENT_LIBRARY
HEADERS += \
client.h \
+ documentsymbolcache.h \
dynamiccapabilities.h \
languageclient_global.h \
languageclientcompletionassist.h \
@@ -18,6 +19,7 @@ HEADERS += \
SOURCES += \
client.cpp \
+ documentsymbolcache.cpp \
dynamiccapabilities.cpp \
languageclientcompletionassist.cpp \
languageclientinterface.cpp \
diff --git a/src/plugins/languageclient/languageclient.qbs b/src/plugins/languageclient/languageclient.qbs
index 0c2752ef5eb..b2520fba34d 100644
--- a/src/plugins/languageclient/languageclient.qbs
+++ b/src/plugins/languageclient/languageclient.qbs
@@ -16,6 +16,8 @@ QtcPlugin {
files: [
"client.cpp",
"client.h",
+ "documentsymbolcache.cpp",
+ "documentsymbolcache.h",
"dynamiccapabilities.cpp",
"dynamiccapabilities.h",
"languageclient.qrc",
diff --git a/src/plugins/languageclient/languageclientoutline.cpp b/src/plugins/languageclient/languageclientoutline.cpp
index 3c3a1aa1b16..e08587c1d32 100644
--- a/src/plugins/languageclient/languageclientoutline.cpp
+++ b/src/plugins/languageclient/languageclientoutline.cpp
@@ -155,7 +155,7 @@ public:
void setCursorSynchronization(bool syncWithCursor) override;
private:
- void handleResponse(const LanguageServerProtocol::DocumentSymbolsRequest::Response &response);
+ void handleResponse(const DocumentUri &uri, const DocumentSymbolsResult &response);
void updateTextCursor(const QModelIndex &proxyIndex);
void updateSelectionInTree(const QTextCursor &currentCursor);
void onItemActivated(const QModelIndex &index);
@@ -164,6 +164,7 @@ private:
QPointer<TextEditor::BaseTextEditor> m_editor;
LanguageClientOutlineModel m_model;
Utils::TreeView m_view;
+ DocumentUri m_uri;
bool m_sync = false;
};
@@ -172,23 +173,19 @@ LanguageClientOutlineWidget::LanguageClientOutlineWidget(Client *client,
: m_client(client)
, m_editor(editor)
, m_view(this)
+ , m_uri(DocumentUri::fromFileName(editor->textDocument()->filePath()))
{
- const DocumentSymbolParams params(
- TextDocumentIdentifier(
- DocumentUri::fromFileName(editor->textDocument()->filePath())));
- DocumentSymbolsRequest request(params);
- request.setResponseCallback([self = QPointer<LanguageClientOutlineWidget>(this)]
- (const DocumentSymbolsRequest::Response &response){
- if (self)
- self->handleResponse(response);
- });
+ connect(client->documentSymbolCache(),
+ &DocumentSymbolCache::gotSymbols,
+ this,
+ &LanguageClientOutlineWidget::handleResponse);
+ client->documentSymbolCache()->requestSymbols(m_uri);
auto *layout = new QVBoxLayout;
layout->setMargin(0);
layout->setSpacing(0);
layout->addWidget(Core::ItemViewFind::createSearchableWrapper(&m_view));
setLayout(layout);
- client->sendContent(request);
m_view.setModel(&m_model);
m_view.setHeaderHidden(true);
connect(&m_view, &QAbstractItemView::activated,
@@ -212,20 +209,17 @@ void LanguageClientOutlineWidget::setCursorSynchronization(bool syncWithCursor)
updateSelectionInTree(m_editor->textCursor());
}
-void LanguageClientOutlineWidget::handleResponse(const DocumentSymbolsRequest::Response &response)
+void LanguageClientOutlineWidget::handleResponse(const DocumentUri &uri,
+ const DocumentSymbolsResult &result)
{
- if (Utils::optional<DocumentSymbolsRequest::Response::Error> error = response.error()) {
- if (m_client)
- m_client->log(error.value());
- }
- if (Utils::optional<DocumentSymbolsResult> result = response.result()) {
- if (Utils::holds_alternative<QList<SymbolInformation>>(result.value()))
- m_model.setInfo(Utils::get<QList<SymbolInformation>>(result.value()));
- else if (Utils::holds_alternative<QList<DocumentSymbol>>(result.value()))
- m_model.setInfo(Utils::get<QList<DocumentSymbol>>(result.value()));
- else
- m_model.clear();
- }
+ if (uri != m_uri)
+ return;
+ if (Utils::holds_alternative<QList<SymbolInformation>>(result))
+ m_model.setInfo(Utils::get<QList<SymbolInformation>>(result));
+ else if (Utils::holds_alternative<QList<DocumentSymbol>>(result))
+ m_model.setInfo(Utils::get<QList<DocumentSymbol>>(result));
+ else
+ m_model.clear();
}
void LanguageClientOutlineWidget::updateTextCursor(const QModelIndex &proxyIndex)