// Copyright (C) 2018 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "servercapabilities.h" namespace lsp { std::optional ServerCapabilities::textDocumentSync() const { const QJsonValue &sync = value(textDocumentSyncKey); if (sync.isUndefined()) return std::nullopt; return std::make_optional(sync.isDouble() ? TextDocumentSync(sync.toInt()) : TextDocumentSync(TextDocumentSyncOptions(sync.toObject()))); } void ServerCapabilities::setTextDocumentSync(const ServerCapabilities::TextDocumentSync &textDocumentSync) { insertVariant(textDocumentSyncKey, textDocumentSync); } TextDocumentSyncKind ServerCapabilities::textDocumentSyncKindHelper() { if (std::optional sync = textDocumentSync()) { if (auto kind = std::get_if(&*sync)) return static_cast(*kind); if (auto options = std::get_if(&*sync)) { if (const std::optional &change = options->change()) return static_cast(*change); } } return TextDocumentSyncKind::None; } std::optional> ServerCapabilities::hoverProvider() const { using RetType = std::variant; const QJsonValue &provider = value(hoverProviderKey); if (provider.isBool()) return std::make_optional(RetType(provider.toBool())); if (provider.isObject()) return std::make_optional(RetType(WorkDoneProgressOptions(provider.toObject()))); return std::nullopt; } void ServerCapabilities::setHoverProvider( const std::variant &hoverProvider) { insertVariant(hoverProviderKey, hoverProvider); } std::optional> ServerCapabilities::definitionProvider() const { using RetType = std::variant; const QJsonValue &provider = value(definitionProviderKey); if (provider.isUndefined() || !(provider.isBool() || provider.isObject())) return std::nullopt; return std::make_optional(provider.isBool() ? RetType(provider.toBool()) : RetType(RegistrationOptions(provider.toObject()))); } void ServerCapabilities::setDefinitionProvider( const std::variant &definitionProvider) { insertVariant(definitionProviderKey, definitionProvider); } std::optional> ServerCapabilities::typeDefinitionProvider() const { using RetType = std::variant; const QJsonValue &provider = value(typeDefinitionProviderKey); if (provider.isUndefined() || !(provider.isBool() || provider.isObject())) return std::nullopt; return std::make_optional(provider.isBool() ? RetType(provider.toBool()) : RetType(RegistrationOptions(provider.toObject()))); } void ServerCapabilities::setTypeDefinitionProvider( const std::variant &typeDefinitionProvider) { insertVariant(typeDefinitionProviderKey, typeDefinitionProvider); } std::optional> ServerCapabilities::implementationProvider() const { using RetType = std::variant; const QJsonValue &provider = value(implementationProviderKey); if (provider.isUndefined() || !(provider.isBool() || provider.isObject())) return std::nullopt; return std::make_optional(provider.isBool() ? RetType(provider.toBool()) : RetType(RegistrationOptions(provider.toObject()))); } void ServerCapabilities::setImplementationProvider( const std::variant &implementationProvider) { insertVariant(implementationProviderKey, implementationProvider); } std::optional> ServerCapabilities::referencesProvider() const { using RetType = std::variant; const QJsonValue &provider = value(referencesProviderKey); if (provider.isBool()) return std::make_optional(RetType(provider.toBool())); if (provider.isObject()) return std::make_optional(RetType(WorkDoneProgressOptions(provider.toObject()))); return std::nullopt; } void ServerCapabilities::setReferencesProvider( const std::variant &referencesProvider) { insertVariant(referencesProviderKey, referencesProvider); } std::optional> ServerCapabilities::documentHighlightProvider() const { using RetType = std::variant; const QJsonValue &provider = value(documentHighlightProviderKey); if (provider.isBool()) return std::make_optional(RetType(provider.toBool())); if (provider.isObject()) return std::make_optional(RetType(WorkDoneProgressOptions(provider.toObject()))); return std::nullopt; } void ServerCapabilities::setDocumentHighlightProvider( const std::variant &documentHighlightProvider) { insertVariant(documentHighlightProviderKey, documentHighlightProvider); } std::optional> ServerCapabilities::documentSymbolProvider() const { using RetType = std::variant; const QJsonValue &provider = value(documentSymbolProviderKey); if (provider.isBool()) return std::make_optional(RetType(provider.toBool())); if (provider.isObject()) return std::make_optional(RetType(WorkDoneProgressOptions(provider.toObject()))); return std::nullopt; } void ServerCapabilities::setDocumentSymbolProvider( std::variant documentSymbolProvider) { insertVariant(documentSymbolProviderKey, documentSymbolProvider); } std::optional ServerCapabilities::semanticTokensProvider() const { return optionalValue(semanticTokensProviderKey); } void ServerCapabilities::setSemanticTokensProvider( const SemanticTokensOptions &semanticTokensProvider) { insert(semanticTokensProviderKey, semanticTokensProvider); } std::optional > ServerCapabilities::callHierarchyProvider() const { const QJsonValue &provider = value(callHierarchyProviderKey); if (provider.isBool()) return provider.toBool(); else if (provider.isObject()) return WorkDoneProgressOptions(provider.toObject()); return std::nullopt; } void ServerCapabilities::setCallHierarchyProvider( const std::variant &callHierarchyProvider) { QJsonValue val; if (std::holds_alternative(callHierarchyProvider)) val = std::get(callHierarchyProvider); else if (std::holds_alternative(callHierarchyProvider)) val = QJsonObject(std::get(callHierarchyProvider)); insert(callHierarchyProviderKey, val); } std::optional> ServerCapabilities::workspaceSymbolProvider() const { using RetType = std::variant; const QJsonValue &provider = value(workspaceSymbolProviderKey); if (provider.isBool()) return std::make_optional(RetType(provider.toBool())); if (provider.isObject()) return std::make_optional(RetType(WorkDoneProgressOptions(provider.toObject()))); return std::nullopt; } void ServerCapabilities::setWorkspaceSymbolProvider( std::variant workspaceSymbolProvider) { insertVariant(workspaceSymbolProviderKey, workspaceSymbolProvider); } std::optional> ServerCapabilities::codeActionProvider() const { const QJsonValue &provider = value(codeActionProviderKey); if (provider.isBool()) return std::make_optional(std::variant(provider.toBool())); if (provider.isObject()) { CodeActionOptions options(provider); if (options.isValid()) return std::make_optional(std::variant(options)); } return std::nullopt; } std::optional> ServerCapabilities::documentFormattingProvider() const { using RetType = std::variant; const QJsonValue &provider = value(documentFormattingProviderKey); if (provider.isBool()) return std::make_optional(RetType(provider.toBool())); if (provider.isObject()) return std::make_optional(RetType(WorkDoneProgressOptions(provider.toObject()))); return std::nullopt; } void ServerCapabilities::setDocumentFormattingProvider( const std::variant &documentFormattingProvider) { insertVariant(documentFormattingProviderKey, documentFormattingProvider); } std::optional> ServerCapabilities::documentRangeFormattingProvider() const { using RetType = std::variant; const QJsonValue &provider = value(documentRangeFormattingProviderKey); if (provider.isBool()) return std::make_optional(RetType(provider.toBool())); if (provider.isObject()) return std::make_optional(RetType(WorkDoneProgressOptions(provider.toObject()))); return std::nullopt; } void ServerCapabilities::setDocumentRangeFormattingProvider( std::variant documentRangeFormattingProvider) { insertVariant(documentRangeFormattingProviderKey, documentRangeFormattingProvider); } std::optional> ServerCapabilities::renameProvider() const { using RetType = std::variant; const QJsonValue &localValue = value(renameProviderKey); if (localValue.isBool()) return RetType(localValue.toBool()); if (localValue.isObject()) return RetType(RenameOptions(localValue.toObject())); return std::nullopt; } void ServerCapabilities::setRenameProvider(std::variant renameProvider) { insertVariant(renameProviderKey, renameProvider); } std::optional> ServerCapabilities::colorProvider() const { using RetType = std::variant; const QJsonValue &localValue = value(colorProviderKey); if (localValue.isBool()) return RetType(localValue.toBool()); if (localValue.isObject()) return RetType(JsonObject(localValue.toObject())); return std::nullopt; } void ServerCapabilities::setColorProvider(std::variant colorProvider) { insertVariant(renameProviderKey, colorProvider); } std::optional > ServerCapabilities::WorkspaceServerCapabilities::WorkspaceFoldersCapabilities::changeNotifications() const { using RetType = std::variant; const QJsonValue &change = value(changeNotificationsKey); if (change.isUndefined()) return std::nullopt; return std::make_optional(change.isBool() ? RetType(change.toBool()) : RetType(change.toString())); } void ServerCapabilities::WorkspaceServerCapabilities::WorkspaceFoldersCapabilities::setChangeNotifications( std::variant changeNotifications) { insertVariant(changeNotificationsKey, changeNotifications); } bool TextDocumentRegistrationOptions::filterApplies(const Utils::FilePath &fileName) const { Q_UNUSED(fileName) return true; } bool ServerCapabilities::ExecuteCommandOptions::isValid() const { return WorkDoneProgressOptions::isValid() && contains(commandsKey); } bool CodeActionOptions::isValid() const { return WorkDoneProgressOptions::isValid() && contains(codeActionKindsKey); } std::optional> SemanticTokensOptions::range() const { using RetType = std::variant; const QJsonValue &rangeOptions = value(rangeKey); if (rangeOptions.isBool()) return RetType(rangeOptions.toBool()); if (rangeOptions.isObject()) return RetType(rangeOptions.toObject()); return std::nullopt; } void SemanticTokensOptions::setRange(const std::variant &range) { insertVariant(rangeKey, range); } std::optional> SemanticTokensOptions::full() const { using RetType = std::variant; const QJsonValue &fullOptions = value(fullKey); if (fullOptions.isBool()) return RetType(fullOptions.toBool()); if (fullOptions.isObject()) return RetType(FullSemanticTokenOptions(fullOptions.toObject())); return std::nullopt; } void SemanticTokensOptions::setFull( const std::variant &full) { insertVariant(fullKey, full); } SemanticRequestTypes SemanticTokensOptions::supportedRequests() const { SemanticRequestTypes result; QJsonValue rangeValue = value(rangeKey); if (rangeValue.isObject() || rangeValue.toBool()) result |= SemanticRequestType::Range; QJsonValue fullValue = value(fullKey); if (fullValue.isObject()) { SemanticTokensOptions::FullSemanticTokenOptions options(fullValue.toObject()); if (options.delta().value_or(false)) result |= SemanticRequestType::FullDelta; result |= SemanticRequestType::Full; } else if (fullValue.toBool()) { result |= SemanticRequestType::Full; } return result; } } // namespace lsp