1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#ifndef QQMLJSREGISTERCONTENT_P_H
5#define QQMLJSREGISTERCONTENT_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16
17#include "qqmljsscope_p.h"
18#include <QtCore/qhash.h>
19#include <QtCore/qstring.h>
20
21#include <variant>
22
23QT_BEGIN_NAMESPACE
24
25class Q_QMLCOMPILER_PRIVATE_EXPORT QQmlJSRegisterContent
26{
27public:
28 enum ContentVariant {
29 ObjectById,
30 Singleton,
31 Script,
32 MetaType,
33
34 JavaScriptGlobal,
35 JavaScriptObject,
36 JavaScriptScopeProperty,
37 GenericObjectProperty, // Can be JSObject property or QVariantMap
38
39 ScopeProperty,
40 ScopeMethod,
41 ScopeAttached,
42 ScopeModulePrefix,
43 ExtensionScopeProperty,
44 ExtensionScopeMethod,
45
46 ObjectProperty,
47 ObjectMethod,
48 ObjectEnum,
49 ObjectAttached,
50 ObjectModulePrefix,
51 ExtensionObjectProperty,
52 ExtensionObjectMethod,
53 ExtensionObjectEnum,
54
55 MethodReturnValue,
56 JavaScriptReturnValue,
57
58 ListValue,
59 Builtin,
60 Unknown,
61 };
62
63 QQmlJSRegisterContent() = default;
64 bool isValid() const { return !m_storedType.isNull(); }
65
66 QString descriptiveName() const;
67
68 friend bool operator==(const QQmlJSRegisterContent &a, const QQmlJSRegisterContent &b)
69 {
70 return a.m_storedType == b.m_storedType && a.m_variant == b.m_variant
71 && a.m_scope == b.m_scope && a.m_content == b.m_content;
72 }
73
74 friend bool operator!=(const QQmlJSRegisterContent &a, const QQmlJSRegisterContent &b)
75 {
76 return !(a == b);
77 }
78
79 bool isType() const { return m_content.index() == Type; }
80 bool isProperty() const { return m_content.index() == Property; }
81 bool isEnumeration() const { return m_content.index() == Enum; }
82 bool isMethod() const { return m_content.index() == Method; }
83 bool isImportNamespace() const { return m_content.index() == ImportNamespace; }
84 bool isConversion() const { return m_content.index() == Conversion; }
85 bool isList() const;
86
87 bool isWritable() const;
88
89 QQmlJSScope::ConstPtr storedType() const { return m_storedType; }
90 QQmlJSScope::ConstPtr scopeType() const { return m_scope; }
91
92 QQmlJSScope::ConstPtr type() const { return std::get<QQmlJSScope::ConstPtr>(v: m_content); }
93 QQmlJSMetaProperty property() const { return std::get<QQmlJSMetaProperty>(v: m_content); }
94 QQmlJSMetaEnum enumeration() const
95 {
96 return std::get<std::pair<QQmlJSMetaEnum, QString>>(v: m_content).first;
97 }
98 QString enumMember() const
99 {
100 return std::get<std::pair<QQmlJSMetaEnum, QString>>(v: m_content).second;
101 }
102 QList<QQmlJSMetaMethod> method() const { return std::get<QList<QQmlJSMetaMethod>>(v: m_content); }
103 uint importNamespace() const { return std::get<uint>(v: m_content); }
104
105 QQmlJSScope::ConstPtr conversionResult() const
106 {
107 return std::get<ConvertedTypes>(v: m_content).result;
108 }
109
110 QQmlJSScope::ConstPtr conversionResultScope() const
111 {
112 return std::get<ConvertedTypes>(v: m_content).resultScope;
113 }
114
115 QList<QQmlJSScope::ConstPtr> conversionOrigins() const
116 {
117 return std::get<ConvertedTypes>(v: m_content).origins;
118 }
119
120 ContentVariant variant() const { return m_variant; }
121
122 friend size_t qHash(const QQmlJSRegisterContent &registerContent, size_t seed = 0)
123 {
124 seed = qHashMulti(seed, args: registerContent.m_storedType, args: registerContent.m_content.index(),
125 args: registerContent.m_scope, args: registerContent.m_variant);
126 switch (registerContent.m_content.index()) {
127 case Type:
128 return qHash(ptr: std::get<QQmlJSScope::ConstPtr>(v: registerContent.m_content), seed);
129 case Property:
130 return qHash(prop: std::get<QQmlJSMetaProperty>(v: registerContent.m_content), seed);
131 case Enum:
132 return qHash(key: std::get<std::pair<QQmlJSMetaEnum, QString>>(v: registerContent.m_content),
133 seed);
134 case Method:
135 return qHash(key: std::get<QList<QQmlJSMetaMethod>>(v: registerContent.m_content), seed);
136 case ImportNamespace:
137 return qHash(key: std::get<uint>(v: registerContent.m_content), seed);
138 case Conversion:
139 return qHash(types: std::get<ConvertedTypes>(v: registerContent.m_content), seed);
140 }
141
142 Q_UNREACHABLE_RETURN(seed);
143 }
144
145 static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType,
146 const QQmlJSScope::ConstPtr &type, ContentVariant variant,
147 const QQmlJSScope::ConstPtr &scope = {});
148
149 static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType,
150 const QQmlJSMetaProperty &property, ContentVariant variant,
151 const QQmlJSScope::ConstPtr &scope);
152
153 static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType,
154 const QQmlJSMetaEnum &enumeration,
155 const QString &enumMember, ContentVariant variant,
156 const QQmlJSScope::ConstPtr &scope);
157
158 static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType,
159 const QList<QQmlJSMetaMethod> &methods,
160 ContentVariant variant,
161 const QQmlJSScope::ConstPtr &scope);
162
163 static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType,
164 uint importNamespaceStringId, ContentVariant variant,
165 const QQmlJSScope::ConstPtr &scope = {});
166
167 static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType,
168 const QList<QQmlJSScope::ConstPtr> origins,
169 const QQmlJSScope::ConstPtr &conversion,
170 const QQmlJSScope::ConstPtr &conversionScope,
171 ContentVariant variant,
172 const QQmlJSScope::ConstPtr &scope = {});
173
174 QQmlJSRegisterContent storedIn(const QQmlJSScope::ConstPtr &newStoredType) const
175 {
176 QQmlJSRegisterContent result = *this;
177 result.m_storedType = newStoredType;
178 return result;
179 }
180
181private:
182 enum ContentKind { Type, Property, Enum, Method, ImportNamespace, Conversion };
183
184 struct ConvertedTypes
185 {
186 QList<QQmlJSScope::ConstPtr> origins;
187 QQmlJSScope::ConstPtr result;
188 QQmlJSScope::ConstPtr resultScope;
189
190 friend size_t qHash(const ConvertedTypes &types, size_t seed = 0)
191 {
192 return qHashMulti(seed, args: types.origins, args: types.result, args: types.resultScope);
193 }
194
195 friend bool operator==(const ConvertedTypes &a, const ConvertedTypes &b)
196 {
197 return a.origins == b.origins && a.result == b.result && a.resultScope == b.resultScope;
198 }
199
200 friend bool operator!=(const ConvertedTypes &a, const ConvertedTypes &b)
201 {
202 return !(a == b);
203 }
204 };
205
206 using Content = std::variant<
207 QQmlJSScope::ConstPtr,
208 QQmlJSMetaProperty,
209 std::pair<QQmlJSMetaEnum, QString>,
210 QList<QQmlJSMetaMethod>,
211 uint,
212 ConvertedTypes
213 >;
214
215 QQmlJSRegisterContent(const QQmlJSScope::ConstPtr &storedType,
216 const QQmlJSScope::ConstPtr &scope, ContentVariant variant)
217 : m_storedType(storedType), m_scope(scope), m_variant(variant)
218 {
219 }
220
221 QQmlJSScope::ConstPtr m_storedType;
222 QQmlJSScope::ConstPtr m_scope;
223 Content m_content;
224 ContentVariant m_variant = Unknown;
225
226 // TODO: Constant string/number/bool/enumval
227};
228
229QT_END_NAMESPACE
230
231#endif // REGISTERCONTENT_H
232

source code of qtdeclarative/src/qmlcompiler/qqmljsregistercontent_p.h