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_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 ListIterator,
60 Builtin,
61 Unknown,
62 };
63
64 enum { InvalidLookupIndex = -1 };
65
66 QQmlJSRegisterContent() = default;
67 bool isValid() const { return !m_storedType.isNull(); }
68
69 QString descriptiveName() const;
70
71 friend bool operator==(const QQmlJSRegisterContent &a, const QQmlJSRegisterContent &b)
72 {
73 return a.m_storedType == b.m_storedType && a.m_variant == b.m_variant
74 && a.m_scope == b.m_scope && a.m_content == b.m_content;
75 }
76
77 friend bool operator!=(const QQmlJSRegisterContent &a, const QQmlJSRegisterContent &b)
78 {
79 return !(a == b);
80 }
81
82 bool isType() const { return m_content.index() == Type; }
83 bool isProperty() const { return m_content.index() == Property; }
84 bool isEnumeration() const { return m_content.index() == Enum; }
85 bool isMethod() const { return m_content.index() == Method; }
86 bool isImportNamespace() const { return m_content.index() == ImportNamespace; }
87 bool isConversion() const { return m_content.index() == Conversion; }
88 bool isList() const;
89
90 bool isWritable() const;
91
92 QQmlJSScope::ConstPtr storedType() const { return m_storedType; }
93 QQmlJSScope::ConstPtr scopeType() const { return m_scope; }
94
95 QQmlJSScope::ConstPtr type() const
96 {
97 return std::get<std::pair<QQmlJSScope::ConstPtr, int>>(v: m_content).first;
98 }
99 QQmlJSMetaProperty property() const
100 {
101 return std::get<PropertyLookup>(v: m_content).property;
102 }
103 int baseLookupIndex() const
104 {
105 return std::get<PropertyLookup>(v: m_content).baseLookupIndex;
106 }
107 int resultLookupIndex() const
108 {
109 switch (m_content.index()) {
110 case Type:
111 return std::get<std::pair<QQmlJSScope::ConstPtr, int>>(v: m_content).second;
112 case Property:
113 return std::get<PropertyLookup>(v: m_content).resultLookupIndex;
114 default:
115 return InvalidLookupIndex;
116 }
117 }
118 QQmlJSMetaEnum enumeration() const
119 {
120 return std::get<std::pair<QQmlJSMetaEnum, QString>>(v: m_content).first;
121 }
122 QString enumMember() const
123 {
124 return std::get<std::pair<QQmlJSMetaEnum, QString>>(v: m_content).second;
125 }
126 QList<QQmlJSMetaMethod> method() const { return std::get<QList<QQmlJSMetaMethod>>(v: m_content); }
127 uint importNamespace() const { return std::get<uint>(v: m_content); }
128
129 QQmlJSScope::ConstPtr conversionResult() const
130 {
131 return std::get<ConvertedTypes>(v: m_content).result;
132 }
133
134 QQmlJSScope::ConstPtr conversionResultScope() const
135 {
136 return std::get<ConvertedTypes>(v: m_content).resultScope;
137 }
138
139 QList<QQmlJSScope::ConstPtr> conversionOrigins() const
140 {
141 return std::get<ConvertedTypes>(v: m_content).origins;
142 }
143
144 ContentVariant variant() const { return m_variant; }
145
146 friend size_t qHash(const QQmlJSRegisterContent &registerContent, size_t seed = 0)
147 {
148 seed = qHashMulti(seed, args: registerContent.m_storedType, args: registerContent.m_content.index(),
149 args: registerContent.m_scope, args: registerContent.m_variant);
150 switch (registerContent.m_content.index()) {
151 case Type:
152 return qHash(key: std::get<std::pair<QQmlJSScope::ConstPtr, int>>(v: registerContent.m_content),
153 seed);
154 case Property:
155 return qHash(property: std::get<PropertyLookup>(v: registerContent.m_content), seed);
156 case Enum:
157 return qHash(key: std::get<std::pair<QQmlJSMetaEnum, QString>>(v: registerContent.m_content),
158 seed);
159 case Method:
160 return qHash(key: std::get<QList<QQmlJSMetaMethod>>(v: registerContent.m_content), seed);
161 case ImportNamespace:
162 return qHash(key: std::get<uint>(v: registerContent.m_content), seed);
163 case Conversion:
164 return qHash(types: std::get<ConvertedTypes>(v: registerContent.m_content), seed);
165 }
166
167 Q_UNREACHABLE_RETURN(seed);
168 }
169
170 static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType,
171 const QQmlJSScope::ConstPtr &type,
172 int resultLookupIndex, ContentVariant variant,
173 const QQmlJSScope::ConstPtr &scope = {});
174
175 static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType,
176 const QQmlJSMetaProperty &property,
177 int baseLookupIndex, int resultLookupIndex,
178 ContentVariant variant,
179 const QQmlJSScope::ConstPtr &scope);
180
181 static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType,
182 const QQmlJSMetaEnum &enumeration,
183 const QString &enumMember, ContentVariant variant,
184 const QQmlJSScope::ConstPtr &scope);
185
186 static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType,
187 const QList<QQmlJSMetaMethod> &methods,
188 ContentVariant variant,
189 const QQmlJSScope::ConstPtr &scope);
190
191 static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType,
192 uint importNamespaceStringId, ContentVariant variant,
193 const QQmlJSScope::ConstPtr &scope = {});
194
195 static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType,
196 const QList<QQmlJSScope::ConstPtr> &origins,
197 const QQmlJSScope::ConstPtr &conversion,
198 const QQmlJSScope::ConstPtr &conversionScope,
199 ContentVariant variant,
200 const QQmlJSScope::ConstPtr &scope = {});
201
202 QQmlJSRegisterContent storedIn(const QQmlJSScope::ConstPtr &newStoredType) const
203 {
204 QQmlJSRegisterContent result = *this;
205 result.m_storedType = newStoredType;
206 return result;
207 }
208
209 QQmlJSRegisterContent castTo(const QQmlJSScope::ConstPtr &newContainedType) const
210 {
211 // This is not a conversion but a run time cast. It may result in null or undefined.
212 QQmlJSRegisterContent result = *this;
213 result.m_content = std::make_pair(x: newContainedType, y: result.resultLookupIndex());
214 return result;
215 }
216
217private:
218 enum ContentKind { Type, Property, Enum, Method, ImportNamespace, Conversion };
219
220 struct ConvertedTypes
221 {
222 QList<QQmlJSScope::ConstPtr> origins;
223 QQmlJSScope::ConstPtr result;
224 QQmlJSScope::ConstPtr resultScope;
225
226 friend size_t qHash(const ConvertedTypes &types, size_t seed = 0)
227 {
228 return qHashMulti(seed, args: types.origins, args: types.result, args: types.resultScope);
229 }
230
231 friend bool operator==(const ConvertedTypes &a, const ConvertedTypes &b)
232 {
233 return a.origins == b.origins && a.result == b.result && a.resultScope == b.resultScope;
234 }
235
236 friend bool operator!=(const ConvertedTypes &a, const ConvertedTypes &b)
237 {
238 return !(a == b);
239 }
240 };
241
242 struct PropertyLookup
243 {
244 QQmlJSMetaProperty property;
245 int baseLookupIndex = InvalidLookupIndex;
246 int resultLookupIndex = InvalidLookupIndex;
247
248 friend size_t qHash(const PropertyLookup &property, size_t seed = 0)
249 {
250 return qHashMulti(
251 seed, args: property.property, args: property.baseLookupIndex, args: property.resultLookupIndex);
252 }
253
254 friend bool operator==(const PropertyLookup &a, const PropertyLookup &b)
255 {
256 return a.baseLookupIndex == b.baseLookupIndex
257 && a.resultLookupIndex == b.resultLookupIndex
258 && a.property == b.property;
259 }
260
261 friend bool operator!=(const PropertyLookup &a, const PropertyLookup &b)
262 {
263 return !(a == b);
264 }
265 };
266
267 using Content = std::variant<
268 std::pair<QQmlJSScope::ConstPtr, int>,
269 PropertyLookup,
270 std::pair<QQmlJSMetaEnum, QString>,
271 QList<QQmlJSMetaMethod>,
272 uint,
273 ConvertedTypes
274 >;
275
276 QQmlJSRegisterContent(const QQmlJSScope::ConstPtr &storedType,
277 const QQmlJSScope::ConstPtr &scope, ContentVariant variant)
278 : m_storedType(storedType), m_scope(scope), m_variant(variant)
279 {
280 }
281
282 QQmlJSScope::ConstPtr m_storedType;
283 QQmlJSScope::ConstPtr m_scope;
284 Content m_content;
285 ContentVariant m_variant = Unknown;
286
287 // TODO: Constant string/number/bool/enumval
288};
289
290QT_END_NAMESPACE
291
292#endif // REGISTERCONTENT_H
293

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

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