2018-07-13 12:33:46 +02:00
|
|
|
/****************************************************************************
|
|
|
|
|
**
|
|
|
|
|
** 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.
|
|
|
|
|
**
|
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include "languageserverprotocol_global.h"
|
|
|
|
|
#include "lsputils.h"
|
|
|
|
|
|
|
|
|
|
#include <QCoreApplication>
|
|
|
|
|
#include <QDebug>
|
|
|
|
|
#include <QJsonObject>
|
|
|
|
|
|
|
|
|
|
namespace LanguageServerProtocol {
|
|
|
|
|
|
|
|
|
|
class LANGUAGESERVERPROTOCOL_EXPORT JsonObject
|
|
|
|
|
{
|
|
|
|
|
Q_DECLARE_TR_FUNCTIONS(LanguageServerProtocol::JsonObject)
|
|
|
|
|
|
|
|
|
|
public:
|
2020-11-04 13:02:21 +01:00
|
|
|
using iterator = QJsonObject::iterator;
|
|
|
|
|
using const_iterator = QJsonObject::const_iterator;
|
|
|
|
|
|
2018-07-13 12:33:46 +02:00
|
|
|
JsonObject() = default;
|
|
|
|
|
|
|
|
|
|
explicit JsonObject(const QJsonObject &object) : m_jsonObject(object) { }
|
|
|
|
|
explicit JsonObject(QJsonObject &&object) : m_jsonObject(std::move(object)) { }
|
|
|
|
|
|
|
|
|
|
JsonObject(const JsonObject &object) : m_jsonObject(object.m_jsonObject) { }
|
|
|
|
|
JsonObject(JsonObject &&object) : m_jsonObject(std::move(object.m_jsonObject)) { }
|
|
|
|
|
|
|
|
|
|
explicit JsonObject(const QJsonValue &value) : m_jsonObject(value.toObject()) { }
|
|
|
|
|
|
|
|
|
|
virtual ~JsonObject() = default;
|
|
|
|
|
|
|
|
|
|
JsonObject &operator=(const JsonObject &other);
|
|
|
|
|
JsonObject &operator=(JsonObject &&other);
|
|
|
|
|
|
|
|
|
|
bool operator==(const JsonObject &other) const { return m_jsonObject == other.m_jsonObject; }
|
|
|
|
|
|
|
|
|
|
operator const QJsonObject&() const { return m_jsonObject; }
|
|
|
|
|
|
2021-02-26 08:29:15 +01:00
|
|
|
virtual bool isValid() const { return true; }
|
2018-07-13 12:33:46 +02:00
|
|
|
|
2020-11-04 13:02:21 +01:00
|
|
|
iterator end() { return m_jsonObject.end(); }
|
|
|
|
|
const_iterator end() const { return m_jsonObject.end(); }
|
2018-07-13 12:33:46 +02:00
|
|
|
|
2020-11-04 13:02:21 +01:00
|
|
|
protected:
|
2018-07-13 12:33:46 +02:00
|
|
|
iterator insert(const QString &key, const JsonObject &value);
|
|
|
|
|
iterator insert(const QString &key, const QJsonValue &value);
|
|
|
|
|
|
2021-02-03 12:17:20 +01:00
|
|
|
template <typename T, typename V>
|
|
|
|
|
iterator insertVariant(const QString &key, const V &variant);
|
|
|
|
|
template <typename T1, typename T2, typename... Args, typename V>
|
|
|
|
|
iterator insertVariant(const QString &key, const V &variant);
|
|
|
|
|
|
2018-07-13 12:33:46 +02:00
|
|
|
// QJSonObject redirections
|
|
|
|
|
QJsonValue value(const QString &key) const { return m_jsonObject.value(key); }
|
|
|
|
|
bool contains(const QString &key) const { return m_jsonObject.contains(key); }
|
|
|
|
|
iterator find(const QString &key) { return m_jsonObject.find(key); }
|
|
|
|
|
const_iterator find(const QString &key) const { return m_jsonObject.find(key); }
|
|
|
|
|
void remove(const QString &key) { m_jsonObject.remove(key); }
|
|
|
|
|
QStringList keys() const { return m_jsonObject.keys(); }
|
|
|
|
|
|
|
|
|
|
// convenience value access
|
|
|
|
|
template<typename T>
|
|
|
|
|
T typedValue(const QString &key) const;
|
|
|
|
|
template<typename T>
|
|
|
|
|
Utils::optional<T> optionalValue(const QString &key) const;
|
|
|
|
|
template<typename T>
|
|
|
|
|
LanguageClientValue<T> clientValue(const QString &key) const;
|
|
|
|
|
template<typename T>
|
|
|
|
|
Utils::optional<LanguageClientValue<T>> optionalClientValue(const QString &key) const;
|
|
|
|
|
template<typename T>
|
|
|
|
|
QList<T> array(const QString &key) const;
|
|
|
|
|
template<typename T>
|
|
|
|
|
Utils::optional<QList<T>> optionalArray(const QString &key) const;
|
|
|
|
|
template<typename T>
|
|
|
|
|
LanguageClientArray<T> clientArray(const QString &key) const;
|
|
|
|
|
template<typename T>
|
|
|
|
|
Utils::optional<LanguageClientArray<T>> optionalClientArray(const QString &key) const;
|
|
|
|
|
template<typename T>
|
|
|
|
|
void insertArray(const QString &key, const QList<T> &array);
|
|
|
|
|
template<typename>
|
|
|
|
|
void insertArray(const QString &key, const QList<JsonObject> &array);
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
QJsonObject m_jsonObject;
|
|
|
|
|
};
|
|
|
|
|
|
2021-02-03 12:17:20 +01:00
|
|
|
template<typename T, typename V>
|
|
|
|
|
JsonObject::iterator JsonObject::insertVariant(const QString &key, const V &variant)
|
|
|
|
|
{
|
|
|
|
|
return Utils::holds_alternative<T>(variant) ? insert(key, Utils::get<T>(variant)) : end();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T1, typename T2, typename... Args, typename V>
|
|
|
|
|
JsonObject::iterator JsonObject::insertVariant(const QString &key, const V &variant)
|
|
|
|
|
{
|
|
|
|
|
auto result = insertVariant<T1>(key, variant);
|
|
|
|
|
return result != end() ? result : insertVariant<T2, Args...>(key, variant);
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-13 12:33:46 +02:00
|
|
|
template<typename T>
|
|
|
|
|
T JsonObject::typedValue(const QString &key) const
|
|
|
|
|
{
|
|
|
|
|
return fromJsonValue<T>(value(key));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
|
Utils::optional<T> JsonObject::optionalValue(const QString &key) const
|
|
|
|
|
{
|
|
|
|
|
const QJsonValue &val = value(key);
|
|
|
|
|
return val.isUndefined() ? Utils::nullopt : Utils::make_optional(fromJsonValue<T>(val));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
|
LanguageClientValue<T> JsonObject::clientValue(const QString &key) const
|
|
|
|
|
{
|
|
|
|
|
return LanguageClientValue<T>(value(key));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
|
Utils::optional<LanguageClientValue<T>> JsonObject::optionalClientValue(const QString &key) const
|
|
|
|
|
{
|
|
|
|
|
return contains(key) ? Utils::make_optional(clientValue<T>(key)) : Utils::nullopt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
|
QList<T> JsonObject::array(const QString &key) const
|
|
|
|
|
{
|
2021-03-25 13:14:09 +01:00
|
|
|
const Utils::optional<QList<T>> &array = optionalArray<T>(key);
|
|
|
|
|
if (array.has_value())
|
|
|
|
|
return array.value();
|
|
|
|
|
qCDebug(conversionLog) << QString("Expected array under %1 in:").arg(key) << *this;
|
|
|
|
|
return {};
|
2018-07-13 12:33:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
|
Utils::optional<QList<T>> JsonObject::optionalArray(const QString &key) const
|
|
|
|
|
{
|
2021-03-25 13:14:09 +01:00
|
|
|
const QJsonValue &jsonValue = value(key);
|
|
|
|
|
if (jsonValue.isUndefined())
|
|
|
|
|
return Utils::nullopt;
|
|
|
|
|
return Utils::transform<QList<T>>(jsonValue.toArray(), &fromJsonValue<T>);
|
2018-07-13 12:33:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
|
LanguageClientArray<T> JsonObject::clientArray(const QString &key) const
|
|
|
|
|
{
|
|
|
|
|
return LanguageClientArray<T>(value(key));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
|
Utils::optional<LanguageClientArray<T>> JsonObject::optionalClientArray(const QString &key) const
|
|
|
|
|
{
|
|
|
|
|
const QJsonValue &val = value(key);
|
|
|
|
|
return !val.isUndefined() ? Utils::make_optional(LanguageClientArray<T>(value(key)))
|
|
|
|
|
: Utils::nullopt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
|
void JsonObject::insertArray(const QString &key, const QList<T> &array)
|
|
|
|
|
{
|
|
|
|
|
QJsonArray jsonArray;
|
|
|
|
|
for (const T &item : array)
|
|
|
|
|
jsonArray.append(QJsonValue(item));
|
|
|
|
|
insert(key, jsonArray);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename >
|
|
|
|
|
void JsonObject::insertArray(const QString &key, const QList<JsonObject> &array)
|
|
|
|
|
{
|
|
|
|
|
QJsonArray jsonArray;
|
|
|
|
|
for (const JsonObject &item : array)
|
|
|
|
|
jsonArray.append(item.m_jsonObject);
|
|
|
|
|
insert(key, jsonArray);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace LanguageServerProtocol
|