aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlmetatype_p.h
blob: f4870d9db118c9b33d32a76b7ca44c9634d413f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only

#ifndef QQMLMETATYPE_P_H
#define QQMLMETATYPE_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 <private/qqmldirparser_p.h>
#include <private/qqmlmetaobject_p.h>
#include <private/qqmlproxymetaobject_p.h>
#include <private/qqmltype_p.h>
#include <private/qtqmlglobal_p.h>

QT_BEGIN_NAMESPACE

class QQmlTypeModule;
class QRecursiveMutex;
class QQmlError;
class QQmlValueType;

namespace QV4 {
namespace CompiledData {
struct CompilationUnit;
}
}

class Q_QML_EXPORT QQmlMetaType
{
    friend class QQmlDesignerMetaObject;

public:

    enum class RegistrationResult {
        Success,
        Failure,
        NoRegistrationFunction
    };

    static QUrl inlineComponentUrl(const QUrl &baseUrl, const QString &name)
    {
        QUrl icUrl = baseUrl;
        icUrl.setFragment(name);
        return icUrl;
    }

    static bool equalBaseUrls(const QUrl &aUrl, const QUrl &bUrl)
    {
        // Everything but fragment has to match
        return aUrl.port() == bUrl.port()
                && aUrl.scheme() == bUrl.scheme()
                && aUrl.userName() == bUrl.userName()
                && aUrl.password() == bUrl.password()
                && aUrl.host() == bUrl.host()
                && aUrl.path() == bUrl.path()
                && aUrl.query() == bUrl.query();
    }

    enum CompositeTypeLookupMode {
        NonSingleton,
        Singleton,
    };

    static QQmlType findCompositeType(
            const QUrl &url,
            const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit,
            CompositeTypeLookupMode mode = NonSingleton);
    static QQmlType findInlineComponentType(
            const QUrl &url,
            const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit);
    static QQmlType findInlineComponentType(
            const QUrl &baseUrl, const QString &name,
            const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit)
    {
        return findInlineComponentType(inlineComponentUrl(baseUrl, name), compilationUnit);
    }

    static void unregisterInternalCompositeType(QMetaType metaType, QMetaType listMetaType);
    static QQmlType registerType(const QQmlPrivate::RegisterType &type);
    static QQmlType registerInterface(const QQmlPrivate::RegisterInterface &type);
    static QQmlType registerSingletonType(
            const QQmlPrivate::RegisterSingletonType &type,
            const QQmlType::SingletonInstanceInfo::ConstPtr &siinfo);
    static QQmlType registerCompositeSingletonType(
            const QQmlPrivate::RegisterCompositeSingletonType &type,
            const QQmlType::SingletonInstanceInfo::ConstPtr &siinfo);
    static QQmlType registerCompositeType(const QQmlPrivate::RegisterCompositeType &type);
    static RegistrationResult registerPluginTypes(QObject *instance, const QString &basePath,
                                                  const QString &uri, const QString &typeNamespace,
                                                  QTypeRevision version, QList<QQmlError> *errors);

    static QQmlType typeForUrl(const QString &urlString, const QHashedStringRef& typeName,
                               CompositeTypeLookupMode mode, QList<QQmlError> *errors,
                               QTypeRevision version = QTypeRevision());

    static QQmlType fetchOrCreateInlineComponentTypeForUrl(const QUrl &url);
    static QQmlType inlineComponentType(const QQmlType &outerType, const QString &name)
    {
        return outerType.isComposite()
                ? fetchOrCreateInlineComponentTypeForUrl(
                        inlineComponentUrl(outerType.sourceUrl(), name))
                : QQmlType();
    }

    static void unregisterType(int type);

    static void registerMetaObjectForType(const QMetaObject *metaobject, QQmlTypePrivate *type);

    static void registerModule(const char *uri, QTypeRevision version);
    static bool protectModule(const QString &uri, QTypeRevision version,
                              bool weakProtectAllVersions = false);

    static void registerModuleImport(const QString &uri, QTypeRevision version,
                                     const QQmlDirParser::Import &import);
    static void unregisterModuleImport(const QString &uri, QTypeRevision version,
                                       const QQmlDirParser::Import &import);
    static QList<QQmlDirParser::Import> moduleImports(const QString &uri, QTypeRevision version);

    static int typeId(const char *uri, QTypeRevision version, const char *qmlName);

    static void registerUndeletableType(const QQmlType &dtype);

    static QList<QString> qmlTypeNames();
    static QList<QQmlType> qmlTypes();
    static QList<QQmlType> qmlSingletonTypes();
    static QList<QQmlType> qmlAllTypes();

