diff options
Diffstat (limited to 'src/qmlcompiler/qqmljsregistercontent_p.h')
-rw-r--r-- | src/qmlcompiler/qqmljsregistercontent_p.h | 292 |
1 files changed, 292 insertions, 0 deletions
diff --git a/src/qmlcompiler/qqmljsregistercontent_p.h b/src/qmlcompiler/qqmljsregistercontent_p.h new file mode 100644 index 0000000000..bbf5008399 --- /dev/null +++ b/src/qmlcompiler/qqmljsregistercontent_p.h @@ -0,0 +1,292 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#ifndef QQMLJSREGISTERCONTENT_P_H +#define QQMLJSREGISTERCONTENT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#include "qqmljsscope_p.h" +#include <QtCore/qhash.h> +#include <QtCore/qstring.h> + +#include <variant> + +QT_BEGIN_NAMESPACE + +class Q_QMLCOMPILER_EXPORT QQmlJSRegisterContent +{ +public: + enum ContentVariant { + ObjectById, + Singleton, + Script, + MetaType, + + JavaScriptGlobal, + JavaScriptObject, + JavaScriptScopeProperty, + GenericObjectProperty, // Can be JSObject property or QVariantMap + + ScopeProperty, + ScopeMethod, + ScopeAttached, + ScopeModulePrefix, + ExtensionScopeProperty, + ExtensionScopeMethod, + + ObjectProperty, + ObjectMethod, + ObjectEnum, + ObjectAttached, + ObjectModulePrefix, + ExtensionObjectProperty, + ExtensionObjectMethod, + ExtensionObjectEnum, + + MethodReturnValue, + JavaScriptReturnValue, + + ListValue, + ListIterator, + Builtin, + Unknown, + }; + + enum { InvalidLookupIndex = -1 }; + + QQmlJSRegisterContent() = default; + bool isValid() const { return !m_storedType.isNull(); } + + QString descriptiveName() const; + + friend bool operator==(const QQmlJSRegisterContent &a, const QQmlJSRegisterContent &b) + { + return a.m_storedType == b.m_storedType && a.m_variant == b.m_variant + && a.m_scope == b.m_scope && a.m_content == b.m_content; + } + + friend bool operator!=(const QQmlJSRegisterContent &a, const QQmlJSRegisterContent &b) + { + return !(a == b); + } + + bool isType() const { return m_content.index() == Type; } + bool isProperty() const { return m_content.index() == Property; } + bool isEnumeration() const { return m_content.index() == Enum; } + bool isMethod() const { return m_content.index() == Method; } + bool isImportNamespace() const { return m_content.index() == ImportNamespace; } + bool isConversion() const { return m_content.index() == Conversion; } + bool isList() const; + + bool isWritable() const; + + QQmlJSScope::ConstPtr storedType() const { return m_storedType; } + QQmlJSScope::ConstPtr scopeType() const { return m_scope; } + + QQmlJSScope::ConstPtr type() const + { + return std::get<std::pair<QQmlJSScope::ConstPtr, int>>(m_content).first; + } + QQmlJSMetaProperty property() const + { + return std::get<PropertyLookup>(m_content).property; + } + int baseLookupIndex() const + { + return std::get<PropertyLookup>(m_content).baseLookupIndex; + } + int resultLookupIndex() const + { + switch (m_content.index()) { + case Type: + return std::get<std::pair<QQmlJSScope::ConstPtr, int>>(m_content).second; + case Property: + return std::get<PropertyLookup>(m_content).resultLookupIndex; + default: + return InvalidLookupIndex; + } + } + QQmlJSMetaEnum enumeration() const + { + return std::get<std::pair<QQmlJSMetaEnum, QString>>(m_content).first; + } + QString enumMember() const + { + return std::get<std::pair<QQmlJSMetaEnum, QString>>(m_content).second; + } + QList<QQmlJSMetaMethod> method() const { return std::get<QList<QQmlJSMetaMethod>>(m_content); } + uint importNamespace() const { return std::get<uint>(m_content); } + + QQmlJSScope::ConstPtr conversionResult() const + { + return std::get<ConvertedTypes>(m_content).result; + } + + QQmlJSScope::ConstPtr conversionResultScope() const + { + return std::get<ConvertedTypes>(m_content).resultScope; + } + + QList<QQmlJSScope::ConstPtr> conversionOrigins() const + { + return std::get<ConvertedTypes>(m_content).origins; + } + + ContentVariant variant() const { return m_variant; } + + friend size_t qHash(const QQmlJSRegisterContent ®isterContent, size_t seed = 0) + { + seed = qHashMulti(seed, registerContent.m_storedType, registerContent.m_content.index(), + registerContent.m_scope, registerContent.m_variant); + switch (registerContent.m_content.index()) { + case Type: + return qHash(std::get<std::pair<QQmlJSScope::ConstPtr, int>>(registerContent.m_content), + seed); + case Property: + return qHash(std::get<PropertyLookup>(registerContent.m_content), seed); + case Enum: + return qHash(std::get<std::pair<QQmlJSMetaEnum, QString>>(registerContent.m_content), + seed); + case Method: + return qHash(std::get<QList<QQmlJSMetaMethod>>(registerContent.m_content), seed); + case ImportNamespace: + return qHash(std::get<uint>(registerContent.m_content), seed); + case Conversion: + return qHash(std::get<ConvertedTypes>(registerContent.m_content), seed); + } + + Q_UNREACHABLE_RETURN(seed); + } + + static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType, + const QQmlJSScope::ConstPtr &type, + int resultLookupIndex, ContentVariant variant, + const QQmlJSScope::ConstPtr &scope = {}); + + static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType, + const QQmlJSMetaProperty &property, + int baseLookupIndex, int resultLookupIndex, + ContentVariant variant, + const QQmlJSScope::ConstPtr &scope); + + static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType, + const QQmlJSMetaEnum &enumeration, + const QString &enumMember, ContentVariant variant, + const QQmlJSScope::ConstPtr &scope); + + static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType, + const QList<QQmlJSMetaMethod> &methods, + ContentVariant variant, + const QQmlJSScope::ConstPtr &scope); + + static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType, + uint importNamespaceStringId, ContentVariant variant, + const QQmlJSScope::ConstPtr &scope = {}); + + static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType, + const QList<QQmlJSScope::ConstPtr> &origins, + const QQmlJSScope::ConstPtr &conversion, + const QQmlJSScope::ConstPtr &conversionScope, + ContentVariant variant, + const QQmlJSScope::ConstPtr &scope = {}); + + QQmlJSRegisterContent storedIn(const QQmlJSScope::ConstPtr &newStoredType) const + { + QQmlJSRegisterContent result = *this; + result.m_storedType = newStoredType; + return result; + } + + QQmlJSRegisterContent castTo(const QQmlJSScope::ConstPtr &newContainedType) const + { + // This is not a conversion but a run time cast. It may result in null or undefined. + QQmlJSRegisterContent result = *this; + result.m_content = std::make_pair(newContainedType, result.resultLookupIndex()); + return result; + } + +private: + enum ContentKind { Type, Property, Enum, Method, ImportNamespace, Conversion }; + + struct ConvertedTypes + { + QList<QQmlJSScope::ConstPtr> origins; + QQmlJSScope::ConstPtr result; + QQmlJSScope::ConstPtr resultScope; + + friend size_t qHash(const ConvertedTypes &types, size_t seed = 0) + { + return qHashMulti(seed, types.origins, types.result, types.resultScope); + } + + friend bool operator==(const ConvertedTypes &a, const ConvertedTypes &b) + { + return a.origins == b.origins && a.result == b.result && a.resultScope == b.resultScope; + } + + friend bool operator!=(const ConvertedTypes &a, const ConvertedTypes &b) + { + return !(a == b); + } + }; + + struct PropertyLookup + { + QQmlJSMetaProperty property; + int baseLookupIndex = InvalidLookupIndex; + int resultLookupIndex = InvalidLookupIndex; + + friend size_t qHash(const PropertyLookup &property, size_t seed = 0) + { + return qHashMulti( + seed, property.property, property.baseLookupIndex, property.resultLookupIndex); + } + + friend bool operator==(const PropertyLookup &a, const PropertyLookup &b) + { + return a.baseLookupIndex == b.baseLookupIndex + && a.resultLookupIndex == b.resultLookupIndex + && a.property == b.property; + } + + friend bool operator!=(const PropertyLookup &a, const PropertyLookup &b) + { + return !(a == b); + } + }; + + using Content = std::variant< + std::pair<QQmlJSScope::ConstPtr, int>, + PropertyLookup, + std::pair<QQmlJSMetaEnum, QString>, + QList<QQmlJSMetaMethod>, + uint, + ConvertedTypes + >; + + QQmlJSRegisterContent(const QQmlJSScope::ConstPtr &storedType, + const QQmlJSScope::ConstPtr &scope, ContentVariant variant) + : m_storedType(storedType), m_scope(scope), m_variant(variant) + { + } + + QQmlJSScope::ConstPtr m_storedType; + QQmlJSScope::ConstPtr m_scope; + Content m_content; + ContentVariant m_variant = Unknown; + + // TODO: Constant string/number/bool/enumval +}; + +QT_END_NAMESPACE + +#endif // REGISTERCONTENT_H |