LSP: support WorkDoneProgressOptions in server capabilities

These options indicate whether a server provides extra messages to track
the status of specific requests.

Change-Id: I3fb78f7fa7144a5a9418b32cb5b33d55b668c484
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
David Schulz
2021-02-02 07:34:15 +01:00
parent aec908180d
commit 7521334261
9 changed files with 270 additions and 68 deletions

View File

@@ -215,6 +215,7 @@ constexpr char valueSetKey[] = "valueSet";
constexpr char versionKey[] = "version"; constexpr char versionKey[] = "version";
constexpr char willSaveKey[] = "willSave"; constexpr char willSaveKey[] = "willSave";
constexpr char willSaveWaitUntilKey[] = "willSaveWaitUntil"; constexpr char willSaveWaitUntilKey[] = "willSaveWaitUntil";
constexpr char workDoneProgressKey[] = "workDoneProgress";
constexpr char workspaceEditKey[] = "workspaceEdit"; constexpr char workspaceEditKey[] = "workspaceEdit";
constexpr char workspaceFoldersKey[] = "workspaceFolders"; constexpr char workspaceFoldersKey[] = "workspaceFolders";
constexpr char workspaceKey[] = "workspace"; constexpr char workspaceKey[] = "workspace";

View File

@@ -55,11 +55,29 @@ TextDocumentSyncKind ServerCapabilities::textDocumentSyncKindHelper()
return TextDocumentSyncKind::None; return TextDocumentSyncKind::None;
} }
Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> ServerCapabilities::hoverProvider()
const
{
using RetType = Utils::variant<bool, WorkDoneProgressOptions>;
const QJsonValue &provider = value(hoverProviderKey);
if (provider.isBool())
return Utils::make_optional(RetType(provider.toBool()));
if (provider.isObject())
return Utils::make_optional(RetType(WorkDoneProgressOptions(provider.toObject())));
return Utils::nullopt;
}
void ServerCapabilities::setHoverProvider(
const Utils::variant<bool, WorkDoneProgressOptions> &hoverProvider)
{
insertVariant<bool, WorkDoneProgressOptions>(hoverProviderKey, hoverProvider);
}
Utils::optional<Utils::variant<bool, ServerCapabilities::RegistrationOptions>> Utils::optional<Utils::variant<bool, ServerCapabilities::RegistrationOptions>>
ServerCapabilities::typeDefinitionProvider() const ServerCapabilities::typeDefinitionProvider() const
{ {
using RetType = Utils::variant<bool, ServerCapabilities::RegistrationOptions>; using RetType = Utils::variant<bool, ServerCapabilities::RegistrationOptions>;
QJsonValue provider = value(typeDefinitionProviderKey); const QJsonValue &provider = value(typeDefinitionProviderKey);
if (provider.isUndefined() || !(provider.isBool() || provider.isObject())) if (provider.isUndefined() || !(provider.isBool() || provider.isObject()))
return Utils::nullopt; return Utils::nullopt;
return Utils::make_optional(provider.isBool() ? RetType(provider.toBool()) return Utils::make_optional(provider.isBool() ? RetType(provider.toBool())
@@ -77,7 +95,7 @@ Utils::optional<Utils::variant<bool, ServerCapabilities::RegistrationOptions>>
ServerCapabilities::implementationProvider() const ServerCapabilities::implementationProvider() const
{ {
using RetType = Utils::variant<bool, ServerCapabilities::RegistrationOptions>; using RetType = Utils::variant<bool, ServerCapabilities::RegistrationOptions>;
QJsonValue provider = value(implementationProviderKey); const QJsonValue &provider = value(implementationProviderKey);
if (provider.isUndefined() || !(provider.isBool() || provider.isObject())) if (provider.isUndefined() || !(provider.isBool() || provider.isObject()))
return Utils::nullopt; return Utils::nullopt;
return Utils::make_optional(provider.isBool() ? RetType(provider.toBool()) return Utils::make_optional(provider.isBool() ? RetType(provider.toBool())
@@ -90,9 +108,85 @@ void ServerCapabilities::setImplementationProvider(
insertVariant<bool, RegistrationOptions>(implementationProviderKey, implementationProvider); insertVariant<bool, RegistrationOptions>(implementationProviderKey, implementationProvider);
} }
Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>>
ServerCapabilities::referencesProvider() const
{
using RetType = Utils::variant<bool, WorkDoneProgressOptions>;
const QJsonValue &provider = value(referencesProviderKey);
if (provider.isBool())
return Utils::make_optional(RetType(provider.toBool()));
if (provider.isObject())
return Utils::make_optional(RetType(WorkDoneProgressOptions(provider.toObject())));
return Utils::nullopt;
}
void ServerCapabilities::setReferencesProvider(
const Utils::variant<bool, WorkDoneProgressOptions> &referencesProvider)
{
insertVariant<bool, WorkDoneProgressOptions>(referencesProviderKey,
referencesProvider);
}
Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>>
ServerCapabilities::documentHighlightProvider() const
{
using RetType = Utils::variant<bool, WorkDoneProgressOptions>;
const QJsonValue &provider = value(documentHighlightProviderKey);
if (provider.isBool())
return Utils::make_optional(RetType(provider.toBool()));
if (provider.isObject())
return Utils::make_optional(RetType(WorkDoneProgressOptions(provider.toObject())));
return Utils::nullopt;
}
void ServerCapabilities::setDocumentHighlightProvider(
const Utils::variant<bool, WorkDoneProgressOptions> &documentHighlightProvider)
{
insertVariant<bool, WorkDoneProgressOptions>(documentHighlightProviderKey,
documentHighlightProvider);
}
Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>>
ServerCapabilities::documentSymbolProvider() const
{
using RetType = Utils::variant<bool, WorkDoneProgressOptions>;
const QJsonValue &provider = value(documentSymbolProviderKey);
if (provider.isBool())
return Utils::make_optional(RetType(provider.toBool()));
if (provider.isObject())
return Utils::make_optional(RetType(WorkDoneProgressOptions(provider.toObject())));
return Utils::nullopt;
}
void ServerCapabilities::setDocumentSymbolProvider(
Utils::variant<bool, WorkDoneProgressOptions> documentSymbolProvider)
{
insertVariant<bool, WorkDoneProgressOptions>(documentSymbolProviderKey,
documentSymbolProvider);
}
Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>>
ServerCapabilities::workspaceSymbolProvider() const
{
using RetType = Utils::variant<bool, WorkDoneProgressOptions>;
const QJsonValue &provider = value(workspaceSymbolProviderKey);
if (provider.isBool())
return Utils::make_optional(RetType(provider.toBool()));
if (provider.isObject())
return Utils::make_optional(RetType(WorkDoneProgressOptions(provider.toObject())));
return Utils::nullopt;
}
void ServerCapabilities::setWorkspaceSymbolProvider(
Utils::variant<bool, WorkDoneProgressOptions> workspaceSymbolProvider)
{
insertVariant<bool, WorkDoneProgressOptions>(workspaceSymbolProviderKey,
workspaceSymbolProvider);
}
Utils::optional<Utils::variant<bool, CodeActionOptions>> ServerCapabilities::codeActionProvider() const Utils::optional<Utils::variant<bool, CodeActionOptions>> ServerCapabilities::codeActionProvider() const
{ {
QJsonValue provider = value(codeActionProviderKey); const QJsonValue &provider = value(codeActionProviderKey);
if (provider.isBool()) if (provider.isBool())
return Utils::make_optional(Utils::variant<bool, CodeActionOptions>(provider.toBool())); return Utils::make_optional(Utils::variant<bool, CodeActionOptions>(provider.toBool()));
if (provider.isObject()) { if (provider.isObject()) {
@@ -103,6 +197,44 @@ Utils::optional<Utils::variant<bool, CodeActionOptions>> ServerCapabilities::cod
return Utils::nullopt; return Utils::nullopt;
} }
Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>>
ServerCapabilities::documentFormattingProvider() const
{
using RetType = Utils::variant<bool, WorkDoneProgressOptions>;
const QJsonValue &provider = value(documentFormattingProviderKey);
if (provider.isBool())
return Utils::make_optional(RetType(provider.toBool()));
if (provider.isObject())
return Utils::make_optional(RetType(WorkDoneProgressOptions(provider.toObject())));
return Utils::nullopt;
}
void ServerCapabilities::setDocumentFormattingProvider(
const Utils::variant<bool, WorkDoneProgressOptions> &documentFormattingProvider)
{
insertVariant<bool, WorkDoneProgressOptions>(documentFormattingProviderKey,
documentFormattingProvider);
}
Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>>
ServerCapabilities::documentRangeFormattingProvider() const
{
using RetType = Utils::variant<bool, WorkDoneProgressOptions>;
const QJsonValue &provider = value(documentRangeFormattingProviderKey);
if (provider.isBool())
return Utils::make_optional(RetType(provider.toBool()));
if (provider.isObject())
return Utils::make_optional(RetType(WorkDoneProgressOptions(provider.toObject())));
return Utils::nullopt;
}
void ServerCapabilities::setDocumentRangeFormattingProvider(
Utils::variant<bool, WorkDoneProgressOptions> documentRangeFormattingProvider)
{
insertVariant<bool, WorkDoneProgressOptions>(documentRangeFormattingProviderKey,
documentRangeFormattingProvider);
}
Utils::optional<Utils::variant<ServerCapabilities::RenameOptions, bool>> ServerCapabilities::renameProvider() const Utils::optional<Utils::variant<ServerCapabilities::RenameOptions, bool>> ServerCapabilities::renameProvider() const
{ {
using RetType = Utils::variant<ServerCapabilities::RenameOptions, bool>; using RetType = Utils::variant<ServerCapabilities::RenameOptions, bool>;
@@ -164,7 +296,7 @@ Utils::optional<Utils::variant<QString, bool> >
ServerCapabilities::WorkspaceServerCapabilities::WorkspaceFoldersCapabilities::changeNotifications() const ServerCapabilities::WorkspaceServerCapabilities::WorkspaceFoldersCapabilities::changeNotifications() const
{ {
using RetType = Utils::variant<QString, bool>; using RetType = Utils::variant<QString, bool>;
QJsonValue provider = value(implementationProviderKey); const QJsonValue &provider = value(implementationProviderKey);
if (provider.isUndefined()) if (provider.isUndefined())
return Utils::nullopt; return Utils::nullopt;
return Utils::make_optional(provider.isBool() ? RetType(provider.toBool()) return Utils::make_optional(provider.isBool() ? RetType(provider.toBool())
@@ -247,4 +379,34 @@ bool ServerCapabilities::SemanticHighlightingServerCapabilities::isValid(ErrorHi
}); });
} }
bool ServerCapabilities::ExecuteCommandOptions::isValid(ErrorHierarchy *error) const
{
return WorkDoneProgressOptions::isValid(error) && checkArray<QString>(error, commandsKey);
}
bool ServerCapabilities::CompletionOptions::isValid(ErrorHierarchy *error) const
{
return WorkDoneProgressOptions::isValid(error)
&& checkOptionalArray<QString>(error, triggerCharactersKey)
&& checkOptional<bool>(error, resolveProviderKey);
}
bool ServerCapabilities::SignatureHelpOptions::isValid(ErrorHierarchy *error) const
{
return WorkDoneProgressOptions::isValid(error)
&& checkOptionalArray<QString>(error, triggerCharactersKey);
}
bool CodeActionOptions::isValid(ErrorHierarchy *error) const
{
return WorkDoneProgressOptions::isValid(error)
&& checkArray<QString>(error, codeActionKindsKey);
}
bool ServerCapabilities::RenameOptions::isValid(ErrorHierarchy *error) const
{
return WorkDoneProgressOptions::isValid(error)
&& checkOptional<bool>(error, prepareProviderKey);
}
} // namespace LanguageServerProtocol } // namespace LanguageServerProtocol

View File

@@ -29,6 +29,19 @@
namespace LanguageServerProtocol { namespace LanguageServerProtocol {
class LANGUAGESERVERPROTOCOL_EXPORT WorkDoneProgressOptions : public JsonObject
{
public:
using JsonObject::JsonObject;
Utils::optional<bool> workDoneProgress() const { return optionalValue<bool>(workDoneProgressKey); }
void setWorkDoneProgress(bool workDoneProgress) { insert(workDoneProgressKey, workDoneProgress); }
void clearWorkDoneProgress() { remove(workDoneProgressKey); }
bool isValid(ErrorHierarchy *error) const override
{ return checkOptional<bool>(error, workDoneProgressKey); }
};
class LANGUAGESERVERPROTOCOL_EXPORT ResolveProviderOption : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT ResolveProviderOption : public JsonObject
{ {
public: public:
@@ -120,17 +133,16 @@ enum class TextDocumentSyncKind
Incremental = 2 Incremental = 2
}; };
class LANGUAGESERVERPROTOCOL_EXPORT CodeActionOptions : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT CodeActionOptions : public WorkDoneProgressOptions
{ {
public: public:
using JsonObject::JsonObject; using WorkDoneProgressOptions::WorkDoneProgressOptions;
QList<QString> codeActionKinds() const { return array<QString>(codeActionKindsKey); } QList<QString> codeActionKinds() const { return array<QString>(codeActionKindsKey); }
void setCodeActionKinds(const QList<QString> &codeActionKinds) void setCodeActionKinds(const QList<QString> &codeActionKinds)
{ insertArray(codeActionKindsKey, codeActionKinds); } { insertArray(codeActionKindsKey, codeActionKinds); }
bool isValid(ErrorHierarchy *error) const override bool isValid(ErrorHierarchy *error) const override;
{ return checkArray<QString>(error, codeActionKindsKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT ServerCapabilities : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT ServerCapabilities : public JsonObject
@@ -140,10 +152,10 @@ public:
// Defines how the host (editor) should sync document changes to the language server. // Defines how the host (editor) should sync document changes to the language server.
class LANGUAGESERVERPROTOCOL_EXPORT CompletionOptions : public ResolveProviderOption class LANGUAGESERVERPROTOCOL_EXPORT CompletionOptions : public WorkDoneProgressOptions
{ {
public: public:
using ResolveProviderOption::ResolveProviderOption; using WorkDoneProgressOptions::WorkDoneProgressOptions;
// The characters that trigger completion automatically. // The characters that trigger completion automatically.
Utils::optional<QList<QString>> triggerCharacters() const Utils::optional<QList<QString>> triggerCharacters() const
@@ -152,14 +164,17 @@ public:
{ insertArray(triggerCharactersKey, triggerCharacters); } { insertArray(triggerCharactersKey, triggerCharacters); }
void clearTriggerCharacters() { remove(triggerCharactersKey); } void clearTriggerCharacters() { remove(triggerCharactersKey); }
bool isValid(ErrorHierarchy *error) const override Utils::optional<bool> resolveProvider() const { return optionalValue<bool>(resolveProviderKey); }
{ return checkOptionalArray<QString>(error, triggerCharactersKey); } void setResolveProvider(bool resolveProvider) { insert(resolveProviderKey, resolveProvider); }
void clearResolveProvider() { remove(resolveProviderKey); }
bool isValid(ErrorHierarchy *error) const override;
}; };
class LANGUAGESERVERPROTOCOL_EXPORT SignatureHelpOptions : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT SignatureHelpOptions : public WorkDoneProgressOptions
{ {
public: public:
using JsonObject::JsonObject; using WorkDoneProgressOptions::WorkDoneProgressOptions;
// The characters that trigger signature help automatically. // The characters that trigger signature help automatically.
Utils::optional<QList<QString>> triggerCharacters() const Utils::optional<QList<QString>> triggerCharacters() const
@@ -167,6 +182,8 @@ public:
void setTriggerCharacters(const QList<QString> &triggerCharacters) void setTriggerCharacters(const QList<QString> &triggerCharacters)
{ insertArray(triggerCharactersKey, triggerCharacters); } { insertArray(triggerCharactersKey, triggerCharacters); }
void clearTriggerCharacters() { remove(triggerCharactersKey); } void clearTriggerCharacters() { remove(triggerCharactersKey); }
bool isValid(ErrorHierarchy *error) const override;
}; };
using CodeLensOptions = ResolveProviderOption; using CodeLensOptions = ResolveProviderOption;
@@ -197,16 +214,15 @@ public:
using DocumentLinkOptions = ResolveProviderOption; using DocumentLinkOptions = ResolveProviderOption;
class LANGUAGESERVERPROTOCOL_EXPORT ExecuteCommandOptions : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT ExecuteCommandOptions : public WorkDoneProgressOptions
{ {
public: public:
using JsonObject::JsonObject; using WorkDoneProgressOptions::WorkDoneProgressOptions;
QList<QString> commands() const { return array<QString>(commandsKey); } QList<QString> commands() const { return array<QString>(commandsKey); }
void setCommands(const QList<QString> &commands) { insertArray(commandsKey, commands); } void setCommands(const QList<QString> &commands) { insertArray(commandsKey, commands); }
bool isValid(ErrorHierarchy *error) const override bool isValid(ErrorHierarchy *error) const override;
{ return checkArray<QString>(error, commandsKey); }
}; };
using ColorProviderOptions = JsonObject; using ColorProviderOptions = JsonObject;
@@ -244,8 +260,8 @@ public:
TextDocumentSyncKind textDocumentSyncKindHelper(); TextDocumentSyncKind textDocumentSyncKindHelper();
// The server provides hover support. // The server provides hover support.
Utils::optional<bool> hoverProvider() const { return optionalValue<bool>(hoverProviderKey); } Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> hoverProvider() const;
void setHoverProvider(bool hoverProvider) { insert(hoverProviderKey, hoverProvider); } void setHoverProvider(const Utils::variant<bool, WorkDoneProgressOptions> &hoverProvider);
void clearHoverProvider() { remove(hoverProviderKey); } void clearHoverProvider() { remove(hoverProviderKey); }
// The server provides completion support. // The server provides completion support.
@@ -303,29 +319,24 @@ public:
void clearImplementationProvider() { remove(implementationProviderKey); } void clearImplementationProvider() { remove(implementationProviderKey); }
// The server provides find references support. // The server provides find references support.
Utils::optional<bool> referencesProvider() const { return optionalValue<bool>(referencesProviderKey); } Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> referencesProvider() const;
void setReferencesProvider(bool referenceProvider) { insert(referencesProviderKey, referenceProvider); } void setReferencesProvider(const Utils::variant<bool, WorkDoneProgressOptions> &referencesProvider);
void clearReferencesProvider() { remove(referencesProviderKey); } void clearReferencesProvider() { remove(referencesProviderKey); }
// The server provides document highlight support. // The server provides document highlight support.
Utils::optional<bool> documentHighlightProvider() const Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> documentHighlightProvider() const;
{ return optionalValue<bool>(documentHighlightProviderKey); } void setDocumentHighlightProvider(
void setDocumentHighlightProvider(bool documentHighlightProvider) const Utils::variant<bool, WorkDoneProgressOptions> &documentHighlightProvider);
{ insert(documentHighlightProviderKey, documentHighlightProvider); }
void clearDocumentHighlightProvider() { remove(documentHighlightProviderKey); } void clearDocumentHighlightProvider() { remove(documentHighlightProviderKey); }
// The server provides document symbol support. // The server provides document symbol support.
Utils::optional<bool> documentSymbolProvider() const Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> documentSymbolProvider() const;
{ return optionalValue<bool>(documentSymbolProviderKey); } void setDocumentSymbolProvider(Utils::variant<bool, WorkDoneProgressOptions> documentSymbolProvider);
void setDocumentSymbolProvider(bool documentSymbolProvider)
{ insert(documentSymbolProviderKey, documentSymbolProvider); }
void clearDocumentSymbolProvider() { remove(documentSymbolProviderKey); } void clearDocumentSymbolProvider() { remove(documentSymbolProviderKey); }
// The server provides workspace symbol support. // The server provides workspace symbol support.
Utils::optional<bool> workspaceSymbolProvider() const Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> workspaceSymbolProvider() const;
{ return optionalValue<bool>(workspaceSymbolProviderKey); } void setWorkspaceSymbolProvider(Utils::variant<bool, WorkDoneProgressOptions> workspaceSymbolProvider);
void setWorkspaceSymbolProvider(bool workspaceSymbolProvider)
{ insert(workspaceSymbolProviderKey, workspaceSymbolProvider); }
void clearWorkspaceSymbolProvider() { remove(workspaceSymbolProviderKey); } void clearWorkspaceSymbolProvider() { remove(workspaceSymbolProviderKey); }
// The server provides code actions. // The server provides code actions.
@@ -344,31 +355,27 @@ public:
void clearCodeLensProvider() { remove(codeLensProviderKey); } void clearCodeLensProvider() { remove(codeLensProviderKey); }
// The server provides document formatting. // The server provides document formatting.
Utils::optional<bool> documentFormattingProvider() const Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> documentFormattingProvider() const;
{ return optionalValue<bool>(documentFormattingProviderKey); } void setDocumentFormattingProvider(
void setDocumentFormattingProvider(bool documentFormattingProvider) const Utils::variant<bool, WorkDoneProgressOptions> &documentFormattingProvider);
{ insert(documentFormattingProviderKey, documentFormattingProvider); }
void clearDocumentFormattingProvider() { remove(documentFormattingProviderKey); } void clearDocumentFormattingProvider() { remove(documentFormattingProviderKey); }
// The server provides document formatting on typing. // The server provides document formatting on typing.
Utils::optional<bool> documentRangeFormattingProvider() const Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> documentRangeFormattingProvider() const;
{ return optionalValue<bool>(documentRangeFormattingProviderKey); } void setDocumentRangeFormattingProvider(Utils::variant<bool, WorkDoneProgressOptions> documentRangeFormattingProvider);
void setDocumentRangeFormattingProvider(bool documentRangeFormattingProvider)
{ insert(documentRangeFormattingProviderKey, documentRangeFormattingProvider); }
void clearDocumentRangeFormattingProvider() { remove(documentRangeFormattingProviderKey); } void clearDocumentRangeFormattingProvider() { remove(documentRangeFormattingProviderKey); }
class RenameOptions : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT RenameOptions : public WorkDoneProgressOptions
{ {
public: public:
using JsonObject::JsonObject; using WorkDoneProgressOptions::WorkDoneProgressOptions;
// Renames should be checked and tested before being executed. // Renames should be checked and tested before being executed.
Utils::optional<bool> prepareProvider() const { return optionalValue<bool>(prepareProviderKey); } Utils::optional<bool> prepareProvider() const { return optionalValue<bool>(prepareProviderKey); }
void setPrepareProvider(bool prepareProvider) { insert(prepareProviderKey, prepareProvider); } void setPrepareProvider(bool prepareProvider) { insert(prepareProviderKey, prepareProvider); }
void clearPrepareProvider() { remove(prepareProviderKey); } void clearPrepareProvider() { remove(prepareProviderKey); }
bool isValid(ErrorHierarchy * error) const override bool isValid(ErrorHierarchy * error) const override;
{ return checkOptional<bool>(error, prepareProviderKey); }
}; };
// The server provides rename support. // The server provides rename support.

View File

@@ -625,8 +625,13 @@ void Client::cursorPositionChanged(TextEditor::TextEditorWidget *widget)
m_dynamicCapabilities.option(DocumentHighlightsRequest::methodName)); m_dynamicCapabilities.option(DocumentHighlightsRequest::methodName));
if (!option.filterApplies(widget->textDocument()->filePath())) if (!option.filterApplies(widget->textDocument()->filePath()))
return; return;
} else if (!m_serverCapabilities.documentHighlightProvider().value_or(false)) { } else {
return; Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> provider
= m_serverCapabilities.documentHighlightProvider();
if (!provider.has_value())
return;
if (Utils::holds_alternative<bool>(*provider) && !Utils::get<bool>(*provider))
return;
} }
auto runningRequest = m_highlightRequests.find(uri); auto runningRequest = m_highlightRequests.find(uri);
@@ -1233,9 +1238,13 @@ void Client::initializeCallback(const InitializeRequest::Response &initResponse)
qCDebug(LOGLSPCLIENT) << "language server " << m_displayName << " initialized"; qCDebug(LOGLSPCLIENT) << "language server " << m_displayName << " initialized";
m_state = Initialized; m_state = Initialized;
sendContent(InitializeNotification(InitializedParams())); sendContent(InitializeNotification(InitializedParams()));
if (m_dynamicCapabilities.isRegistered(DocumentSymbolsRequest::methodName) Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> documentSymbolProvider
.value_or(capabilities().documentSymbolProvider().value_or(false))) { = capabilities().documentSymbolProvider();
TextEditor::IOutlineWidgetFactory::updateOutline(); if (documentSymbolProvider.has_value()) {
if (!Utils::holds_alternative<bool>(*documentSymbolProvider)
|| Utils::get<bool>(*documentSymbolProvider)) {
TextEditor::IOutlineWidgetFactory::updateOutline();
}
} }
for (auto it = m_openedDocument.cbegin(); it != m_openedDocument.cend(); ++it) for (auto it = m_openedDocument.cbegin(); it != m_openedDocument.cend(); ++it)

View File

@@ -84,8 +84,13 @@ QFutureWatcher<ChangeSet> *LanguageClientFormatter::format(
&& !option.filterApplies(filePath, Utils::mimeTypeForName(m_document->mimeType()))) { && !option.filterApplies(filePath, Utils::mimeTypeForName(m_document->mimeType()))) {
return nullptr; return nullptr;
} }
} else if (!m_client->capabilities().documentRangeFormattingProvider().value_or(false)) { } else {
return nullptr; const Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> &provider
= m_client->capabilities().documentRangeFormattingProvider();
if (!provider.has_value())
return nullptr;
if (Utils::holds_alternative<bool>(*provider) && !Utils::get<bool>(*provider))
return nullptr;
} }
DocumentRangeFormattingParams params; DocumentRangeFormattingParams params;
const DocumentUri uri = DocumentUri::fromFilePath(filePath); const DocumentUri uri = DocumentUri::fromFilePath(filePath);

View File

@@ -74,7 +74,11 @@ void HoverHandler::identifyMatch(TextEditor::TextEditorWidget *editorWidget,
return; return;
} }
bool sendMessage = m_client->capabilities().hoverProvider().value_or(false); const Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> &provider
= m_client->capabilities().hoverProvider();
bool sendMessage = provider.has_value();
if (sendMessage && Utils::holds_alternative<bool>(*provider))
sendMessage = Utils::get<bool>(*provider);
if (Utils::optional<bool> registered = m_client->dynamicCapabilities().isRegistered( if (Utils::optional<bool> registered = m_client->dynamicCapabilities().isRegistered(
HoverRequest::methodName)) { HoverRequest::methodName)) {
sendMessage = registered.value(); sendMessage = registered.value();

View File

@@ -234,7 +234,13 @@ bool LanguageClientOutlineWidgetFactory::clientSupportsDocumentSymbols(
return !options.isValid(nullptr) return !options.isValid(nullptr)
|| options.filterApplies(doc->filePath(), Utils::mimeTypeForName(doc->mimeType())); || options.filterApplies(doc->filePath(), Utils::mimeTypeForName(doc->mimeType()));
} }
return client->capabilities().documentSymbolProvider().value_or(false); 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

View File

@@ -46,7 +46,7 @@ template<typename Request>
static void sendTextDocumentPositionParamsRequest(Client *client, static void sendTextDocumentPositionParamsRequest(Client *client,
const Request &request, const Request &request,
const DynamicCapabilities &dynamicCapabilities, const DynamicCapabilities &dynamicCapabilities,
const Utils::optional<bool> &serverCapability) const ServerCapabilities &serverCapability)
{ {
if (!request.isValid(nullptr)) if (!request.isValid(nullptr))
return; return;
@@ -62,7 +62,11 @@ static void sendTextDocumentPositionParamsRequest(Client *client,
else else
sendMessage = supportedFile; sendMessage = supportedFile;
} else { } else {
sendMessage = serverCapability.value_or(sendMessage) && supportedFile; const Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> &provider
= serverCapability.referencesProvider();
sendMessage = provider.has_value();
if (sendMessage && Utils::holds_alternative<bool>(*provider))
sendMessage = Utils::get<bool>(*provider);
} }
if (sendMessage) if (sendMessage)
client->sendContent(request); client->sendContent(request);
@@ -121,7 +125,7 @@ void SymbolSupport::findLinkAt(TextEditor::TextDocument *document,
sendTextDocumentPositionParamsRequest(m_client, sendTextDocumentPositionParamsRequest(m_client,
request, request,
m_client->dynamicCapabilities(), m_client->dynamicCapabilities(),
m_client->capabilities().referencesProvider()); m_client->capabilities());
} }
@@ -230,7 +234,7 @@ void SymbolSupport::findUsages(TextEditor::TextDocument *document, const QTextCu
sendTextDocumentPositionParamsRequest(m_client, sendTextDocumentPositionParamsRequest(m_client,
request, request,
m_client->dynamicCapabilities(), m_client->dynamicCapabilities(),
m_client->capabilities().referencesProvider()); m_client->capabilities());
} }
static bool supportsRename(Client *client, static bool supportsRename(Client *client,

View File

@@ -221,15 +221,19 @@ void WorkspaceLocatorFilter::prepareSearch(const QString &entry)
QMutexLocker locker(&m_mutex); QMutexLocker locker(&m_mutex);
for (auto client : Utils::filtered(LanguageClientManager::clients(), &Client::reachable)) { for (auto client : Utils::filtered(LanguageClientManager::clients(), &Client::reachable)) {
if (client->capabilities().workspaceSymbolProvider().value_or(false)) { Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> capability
WorkspaceSymbolRequest request(params); = client->capabilities().workspaceSymbolProvider();
request.setResponseCallback( if (!capability.has_value())
[this, client](const WorkspaceSymbolRequest::Response &response) { continue;
handleResponse(client, response); if (Utils::holds_alternative<bool>(*capability) && !Utils::get<bool>(*capability))
}); continue;
m_pendingRequests[client] = request.id(); WorkspaceSymbolRequest request(params);
client->sendContent(request); request.setResponseCallback(
} [this, client](const WorkspaceSymbolRequest::Response &response) {
handleResponse(client, response);
});
m_pendingRequests[client] = request.id();
client->sendContent(request);
} }
} }