    static QQmlType qmlType(const QString &qualifiedName, QTypeRevision version);
    static QQmlType qmlType(const QHashedStringRef &name, const QHashedStringRef &module, QTypeRevision version);
    static QQmlType qmlType(const QMetaObject *);
    static QQmlType qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, QTypeRevision version);
    static QQmlType qmlTypeById(int qmlTypeId);

    static QQmlType qmlType(QMetaType metaType);
    static QQmlType qmlListType(QMetaType metaType);

    static QQmlType qmlType(const QUrl &unNormalizedUrl, bool includeNonFileImports = false);

    static QQmlPropertyCache::ConstPtr propertyCache(
            QObject *object, QTypeRevision version = QTypeRevision());
    static QQmlPropertyCache::ConstPtr propertyCache(
            const QMetaObject *metaObject, QTypeRevision version = QTypeRevision());
    static QQmlPropertyCache::ConstPtr propertyCache(
            const QQmlType &type, QTypeRevision version);

    // These methods may be called from the loader thread
    static QQmlMetaObject rawMetaObjectForType(QMetaType metaType);
    static QQmlMetaObject metaObjectForType(QMetaType metaType);
    static QQmlPropertyCache::ConstPtr propertyCacheForType(QMetaType metaType);
    static QQmlPropertyCache::ConstPtr rawPropertyCacheForType(QMetaType metaType);
    static QQmlPropertyCache::ConstPtr rawPropertyCacheForType(
            QMetaType metaType, QTypeRevision version);

    static void freeUnusedTypesAndCaches();

    static QMetaProperty defaultProperty(const QMetaObject *);
    static QMetaProperty defaultProperty(QObject *);
    static QMetaMethod defaultMethod(const QMetaObject *);
    static QMetaMethod defaultMethod(QObject *);

    static QObject *toQObject(const QVariant &, bool *ok = nullptr);

    static QMetaType listValueType(QMetaType type);
    static QQmlAttachedPropertiesFunc attachedPropertiesFunc(QQmlEnginePrivate *,
                                                             const QMetaObject *);
    static bool isInterface(QMetaType type);
    static const char *interfaceIId(QMetaType type);
    static bool isList(QMetaType type);

    static QTypeRevision latestModuleVersion(const QString &uri);
    static bool isStronglyLockedModule(const QString &uri, QTypeRevision version);
    static QTypeRevision matchingModuleVersion(const QString &module, QTypeRevision version);
    static QQmlTypeModule *typeModule(const QString &uri, QTypeRevision version);

    static QList<QQmlPrivate::AutoParentFunction> parentFunctions();

    enum class CachedUnitLookupError {
        NoError,
        NoUnitFound,
        VersionMismatch,
        NotFullyTyped
    };

    enum CacheMode { RejectAll, AcceptUntyped, RequireFullyTyped };
    static const QQmlPrivate::CachedQmlUnit *findCachedCompilationUnit(
            const QUrl &uri, CacheMode mode, CachedUnitLookupError *status);

    // used by tst_qqmlcachegen.cpp
    static void prependCachedUnitLookupFunction(QQmlPrivate::QmlUnitCacheLookupFunction handler);
    static void removeCachedUnitLookupFunction(QQmlPrivate::QmlUnitCacheLookupFunction handler);

    static QString prettyTypeName(const QObject *object);

    template <typename QQmlTypeContainer>
    static void removeQQmlTypePrivate(QQmlTypeContainer &container,
                                      const QQmlTypePrivate *reference)
    {
        for (typename QQmlTypeContainer::iterator it = container.begin(); it != container.end();) {
            if (*it == reference)
                it = container.erase(it);
            else
                ++it;
        }
    }

    template <typename InlineComponentContainer>
    static void removeFromInlineComponents(
        InlineComponentContainer &container, const QQmlTypePrivate *reference)
    {
        const QUrl referenceUrl = QQmlType(reference).sourceUrl();
        for (auto it = container.begin(), end = container.end(); it != end;) {
            if (equalBaseUrls(it.key(), referenceUrl))
                it = container.erase(it);
            else
                ++it;
        }
    }

    static void registerTypeAlias(int typeId, const QString &name);

    static int registerAutoParentFunction(const QQmlPrivate::RegisterAutoParent &autoparent);
    static void unregisterAutoParentFunction(const QQmlPrivate::AutoParentFunction &function);

    static QQmlType registerSequentialContainer(
            const QQmlPrivate::RegisterSequentialContainer &sequenceRegistration);
    static void unregisterSequentialContainer(int id);

    static int registerUnitCacheHook(const QQmlPrivate::RegisterQmlUnitCacheHook &hookRegistration);
    static void clearTypeRegistrations();

    static QList<QQmlProxyMetaObject::ProxyData> proxyData(const QMetaObject *mo,
                                                           const QMetaObject *baseMetaObject,
                                                           QMetaObject *lastMetaObject);

    enum ClonePolicy {
        CloneAll, // default
        CloneEnumsOnly, // skip properties and methods
    };
    static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo,
                      const QMetaObject *ignoreStart, const QMetaObject *ignoreEnd,
                      ClonePolicy policy);

    static void qmlInsertModuleRegistration(const QString &uri, void (*registerFunction)());
    static void qmlRemoveModuleRegistration(const QString &uri);

    static bool qmlRegisterModuleTypes(const QString &uri);

    static bool isValueType(QMetaType type);
    static QQmlValueType *valueType(QMetaType metaType);
    static const QMetaObject *metaObjectForValueType(QMetaType type);

    static QQmlPropertyCache::ConstPtr findPropertyCacheInCompositeTypes(QMetaType t);
    static void registerInternalCompositeType(
            const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit);
    static void unregisterInternalCompositeType(
            const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit);
    static int countInternalCompositeTypeSelfReferences(
            const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit);
    static QQmlRefPointer<QV4::CompiledData::CompilationUnit> obtainCompilationUnit(
            QMetaType type);
    static QQmlRefPointer<QV4::CompiledData::CompilationUnit> obtainCompilationUnit(
            const QUrl &url);
};

