1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQml module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QQMLPRIVATE_H
41#define QQMLPRIVATE_H
42
43//
44// W A R N I N G
45// -------------
46//
47// This file is not part of the Qt API. It exists purely as an
48// implementation detail. This header file may change from version to
49// version without notice, or even be removed.
50//
51// We mean it.
52//
53
54#include <functional>
55
56#include <QtQml/qtqmlglobal.h>
57
58#include <QtCore/qglobal.h>
59#include <QtCore/qvariant.h>
60#include <QtCore/qurl.h>
61
62QT_BEGIN_NAMESPACE
63
64namespace QQmlPrivate {
65struct CachedQmlUnit;
66}
67
68namespace QV4 {
69struct ExecutionEngine;
70namespace CompiledData {
71struct Unit;
72struct CompilationUnit;
73}
74}
75namespace QmlIR {
76struct Document;
77typedef void (*IRLoaderFunction)(Document *, const QQmlPrivate::CachedQmlUnit *);
78}
79
80typedef QObject *(*QQmlAttachedPropertiesFunc)(QObject *);
81
82inline uint qHash(QQmlAttachedPropertiesFunc func, uint seed = 0)
83{
84 return qHash(quintptr(func), seed);
85}
86
87template <typename TYPE>
88class QQmlTypeInfo
89{
90public:
91 enum {
92 hasAttachedProperties = 0
93 };
94};
95
96
97class QJSValue;
98class QJSEngine;
99class QQmlEngine;
100class QQmlCustomParser;
101namespace QQmlPrivate
102{
103 void Q_QML_EXPORT qdeclarativeelement_destructor(QObject *);
104 template<typename T>
105 class QQmlElement final : public T
106 {
107 public:
108 ~QQmlElement() override {
109 QQmlPrivate::qdeclarativeelement_destructor(this);
110 }
111 static void operator delete(void *ptr) {
112 // We allocate memory from this class in QQmlType::create
113 // along with some additional memory.
114 // So we override the operator delete in order to avoid the
115 // sized operator delete to be called with a different size than
116 // the size that was allocated.
117 ::operator delete (ptr);
118 }
119 static void operator delete(void *, void *) {
120 // Deliberately empty placement delete operator.
121 // Silences MSVC warning C4291: no matching operator delete found
122 }
123 };
124
125 template<typename T>
126 void createInto(void *memory) { new (memory) QQmlElement<T>; }
127
128 template<typename T>
129 QObject *createParent(QObject *p) { return new T(p); }
130
131 template<class From, class To, int N>
132 struct StaticCastSelectorClass
133 {
134 static inline int cast() { return -1; }
135 };
136
137 template<class From, class To>
138 struct StaticCastSelectorClass<From, To, sizeof(int)>
139 {
140 static inline int cast() { return int(reinterpret_cast<quintptr>(static_cast<To *>(reinterpret_cast<From *>(0x10000000)))) - 0x10000000; }
141 };
142
143 template<class From, class To>
144 struct StaticCastSelector
145 {
146 typedef int yes_type;
147 typedef char no_type;
148
149 static yes_type checkType(To *);
150 static no_type checkType(...);
151
152 static inline int cast()
153 {
154 return StaticCastSelectorClass<From, To, sizeof(checkType(reinterpret_cast<From *>(0)))>::cast();
155 }
156 };
157
158 template <typename T>
159 struct has_attachedPropertiesMember
160 {
161 static bool const value = QQmlTypeInfo<T>::hasAttachedProperties;
162 };
163
164 template <typename T, bool hasMember>
165 class has_attachedPropertiesMethod
166 {
167 public:
168 typedef int yes_type;
169 typedef char no_type;
170
171 template<typename ReturnType>
172 static yes_type checkType(ReturnType *(*)(QObject *));
173 static no_type checkType(...);
174
175 static bool const value = sizeof(checkType(&T::qmlAttachedProperties)) == sizeof(yes_type);
176 };
177
178 template <typename T>
179 class has_attachedPropertiesMethod<T, false>
180 {
181 public:
182 static bool const value = false;
183 };
184
185 template<typename T, int N>
186 class AttachedPropertySelector
187 {
188 public:
189 static inline QQmlAttachedPropertiesFunc func() { return nullptr; }
190 static inline const QMetaObject *metaObject() { return nullptr; }
191 };
192 template<typename T>
193 class AttachedPropertySelector<T, 1>
194 {
195 template<typename ReturnType>
196 static inline const QMetaObject *attachedPropertiesMetaObject(ReturnType *(*)(QObject *)) {
197 return &ReturnType::staticMetaObject;
198 }
199 public:
200 static inline QQmlAttachedPropertiesFunc func() {
201 return QQmlAttachedPropertiesFunc(&T::qmlAttachedProperties);
202 }
203 static inline const QMetaObject *metaObject() {
204 return attachedPropertiesMetaObject(&T::qmlAttachedProperties);
205 }
206 };
207
208 template<typename T>
209 inline QQmlAttachedPropertiesFunc attachedPropertiesFunc()
210 {
211 return AttachedPropertySelector<T, has_attachedPropertiesMethod<T, has_attachedPropertiesMember<T>::value>::value>::func();
212 }
213
214 template<typename T>
215 inline const QMetaObject *attachedPropertiesMetaObject()
216 {
217 return AttachedPropertySelector<T, has_attachedPropertiesMethod<T, has_attachedPropertiesMember<T>::value>::value>::metaObject();
218 }
219
220 enum AutoParentResult { Parented, IncompatibleObject, IncompatibleParent };
221 typedef AutoParentResult (*AutoParentFunction)(QObject *object, QObject *parent);
222
223 struct RegisterType {
224 int version;
225
226 int typeId;
227 int listId;
228 int objectSize;
229 void (*create)(void *);
230 QString noCreationReason;
231
232 const char *uri;
233 int versionMajor;
234 int versionMinor;
235 const char *elementName;
236 const QMetaObject *metaObject;
237
238 QQmlAttachedPropertiesFunc attachedPropertiesFunction;
239 const QMetaObject *attachedPropertiesMetaObject;
240
241 int parserStatusCast;
242 int valueSourceCast;
243 int valueInterceptorCast;
244
245 QObject *(*extensionObjectCreate)(QObject *);
246 const QMetaObject *extensionMetaObject;
247
248 QQmlCustomParser *customParser;
249 int revision;
250 // If this is extended ensure "version" is bumped!!!
251 };
252
253 struct RegisterInterface {
254 int version;
255
256 int typeId;
257 int listId;
258
259 const char *iid;
260 };
261
262 struct RegisterAutoParent {
263 int version;
264
265 AutoParentFunction function;
266 };
267
268 struct RegisterSingletonType {
269 int version;
270
271 const char *uri;
272 int versionMajor;
273 int versionMinor;
274 const char *typeName;
275
276 QJSValue (*scriptApi)(QQmlEngine *, QJSEngine *);
277 QObject *(*qobjectApi)(QQmlEngine *, QJSEngine *);
278 const QMetaObject *instanceMetaObject; // new in version 1
279 int typeId; // new in version 2
280 int revision; // new in version 2
281 std::function<QObject*(QQmlEngine *, QJSEngine *)> generalizedQobjectApi; // new in version 3
282 // If this is extended ensure "version" is bumped!!!
283 };
284
285 struct RegisterCompositeType {
286 QUrl url;
287 const char *uri;
288 int versionMajor;
289 int versionMinor;
290 const char *typeName;
291 };
292
293 struct RegisterCompositeSingletonType {
294 QUrl url;
295 const char *uri;
296 int versionMajor;
297 int versionMinor;
298 const char *typeName;
299 };
300
301 struct CachedQmlUnit {
302 const QV4::CompiledData::Unit *qmlData;
303 void *unused1;
304 void *unused2;
305 };
306
307 typedef const CachedQmlUnit *(*QmlUnitCacheLookupFunction)(const QUrl &url);
308 struct RegisterQmlUnitCacheHook {
309 int version;
310 QmlUnitCacheLookupFunction lookupCachedQmlUnit;
311 };
312
313 enum RegistrationType {
314 TypeRegistration = 0,
315 InterfaceRegistration = 1,
316 AutoParentRegistration = 2,
317 SingletonRegistration = 3,
318 CompositeRegistration = 4,
319 CompositeSingletonRegistration = 5,
320 QmlUnitCacheHookRegistration = 6
321 };
322
323 int Q_QML_EXPORT qmlregister(RegistrationType, void *);
324 void Q_QML_EXPORT qmlunregister(RegistrationType, quintptr);
325 struct Q_QML_EXPORT RegisterSingletonFunctor
326 {
327 QObject *operator()(QQmlEngine *, QJSEngine *);
328
329 QObject *m_object;
330 bool alreadyCalled = false;
331 };
332}
333
334QT_END_NAMESPACE
335
336#endif // QQMLPRIVATE_H
337