/**************************************************************************** ** ** Copyright (C) 2018 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 "languagefeatures.h" #include namespace LanguageServerProtocol { constexpr const char HoverRequest::methodName[]; constexpr const char GotoDefinitionRequest::methodName[]; constexpr const char GotoTypeDefinitionRequest::methodName[]; constexpr const char GotoImplementationRequest::methodName[]; constexpr const char FindReferencesRequest::methodName[]; constexpr const char DocumentHighlightsRequest::methodName[]; constexpr const char DocumentSymbolsRequest::methodName[]; constexpr const char CodeActionRequest::methodName[]; constexpr const char CodeLensRequest::methodName[]; constexpr const char CodeLensResolveRequest::methodName[]; constexpr const char DocumentLinkRequest::methodName[]; constexpr const char DocumentLinkResolveRequest::methodName[]; constexpr const char DocumentColorRequest::methodName[]; constexpr const char ColorPresentationRequest::methodName[]; constexpr const char DocumentFormattingRequest::methodName[]; constexpr const char DocumentRangeFormattingRequest::methodName[]; constexpr const char DocumentOnTypeFormattingRequest::methodName[]; constexpr const char RenameRequest::methodName[]; constexpr const char SignatureHelpRequest::methodName[]; MarkedString LanguageServerProtocol::Hover::content() const { return MarkedString(value(contentKey)); } void Hover::setContent(const MarkedString &content) { if (auto val = Utils::get_if(&content)) insert(contentKey, *val); else if (auto val = Utils::get_if(&content)) insert(contentKey, *val); else if (auto val = Utils::get_if>(&content)) insert(contentKey, LanguageClientArray(*val).toJson()); else QTC_ASSERT_STRING("LanguageClient Using unknown type Hover::setContent"); } HoverRequest::HoverRequest(const TextDocumentPositionParams ¶ms) : Request(methodName, params) { } Utils::optional ParameterInformation::documentation() const { QJsonValue documentation = value(documentationKey); if (documentation.isUndefined()) return Utils::nullopt; return MarkupOrString(documentation); } bool SignatureHelp::isValid(QStringList *error) const { return checkArray(error, signaturesKey); } GotoDefinitionRequest::GotoDefinitionRequest(const TextDocumentPositionParams ¶ms) : Request(methodName, params) { } GotoTypeDefinitionRequest::GotoTypeDefinitionRequest(const TextDocumentPositionParams ¶ms) : Request(methodName, params) { } GotoImplementationRequest::GotoImplementationRequest(const TextDocumentPositionParams ¶ms) : Request(methodName, params) { } FindReferencesRequest::FindReferencesRequest(const ReferenceParams ¶ms) : Request(methodName, params) { } DocumentHighlightsRequest::DocumentHighlightsRequest(const TextDocumentPositionParams ¶ms) : Request(methodName, params) { } DocumentSymbolsRequest::DocumentSymbolsRequest(const DocumentSymbolParams ¶ms) : Request(methodName, params) { } Utils::optional > CodeActionParams::CodeActionContext::only() const { return optionalArray(onlyKey); } void CodeActionParams::CodeActionContext::setOnly(const QList &only) { insertArray(onlyKey, only); } bool CodeActionParams::CodeActionContext::isValid(QStringList *error) const { return checkArray(error, diagnosticsKey); } bool CodeActionParams::isValid(QStringList *error) const { return check(error, textDocumentKey) && check(error, rangeKey) && check(error, contextKey); } CodeActionRequest::CodeActionRequest(const CodeActionParams ¶ms) : Request(methodName, params) { } CodeLensRequest::CodeLensRequest(const CodeLensParams ¶ms) : Request(methodName, params) { } CodeLensResolveRequest::CodeLensResolveRequest(const CodeLens ¶ms) : Request(methodName, params) { } DocumentLinkRequest::DocumentLinkRequest(const DocumentLinkParams ¶ms) : Request(methodName, params) { } DocumentLinkResolveRequest::DocumentLinkResolveRequest(const DocumentLink ¶ms) : Request(methodName, params) { } DocumentColorRequest::DocumentColorRequest(const DocumentColorParams ¶ms) : Request(methodName, params) { } bool Color::isValid(QStringList *error) const { return check(error, redKey) && check(error, greenKey) && check(error, blueKey) && check(error, alphaKey); } bool ColorPresentationParams::isValid(QStringList *error) const { return check(error, textDocumentKey) && check(error, colorInfoKey) && check(error, rangeKey); } ColorPresentationRequest::ColorPresentationRequest(const ColorPresentationParams ¶ms) : Request(methodName, params) { } QHash FormattingOptions::properties() const { QHash ret; for (const QString &key : keys()) { if (key == tabSizeKey || key == insertSpaceKey) continue; QJsonValue property = value(key); if (property.isBool()) ret[key] = property.toBool(); if (property.isDouble()) ret[key] = property.toDouble(); if (property.isString()) ret[key] = property.toString(); } return ret; } void FormattingOptions::setProperty(const QString &key, const DocumentFormattingProperty &property) { using namespace Utils; if (auto val = get_if(&property)) insert(key, *val); else if (auto val = get_if(&property)) insert(key, *val); else if (auto val = get_if(&property)) insert(key, *val); } bool FormattingOptions::isValid(QStringList *error) const { return Utils::allOf(keys(), [this, &error](auto key){ return (key == tabSizeKey && this->check(error, key)) || (key == insertSpaceKey && this->check(error, key)) || this->check(error, key); }); } bool DocumentFormattingParams::isValid(QStringList *error) const { return check(error, textDocumentKey) && check(error, optionsKey); } DocumentFormattingRequest::DocumentFormattingRequest(const DocumentFormattingParams ¶ms) : Request(methodName, params) { } bool DocumentRangeFormattingParams::isValid(QStringList *error) const { return check(error, textDocumentKey) && check(error, rangeKey) && check(error, optionsKey); } DocumentRangeFormattingRequest::DocumentRangeFormattingRequest( const DocumentFormattingParams ¶ms) : Request(methodName, params) { } bool DocumentOnTypeFormattingParams::isValid(QStringList *error) const { return check(error, textDocumentKey) && check(error, positionKey) && check(error, chKey) && check(error, optionsKey); } DocumentOnTypeFormattingRequest::DocumentOnTypeFormattingRequest( const DocumentFormattingParams ¶ms) : Request(methodName, params) { } bool RenameParams::isValid(QStringList *error) const { return check(error, textDocumentKey) && check(error, positionKey) && check(error, newNameKey); } RenameRequest::RenameRequest(const RenameParams ¶ms) : Request(methodName, params) { } Utils::optional DocumentLink::target() const { Utils::optional optionalTarget = optionalValue(targetKey); return optionalTarget.has_value() ? Utils::make_optional(DocumentUri::fromProtocol(optionalTarget.value())) : Utils::nullopt; } TextDocumentParams::TextDocumentParams() : TextDocumentParams(TextDocumentIdentifier()) { } TextDocumentParams::TextDocumentParams(const TextDocumentIdentifier &identifier) : JsonObject() { setTextDocument(identifier); } GotoResult::GotoResult(const QJsonValue &value) { if (value.isArray()) { QList locations; for (auto arrayValue : value.toArray()) { if (arrayValue.isObject()) locations.append(Location(arrayValue.toObject())); } emplace>(locations); } else if (value.isObject()) { emplace(value.toObject()); } else { emplace(nullptr); } } template QList documentSymbolsResultArray(const QJsonArray &array) { QList ret; for (const auto &arrayValue : array) { if (arrayValue.isObject()) ret << Symbol(arrayValue.toObject()); } return ret; } DocumentSymbolsResult::DocumentSymbolsResult(const QJsonValue &value) { if (value.isArray()) { QJsonArray array = value.toArray(); if (array.isEmpty()) { *this = QList(); } else { QJsonObject arrayObject = array.first().toObject(); if (arrayObject.contains(rangeKey)) *this = documentSymbolsResultArray(array); else *this = documentSymbolsResultArray(array); } } else { *this = nullptr; } } DocumentHighlightsResult::DocumentHighlightsResult(const QJsonValue &value) { if (value.isArray()) { QList highlights; for (auto arrayValue : value.toArray()) { if (arrayValue.isObject()) highlights.append(DocumentHighlight(arrayValue.toObject())); } *this = highlights; } else { *this = nullptr; } } MarkedString::MarkedString(const QJsonValue &value) { if (value.isArray()) { emplace>( LanguageClientArray(value).toList()); } else if (value.isObject()) { const QJsonObject &object = value.toObject(); MarkedLanguageString markedLanguageString(object); if (markedLanguageString.isValid(nullptr)) emplace(markedLanguageString); else emplace(MarkupContent(object)); } } bool MarkedString::isValid(QStringList *errorHierarchy) const { if (Utils::holds_alternative(*this) || Utils::holds_alternative(*this) || Utils::holds_alternative>(*this)) { return true; } if (errorHierarchy) { *errorHierarchy << QCoreApplication::translate( "LanguageServerProtocol::MarkedString", "MarkedString should be either MarkedLanguageString, " "MarkupContent, or QList."); } return false; } DocumentFormattingProperty::DocumentFormattingProperty(const QJsonValue &value) { if (value.isBool()) *this = value.toBool(); if (value.isDouble()) *this = value.toDouble(); if (value.isString()) *this = value.toString(); } bool DocumentFormattingProperty::isValid(QStringList *error) const { if (Utils::holds_alternative(*this) || Utils::holds_alternative(*this) || Utils::holds_alternative(*this)) { return true; } if (error) { *error << QCoreApplication::translate( "LanguageServerProtocol::MarkedString", "DocumentFormattingProperty should be either bool, double, or QString."); } return false; } SignatureHelpRequest::SignatureHelpRequest(const TextDocumentPositionParams ¶ms) : Request(methodName, params) { } CodeActionResult::CodeActionResult(const QJsonValue &val) { using ResultArray = QList>; if (val.isArray()) { const QJsonArray array = val.toArray(); ResultArray result; for (const QJsonValue &val : array) { Command command(val); if (command.isValid(nullptr)) result << command; else result << CodeAction(val); } emplace(result); return; } emplace(nullptr); } bool CodeAction::isValid(QStringList *error) const { return check(error, titleKey) && checkOptional(error, codeActionKindKey) && checkOptionalArray(error, diagnosticsKey) && checkOptional(error, editKey) && checkOptional(error, commandKey); } } // namespace LanguageServerProtocol