Q_DECLARE_TYPEINFO(QQmlMetaType, Q_RELOCATABLE_TYPE);

// used in QQmlListMetaType to tag the metatpye
inline const QMetaObject *dynamicQmlListMarker(const QtPrivate::QMetaTypeInterface *) {
    return nullptr;
};

inline const QMetaObject *dynamicQmlMetaObject(const QtPrivate::QMetaTypeInterface *iface) {
    return QQmlMetaType::metaObjectForType(QMetaType(iface)).metaObject();
};

// metatype interface for composite QML types
struct QQmlMetaTypeInterface : QtPrivate::QMetaTypeInterface
{
    const QByteArray name;
    QQmlMetaTypeInterface(const QByteArray &name)
        : QMetaTypeInterface {
            /*.revision=*/ QMetaTypeInterface::CurrentRevision,
            /*.alignment=*/ alignof(QObject *),
            /*.size=*/ sizeof(QObject *),
            /*.flags=*/ QtPrivate::QMetaTypeTypeFlags<QObject *>::Flags,
            /*.typeId=*/ 0,
            /*.metaObjectFn=*/ &dynamicQmlMetaObject,
            /*.name=*/ name.constData(),
            /*.defaultCtr=*/ [](const QMetaTypeInterface *, void *addr) {
                *static_cast<QObject **>(addr) = nullptr;
            },
            /*.copyCtr=*/ [](const QMetaTypeInterface *, void *addr, const void *other) {
                *static_cast<QObject **>(addr) = *static_cast<QObject *const *>(other);
            },
            /*.moveCtr=*/ [](const QMetaTypeInterface *, void *addr, void *other) {
                *static_cast<QObject **>(addr) = *static_cast<QObject **>(other);
            },
            /*.dtor=*/ [](const QMetaTypeInterface *, void *) {},
            /*.equals*/ nullptr,
            /*.lessThan*/ nullptr,
            /*.debugStream=*/ nullptr,
            /*.dataStreamOut=*/ nullptr,
            /*.dataStreamIn=*/ nullptr,
            /*.legacyRegisterOp=*/ nullptr
        }
        , name(name) { }
};

// metatype for qml list types
struct QQmlListMetaTypeInterface : QtPrivate::QMetaTypeInterface
{
    const QByteArray name;
    // if this interface is for list<type>; valueType stores the interface for type
    const QtPrivate::QMetaTypeInterface *valueType;
    QQmlListMetaTypeInterface(const QByteArray &name, const QtPrivate::QMetaTypeInterface *valueType)
        : QMetaTypeInterface {
            /*.revision=*/ QMetaTypeInterface::CurrentRevision,
            /*.alignment=*/ alignof(QQmlListProperty<QObject>),
            /*.size=*/ sizeof(QQmlListProperty<QObject>),
            /*.flags=*/ QtPrivate::QMetaTypeTypeFlags<QQmlListProperty<QObject>>::Flags,
            /*.typeId=*/ 0,
            /*.metaObjectFn=*/ &dynamicQmlListMarker,
            /*.name=*/ name.constData(),
            /*.defaultCtr=*/ [](const QMetaTypeInterface *, void *addr) {
                new (addr) QQmlListProperty<QObject> ();
            },
            /*.copyCtr=*/ [](const QMetaTypeInterface *, void *addr, const void *other) {
                new (addr) QQmlListProperty<QObject>(
                        *static_cast<const QQmlListProperty<QObject> *>(other));
            },
            /*.moveCtr=*/ [](const QMetaTypeInterface *, void *addr, void *other) {
                new (addr) QQmlListProperty<QObject>(
                        std::move(*static_cast<QQmlListProperty<QObject> *>(other)));
            },
            /*.dtor=*/ [](const QMetaTypeInterface *, void *addr) {
                static_cast<QQmlListProperty<QObject> *>(addr)->~QQmlListProperty<QObject>();
            },
            /*.equals*/ nullptr,
            /*.lessThan*/ nullptr,
            /*.debugStream=*/ nullptr,
            /*.dataStreamOut=*/ nullptr,
            /*.dataStreamIn=*/ nullptr,
            /*.legacyRegisterOp=*/ nullptr
        }
        , name(name), valueType(valueType) { }
};

QT_END_NAMESPACE

#endif // QQMLMETATYPE_P_H