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 | |
23 | QT_BEGIN_NAMESPACE |
24 | |
25 | class Q_QMLCOMPILER_PRIVATE_EXPORT QQmlJSRegisterContent |
26 | { |
27 | public: |
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 ®isterContent, 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 | |
181 | private: |
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 | |
229 | QT_END_NAMESPACE |
230 | |
231 | #endif // REGISTERCONTENT_H |
232 | |