LanguageClient: move document symbol support check to client

Used there to prevent requesting document symbols from server that do
not support these requests.

Change-Id: Icca64c41415ba7098c769854823431fb05e5ce1d
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
David Schulz
2021-12-10 10:49:30 +01:00
parent 92156cc1d6
commit 348652dc26
6 changed files with 45 additions and 34 deletions

View File

@@ -1085,6 +1085,25 @@ void Client::setQuickFixAssistProvider(LanguageClientQuickFixProvider *provider)
m_clientProviders.quickFixAssistProvider = provider; m_clientProviders.quickFixAssistProvider = provider;
} }
bool Client::supportsDocumentSymbols(const TextEditor::TextDocument *doc) const
{
if (!doc)
return false;
DynamicCapabilities dc = dynamicCapabilities();
if (dc.isRegistered(DocumentSymbolsRequest::methodName).value_or(false)) {
TextDocumentRegistrationOptions options(dc.option(DocumentSymbolsRequest::methodName));
return !options.isValid()
|| options.filterApplies(doc->filePath(), Utils::mimeTypeForName(doc->mimeType()));
}
const Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> &provider
= capabilities().documentSymbolProvider();
if (!provider.has_value())
return false;
if (Utils::holds_alternative<bool>(*provider))
return Utils::get<bool>(*provider);
return true;
}
void Client::start() void Client::start()
{ {
LanguageClientManager::addClient(this); LanguageClientManager::addClient(this);

View File

@@ -193,6 +193,7 @@ public:
void setSnippetsGroup(const QString &group); void setSnippetsGroup(const QString &group);
void setCompletionAssistProvider(LanguageClientCompletionAssistProvider *provider); void setCompletionAssistProvider(LanguageClientCompletionAssistProvider *provider);
void setQuickFixAssistProvider(LanguageClientQuickFixProvider *provider); void setQuickFixAssistProvider(LanguageClientQuickFixProvider *provider);
virtual bool supportsDocumentSymbols(const TextEditor::TextDocument *doc) const;
// logging // logging
enum class LogTarget { Console, Ui }; enum class LogTarget { Console, Ui };

View File

@@ -67,6 +67,13 @@ void DocumentSymbolCache::requestSymbols(const DocumentUri &uri, Schedule schedu
} }
} }
bool clientSupportsDocumentSymbols(const Client *client, const DocumentUri &uri)
{
QTC_ASSERT(client, return false);
const auto doc = TextEditor::TextDocument::textDocumentForFilePath(uri.toFilePath());
return client->supportsDocumentSymbols(doc);
}
void DocumentSymbolCache::requestSymbolsImpl() void DocumentSymbolCache::requestSymbolsImpl()
{ {
if (!m_client->reachable()) { if (!m_client->reachable()) {
@@ -80,6 +87,11 @@ void DocumentSymbolCache::requestSymbolsImpl()
continue; continue;
} }
if (!LanguageClient::clientSupportsDocumentSymbols(m_client, uri)) {
emit gotSymbols(uri, nullptr);
continue;
}
const DocumentSymbolParams params((TextDocumentIdentifier(uri))); const DocumentSymbolParams params((TextDocumentIdentifier(uri)));
DocumentSymbolsRequest request(params); DocumentSymbolsRequest request(params);
request.setResponseCallback([uri, self = QPointer<DocumentSymbolCache>(this)]( request.setResponseCallback([uri, self = QPointer<DocumentSymbolCache>(this)](

View File

@@ -237,43 +237,25 @@ void LanguageClientOutlineWidget::onItemActivated(const QModelIndex &index)
m_editor->widget()->setFocus(); m_editor->widget()->setFocus();
} }
bool LanguageClientOutlineWidgetFactory::clientSupportsDocumentSymbols(
const Client *client, const TextEditor::TextDocument *doc)
{
if (!client)
return false;
DynamicCapabilities dc = client->dynamicCapabilities();
if (dc.isRegistered(DocumentSymbolsRequest::methodName).value_or(false)) {
TextDocumentRegistrationOptions options(dc.option(DocumentSymbolsRequest::methodName));
return !options.isValid()
|| options.filterApplies(doc->filePath(), Utils::mimeTypeForName(doc->mimeType()));
}
const Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> &provider
= client->capabilities().documentSymbolProvider();
if (!provider.has_value())
return false;
if (Utils::holds_alternative<bool>(*provider))
return Utils::get<bool>(*provider);
return true;
}
bool LanguageClientOutlineWidgetFactory::supportsEditor(Core::IEditor *editor) const bool LanguageClientOutlineWidgetFactory::supportsEditor(Core::IEditor *editor) const
{ {
auto doc = qobject_cast<TextEditor::TextDocument *>(editor->document()); if (auto doc = qobject_cast<TextEditor::TextDocument *>(editor->document())) {
if (!doc) if (Client *client = LanguageClientManager::clientForDocument(doc))
return client->supportsDocumentSymbols(doc);
}
return false; return false;
return clientSupportsDocumentSymbols(LanguageClientManager::clientForDocument(doc), doc);
} }
TextEditor::IOutlineWidget *LanguageClientOutlineWidgetFactory::createWidget(Core::IEditor *editor) TextEditor::IOutlineWidget *LanguageClientOutlineWidgetFactory::createWidget(Core::IEditor *editor)
{ {
auto textEditor = qobject_cast<TextEditor::BaseTextEditor *>(editor); auto textEditor = qobject_cast<TextEditor::BaseTextEditor *>(editor);
QTC_ASSERT(textEditor, return nullptr); QTC_ASSERT(textEditor, return nullptr);
Client *client = LanguageClientManager::clientForDocument(textEditor->textDocument()); if (Client *client = LanguageClientManager::clientForDocument(textEditor->textDocument())) {
if (!client || !clientSupportsDocumentSymbols(client, textEditor->textDocument())) if (client->supportsDocumentSymbols(textEditor->textDocument()))
return nullptr;
return new LanguageClientOutlineWidget(client, textEditor); return new LanguageClientOutlineWidget(client, textEditor);
} }
return nullptr;
}
class OutlineComboBox : public Utils::TreeViewComboBox class OutlineComboBox : public Utils::TreeViewComboBox
{ {
@@ -297,8 +279,7 @@ Utils::TreeViewComboBox *LanguageClientOutlineWidgetFactory::createComboBox(Clie
{ {
auto textEditor = qobject_cast<TextEditor::BaseTextEditor *>(editor); auto textEditor = qobject_cast<TextEditor::BaseTextEditor *>(editor);
QTC_ASSERT(textEditor, return nullptr); QTC_ASSERT(textEditor, return nullptr);
TextEditor::TextDocument *document = textEditor->textDocument(); if (!client || !client->supportsDocumentSymbols(textEditor->textDocument()))
if (!client || !clientSupportsDocumentSymbols(client, document))
return nullptr; return nullptr;
return new OutlineComboBox(client, textEditor); return new OutlineComboBox(client, textEditor);

View File

@@ -40,8 +40,6 @@ public:
using IOutlineWidgetFactory::IOutlineWidgetFactory; using IOutlineWidgetFactory::IOutlineWidgetFactory;
static Utils::TreeViewComboBox *createComboBox(Client *client, Core::IEditor *editor); static Utils::TreeViewComboBox *createComboBox(Client *client, Core::IEditor *editor);
static bool clientSupportsDocumentSymbols(const Client *client,
const TextEditor::TextDocument *doc);
// IOutlineWidgetFactory interface // IOutlineWidgetFactory interface
public: public:
bool supportsEditor(Core::IEditor *editor) const override; bool supportsEditor(Core::IEditor *editor) const override;

View File

@@ -278,8 +278,8 @@ void updateEditorToolBar(Core::IEditor *editor)
}); });
} }
if (!extras->m_client || extras->m_client != client || if (!extras->m_client || !client || extras->m_client != client
!LanguageClientOutlineWidgetFactory::clientSupportsDocumentSymbols(client, document)) { || !client->supportsDocumentSymbols(document)) {
if (extras->m_outlineAction) { if (extras->m_outlineAction) {
widget->toolBar()->removeAction(extras->m_outlineAction); widget->toolBar()->removeAction(extras->m_outlineAction);
delete extras->m_outlineAction; delete extras->m_outlineAction;