diff options
Diffstat (limited to 'src/qml/qml/qqmlprivate.h')
-rw-r--r-- | src/qml/qml/qqmlprivate.h | 475 |
1 files changed, 353 insertions, 122 deletions
diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h index fb2d80b3df..92c9765509 100644 --- a/src/qml/qml/qqmlprivate.h +++ b/src/qml/qml/qqmlprivate.h @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// 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 QQMLPRIVATE_H #define QQMLPRIVATE_H @@ -51,29 +15,32 @@ // We mean it. // -#include <functional> -#include <type_traits> - -#include <QtQml/qtqmlglobal.h> -#include <QtQml/qqmlparserstatus.h> +#include <QtQml/qjsprimitivevalue.h> +#include <QtQml/qjsvalue.h> #include <QtQml/qqmllist.h> +#include <QtQml/qqmlparserstatus.h> #include <QtQml/qqmlpropertyvaluesource.h> -#include <QtQml/qjsvalue.h> +#include <QtQml/qtqmlglobal.h> +#include <QtCore/qdatetime.h> +#include <QtCore/qdebug.h> #include <QtCore/qglobal.h> -#include <QtCore/qvariant.h> -#include <QtCore/qurl.h> +#include <QtCore/qmetacontainer.h> +#include <QtCore/qmetaobject.h> #include <QtCore/qpointer.h> +#include <QtCore/qurl.h> +#include <QtCore/qvariant.h> #include <QtCore/qversionnumber.h> -#include <QtCore/qmetaobject.h> -#include <QtCore/qmetacontainer.h> -#include <QtCore/qdebug.h> +#include <functional> +#include <limits> +#include <type_traits> QT_BEGIN_NAMESPACE class QQmlPropertyValueInterceptor; -class QQmlContext; +class QQmlContextData; +class QQmlFinalizerHook; namespace QQmlPrivate { struct CachedQmlUnit; @@ -83,9 +50,9 @@ using QQmlAttachedPropertiesFunc = A *(*)(QObject *); namespace QV4 { struct ExecutionEngine; +class ExecutableCompilationUnit; namespace CompiledData { struct Unit; -struct CompilationUnit; } } namespace QmlIR { @@ -115,6 +82,10 @@ class QQmlEngine; class QQmlCustomParser; class QQmlTypeNotAvailable; +class QQmlV4Function; +using QQmlV4FunctionPtr = QQmlV4Function *; +using QQmlV4ExecutionEnginePtr = QV4::ExecutionEngine *; + template<class T> QQmlCustomParser *qmlCreateCustomParser() { @@ -139,13 +110,16 @@ namespace QQmlPrivate // the size that was allocated. ::operator delete (ptr); } +#ifdef Q_CC_MSVC static void operator delete(void *, void *) { // Deliberately empty placement delete operator. // Silences MSVC warning C4291: no matching operator delete found + // On MinGW it causes -Wmismatched-new-delete, though. } +#endif }; - enum class ConstructionMode + enum class SingletonConstructionMode { None, Constructor, @@ -170,33 +144,45 @@ namespace QQmlPrivate }; template<typename T, typename WrapperT> - constexpr ConstructionMode constructionMode() + constexpr SingletonConstructionMode singletonConstructionMode() { if constexpr (!std::is_base_of<QObject, T>::value) - return ConstructionMode::None; + return SingletonConstructionMode::None; if constexpr (!std::is_same_v<T, WrapperT> && HasSingletonFactory<T, WrapperT>::value) - return ConstructionMode::FactoryWrapper; + return SingletonConstructionMode::FactoryWrapper; if constexpr (std::is_default_constructible<T>::value) - return ConstructionMode::Constructor; + return SingletonConstructionMode::Constructor; if constexpr (HasSingletonFactory<T>::value) - return ConstructionMode::Factory; + return SingletonConstructionMode::Factory; - return ConstructionMode::None; + return SingletonConstructionMode::None; } + template<typename> + struct QmlMarkerFunction; + + template<typename Ret, typename Class> + struct QmlMarkerFunction<Ret (Class::*)()> + { + using ClassType = Class; + }; + + template<typename T, typename Marker> + using QmlTypeHasMarker = std::is_same<T, typename QmlMarkerFunction<Marker>::ClassType>; + template<typename T> void createInto(void *memory, void *) { new (memory) QQmlElement<T>; } - template<typename T, typename WrapperT, ConstructionMode Mode> + template<typename T, typename WrapperT, SingletonConstructionMode Mode> QObject *createSingletonInstance(QQmlEngine *q, QJSEngine *j) { Q_UNUSED(q); Q_UNUSED(j); - if constexpr (Mode == ConstructionMode::Constructor) + if constexpr (Mode == SingletonConstructionMode::Constructor) return new T; - else if constexpr (Mode == ConstructionMode::Factory) + else if constexpr (Mode == SingletonConstructionMode::Factory) return T::create(q, j); - else if constexpr (Mode == ConstructionMode::FactoryWrapper) + else if constexpr (Mode == SingletonConstructionMode::FactoryWrapper) return WrapperT::create(q, j); else return nullptr; @@ -210,39 +196,43 @@ namespace QQmlPrivate using CreateParentFunction = QObject *(*)(QObject *); using CreateValueTypeFunction = QVariant (*)(const QJSValue &); - template<typename T, typename WrapperT = T, ConstructionMode Mode = constructionMode<T, WrapperT>()> + template<typename T, typename WrapperT = T, + SingletonConstructionMode Mode = singletonConstructionMode<T, WrapperT>()> struct Constructors; template<typename T, typename WrapperT> - struct Constructors<T, WrapperT, ConstructionMode::Constructor> + struct Constructors<T, WrapperT, SingletonConstructionMode::Constructor> { static constexpr CreateIntoFunction createInto = QQmlPrivate::createInto<T>; static constexpr CreateSingletonFunction createSingletonInstance - = QQmlPrivate::createSingletonInstance<T, WrapperT, ConstructionMode::Constructor>; + = QQmlPrivate::createSingletonInstance< + T, WrapperT, SingletonConstructionMode::Constructor>; }; template<typename T, typename WrapperT> - struct Constructors<T, WrapperT, ConstructionMode::None> + struct Constructors<T, WrapperT, SingletonConstructionMode::None> { static constexpr CreateIntoFunction createInto = nullptr; static constexpr CreateSingletonFunction createSingletonInstance = nullptr; }; template<typename T, typename WrapperT> - struct Constructors<T, WrapperT, ConstructionMode::Factory> + struct Constructors<T, WrapperT, SingletonConstructionMode::Factory> { static constexpr CreateIntoFunction createInto = nullptr; static constexpr CreateSingletonFunction createSingletonInstance - = QQmlPrivate::createSingletonInstance<T, WrapperT, ConstructionMode::Factory>; + = QQmlPrivate::createSingletonInstance< + T, WrapperT, SingletonConstructionMode::Factory>; }; template<typename T, typename WrapperT> - struct Constructors<T, WrapperT, ConstructionMode::FactoryWrapper> + struct Constructors<T, WrapperT, SingletonConstructionMode::FactoryWrapper> { static constexpr CreateIntoFunction createInto = nullptr; static constexpr CreateSingletonFunction createSingletonInstance - = QQmlPrivate::createSingletonInstance<T, WrapperT, ConstructionMode::FactoryWrapper>; + = QQmlPrivate::createSingletonInstance< + T, WrapperT, SingletonConstructionMode::FactoryWrapper>; }; template<typename T, @@ -380,11 +370,13 @@ namespace QQmlPrivate struct Properties<Parent, void> { using Func = QQmlAttachedPropertiesFunc<QObject>; - static const QMetaObject *staticMetaObject() { return nullptr; }; - static Func attachedPropertiesFunc() { return nullptr; }; + static const QMetaObject *staticMetaObject() { return nullptr; } + static Func attachedPropertiesFunc() { return nullptr; } }; - using Type = typename OverridableAttachedType<T, typename T::QmlAttachedType>::Type; + using Type = typename std::conditional< + QmlTypeHasMarker<T, decltype(&T::qt_qmlMarker_attached)>::value, + typename OverridableAttachedType<T, typename T::QmlAttachedType>::Type, void>::type; using Func = typename Properties<T, Type>::Func; static const QMetaObject *staticMetaObject() @@ -444,7 +436,18 @@ namespace QQmlPrivate enum AutoParentResult { Parented, IncompatibleObject, IncompatibleParent }; typedef AutoParentResult (*AutoParentFunction)(QObject *object, QObject *parent); + enum class ValueTypeCreationMethod { None, Construct, Structured }; + struct RegisterType { + enum StructVersion: int { + Base = 0, + FinalizerCast = 1, + CreationMethod = 2, + CurrentVersion = CreationMethod, + }; + + bool has(StructVersion v) const { return structVersion >= int(v); } + int structVersion; QMetaType typeId; @@ -455,6 +458,7 @@ namespace QQmlPrivate void *userdata; QString noCreationReason; + // ### Qt7: Get rid of this. It can be covered by creationMethod below. QVariant (*createValueType)(const QJSValue &); const char *uri; @@ -475,6 +479,9 @@ namespace QQmlPrivate QQmlCustomParser *customParser; QTypeRevision revision; + int finalizerCast; + + ValueTypeCreationMethod creationMethod; // If this is extended ensure "version" is bumped!!! }; @@ -507,6 +514,10 @@ namespace QQmlPrivate QQmlCustomParser *(*customParserFactory)(); QVector<int> *qmlTypeIds; + int finalizerCast; + + bool forceAnonymous; + QMetaSequence listMetaSequence; }; struct RegisterInterface { @@ -584,7 +595,11 @@ namespace QQmlPrivate int structVersion; const char *uri; QTypeRevision version; + + // ### Qt7: Remove typeName. It's ignored because the only valid name is "list", + // and that's automatic. const char *typeName; + QMetaType typeId; QMetaSequence metaSequence; QTypeRevision revision; @@ -603,22 +618,139 @@ namespace QQmlPrivate }; struct Q_QML_EXPORT AOTCompiledContext { - QQmlContext *qmlContext; + enum: uint { InvalidStringId = (std::numeric_limits<uint>::max)() }; + + QQmlContextData *qmlContext; QObject *qmlScopeObject; QJSEngine *engine; - QV4::CompiledData::CompilationUnit *compilationUnit; + union { + QV4::ExecutableCompilationUnit *compilationUnit; + qintptr extraData; + }; + + QObject *thisObject() const; + QQmlEngine *qmlEngine() const; QJSValue jsMetaType(int index) const; void setInstructionPointer(int offset) const; + void setReturnValueUndefined() const; + + // Run QQmlPropertyCapture::captureProperty() without retrieving the value. + bool captureLookup(uint index, QObject *object) const; + bool captureQmlContextPropertyLookup(uint index) const; + void captureTranslation() const; + QString translationContext() const; + QMetaType lookupResultMetaType(uint index) const; + void storeNameSloppy(uint nameIndex, void *value, QMetaType type) const; + QJSValue javaScriptGlobalProperty(uint nameIndex) const; + + const QLoggingCategory *resolveLoggingCategory(QObject *wrapper, bool *ok) const; + + void writeToConsole( + QtMsgType type, const QString &message, + const QLoggingCategory *loggingCategory) const; + + QVariant constructValueType( + QMetaType resultMetaType, const QMetaObject *resultMetaObject, + int ctorIndex, void *ctorArg) const; + + // Those are explicit arguments to the Date() ctor, not implicit coercions. + QDateTime constructDateTime(double timestamp) const; + QDateTime constructDateTime(const QString &string) const; + QDateTime constructDateTime(const QJSPrimitiveValue &arg) const + { + return arg.type() == QJSPrimitiveValue::String + ? constructDateTime(arg.toString()) + : constructDateTime(arg.toDouble()); + } + + QDateTime constructDateTime( + double year, double month, double day = 1, + double hours = 0, double minutes = 0, double seconds = 0, double msecs = 0) const; + + // All of these lookup functions should be used as follows: + // + // while (!fooBarLookup(...)) { + // setInstructionPointer(...); + // initFooBarLookup(...); + // if (engine->hasException()) { + // ... + // break; + // } + // } + // + // The bool-returning *Lookup functions exclusively run the happy path and return false if + // that fails in any way. The failure may either be in the lookup structs not being + // initialized or an exception being thrown. + // The init*Lookup functions initialize the lookup structs and amend any exceptions + // previously thrown with line numbers. They might also throw their own exceptions. If an + // exception is present after the initialization there is no way to carry out the lookup and + // the exception should be propagated. If not, the original lookup can be tried again. + + bool callQmlContextPropertyLookup( + uint index, void **args, const QMetaType *types, int argc) const; + void initCallQmlContextPropertyLookup(uint index) const; + + bool loadContextIdLookup(uint index, void *target) const; + void initLoadContextIdLookup(uint index) const; + + bool callObjectPropertyLookup(uint index, QObject *object, + void **args, const QMetaType *types, int argc) const; + void initCallObjectPropertyLookup(uint index) const; + + bool callGlobalLookup(uint index, void **args, const QMetaType *types, int argc) const; + void initCallGlobalLookup(uint index) const; + + bool loadGlobalLookup(uint index, void *target, QMetaType type) const; + void initLoadGlobalLookup(uint index) const; + + bool loadScopeObjectPropertyLookup(uint index, void *target) const; + bool writeBackScopeObjectPropertyLookup(uint index, void *source) const; + void initLoadScopeObjectPropertyLookup(uint index, QMetaType type) const; + + bool loadSingletonLookup(uint index, void *target) const; + void initLoadSingletonLookup(uint index, uint importNamespace) const; + + bool loadAttachedLookup(uint index, QObject *object, void *target) const; + void initLoadAttachedLookup(uint index, uint importNamespace, QObject *object) const; + + bool loadTypeLookup(uint index, void *target) const; + void initLoadTypeLookup(uint index, uint importNamespace) const; + + bool getObjectLookup(uint index, QObject *object, void *target) const; + bool writeBackObjectLookup(uint index, QObject *object, void *source) const; + void initGetObjectLookup(uint index, QObject *object, QMetaType type) const; + + bool getValueLookup(uint index, void *value, void *target) const; + bool writeBackValueLookup(uint index, void *value, void *source) const; + void initGetValueLookup(uint index, const QMetaObject *metaObject, QMetaType type) const; + + bool getEnumLookup(uint index, void *target) const; +#if QT_QML_REMOVED_SINCE(6, 6) + bool getEnumLookup(uint index, int *target) const; +#endif + void initGetEnumLookup(uint index, const QMetaObject *metaObject, + const char *enumerator, const char *enumValue) const; + + bool setObjectLookup(uint index, QObject *object, void *value) const; + void initSetObjectLookup(uint index, QObject *object, QMetaType type) const; + + bool setValueLookup(uint index, void *target, void *value) const; + void initSetValueLookup(uint index, const QMetaObject *metaObject, QMetaType type) const; }; struct AOTCompiledFunction { - int index; - QMetaType returnType; - QList<QMetaType> argumentTypes; - void (*functionPtr)(const AOTCompiledContext *context, void *resultPtr, void **arguments); + int functionIndex; + int numArguments; + void (*signature)(QV4::ExecutableCompilationUnit *unit, QMetaType *argTypes); + void (*functionPtr)(const AOTCompiledContext *context, void **argv); }; +#if QT_DEPRECATED_SINCE(6, 6) + QT_DEPRECATED_VERSION_X(6, 6, "Use AOTCompiledFunction instead") + typedef AOTCompiledFunction TypedFunction; +#endif + struct CachedQmlUnit { const QV4::CompiledData::Unit *qmlData; const AOTCompiledFunction *aotCompiledFunctions; @@ -647,21 +779,38 @@ namespace QQmlPrivate int Q_QML_EXPORT qmlregister(RegistrationType, void *); void Q_QML_EXPORT qmlunregister(RegistrationType, quintptr); + +#if QT_DEPRECATED_SINCE(6, 3) struct Q_QML_EXPORT SingletonFunctor { + QT_DEPRECATED QObject *operator()(QQmlEngine *, QJSEngine *); + QPointer<QObject> m_object; + bool alreadyCalled = false; + }; +#endif + + struct Q_QML_EXPORT SingletonInstanceFunctor + { QObject *operator()(QQmlEngine *, QJSEngine *); QPointer<QObject> m_object; - bool alreadyCalled = false; + + // Not a QPointer, so that you cannot assign it to a different + // engine when the first one is deleted. + // That would mess up the QML contexts. + QQmlEngine *m_engine = nullptr; }; - static int indexOfOwnClassInfo(const QMetaObject *metaObject, const char *key) + static int indexOfOwnClassInfo(const QMetaObject *metaObject, const char *key, int startOffset = -1) { if (!metaObject || !key) return -1; const int offset = metaObject->classInfoOffset(); - for (int i = metaObject->classInfoCount() + offset - 1; i >= offset; --i) + const int start = (startOffset == -1) + ? (metaObject->classInfoCount() + offset - 1) + : startOffset; + for (int i = start; i >= offset; --i) if (qstrcmp(key, metaObject->classInfo(i).name()) == 0) { return i; } @@ -679,38 +828,18 @@ namespace QQmlPrivate const int index = indexOfOwnClassInfo(metaObject, key); return (index == -1) ? defaultValue : QTypeRevision::fromEncodedVersion( - QByteArray(metaObject->classInfo(index).value()).toInt()); + QLatin1StringView(metaObject->classInfo(index).value()).toInt()); } + Q_QML_EXPORT QList<QTypeRevision> revisionClassInfos(const QMetaObject *metaObject, const char *key); + inline bool boolClassInfo(const QMetaObject *metaObject, const char *key, bool defaultValue = false) { const int index = indexOfOwnClassInfo(metaObject, key); - return (index == -1) ? defaultValue - : (QByteArray(metaObject->classInfo(index).value()) == "true"); - } - - inline const char *classElementName(const QMetaObject *metaObject) - { - const char *elementName = classInfo(metaObject, "QML.Element"); - if (qstrcmp(elementName, "auto") == 0) { - const char *strippedClassName = metaObject->className(); - for (const char *c = strippedClassName; *c != '\0'; c++) { - if (*c == ':') - strippedClassName = c + 1; - } - - return strippedClassName; - } - if (qstrcmp(elementName, "anonymous") == 0) - return nullptr; - - if (!elementName) { - qWarning().nospace() << "Missing QML.Element class info \"" << elementName << "\"" - << " for " << metaObject->className(); - } - - return elementName; + if (index == -1) + return defaultValue; + return qstrcmp(metaObject->classInfo(index).value(), "true") == 0; } template<class T, class = std::void_t<>> @@ -722,7 +851,9 @@ namespace QQmlPrivate template<class T> struct QmlExtended<T, std::void_t<typename T::QmlExtendedType>> { - using Type = typename T::QmlExtendedType; + using Type = typename std::conditional< + QmlTypeHasMarker<T, decltype(&T::qt_qmlMarker_extended)>::value, + typename T::QmlExtendedType, void>::type; }; template<class T, class = std::void_t<>> @@ -734,7 +865,13 @@ namespace QQmlPrivate template<class T> struct QmlExtendedNamespace<T, std::void_t<decltype(T::qmlExtendedNamespace())>> { - static constexpr const QMetaObject *metaObject() { return T::qmlExtendedNamespace(); } + static constexpr const QMetaObject *metaObject() + { + if constexpr (QmlTypeHasMarker<T, decltype(&T::qt_qmlMarker_extendedNamespace)>::value) + return T::qmlExtendedNamespace(); + else + return nullptr; + } }; template<class T, class = std::void_t<>> @@ -746,9 +883,40 @@ namespace QQmlPrivate template<class T> struct QmlResolved<T, std::void_t<typename T::QmlForeignType>> { - using Type = typename T::QmlForeignType; + using Type = typename std::conditional< + QmlTypeHasMarker<T, decltype(&T::qt_qmlMarker_foreign)>::value, + typename T::QmlForeignType, T>::type; + }; + + template<class T, class = std::void_t<>> + struct QmlUncreatable + { + static constexpr bool Value = false; + }; + + template<class T> + struct QmlUncreatable<T, std::void_t<typename T::QmlIsUncreatable>> + { + static constexpr bool Value = + QmlTypeHasMarker<T, decltype(&T::qt_qmlMarker_uncreatable)>::value + && bool(T::QmlIsUncreatable::yes); + }; + + template<class T, class = std::void_t<>> + struct QmlAnonymous + { + static constexpr bool Value = false; + }; + + template<class T> + struct QmlAnonymous<T, std::void_t<typename T::QmlIsAnonymous>> + { + static constexpr bool Value = + QmlTypeHasMarker<T, decltype(&T::qt_qmlMarker_anonymous)>::value + && bool(T::QmlIsAnonymous::yes); }; + template<class T, class = std::void_t<>> struct QmlSingleton { @@ -758,7 +926,9 @@ namespace QQmlPrivate template<class T> struct QmlSingleton<T, std::void_t<typename T::QmlIsSingleton>> { - static constexpr bool Value = bool(T::QmlIsSingleton::yes); + static constexpr bool Value = + QmlTypeHasMarker<T, decltype(&T::qt_qmlMarker_singleton)>::value + && bool(T::QmlIsSingleton::yes); }; template<class T, class = std::void_t<>> @@ -782,7 +952,7 @@ namespace QQmlPrivate }; template<class T> - struct QmlInterface<T, std::void_t<typename T::QmlIsInterface>> + struct QmlInterface<T, std::void_t<typename T::QmlIsInterface, decltype(qobject_interface_iid<T *>())>> { static constexpr bool Value = bool(T::QmlIsInterface::yes); }; @@ -802,7 +972,17 @@ namespace QQmlPrivate template<class T> struct QmlMetaType { - static QMetaType self() + static constexpr bool hasAcceptableCtors() + { + if constexpr (!std::is_default_constructible_v<T>) + return false; + else if constexpr (std::is_base_of_v<QObject, T>) + return true; + else + return std::is_copy_constructible_v<T>; + } + + static constexpr QMetaType self() { if constexpr (std::is_base_of_v<QObject, T>) return QMetaType::fromType<T*>(); @@ -810,20 +990,44 @@ namespace QQmlPrivate return QMetaType::fromType<T>(); } - static QMetaType list() + static constexpr QMetaType list() { if constexpr (std::is_base_of_v<QObject, T>) return QMetaType::fromType<QQmlListProperty<T>>(); else - return QMetaType(); + return QMetaType::fromType<QList<T>>(); + } + + static constexpr QMetaSequence sequence() + { + if constexpr (std::is_base_of_v<QObject, T>) + return QMetaSequence(); + else + return QMetaSequence::fromContainer<QList<T>>(); + } + + static constexpr int size() + { + return sizeof(T); } }; + template<> + struct QmlMetaType<void> + { + static constexpr bool hasAcceptableCtors() { return true; } + static constexpr QMetaType self() { return QMetaType(); } + static constexpr QMetaType list() { return QMetaType(); } + static constexpr QMetaSequence sequence() { return QMetaSequence(); } + static constexpr int size() { return 0; } + }; + template<typename T, typename E, typename WrapperT = T> void qmlRegisterSingletonAndRevisions(const char *uri, int versionMajor, const QMetaObject *classInfoMetaObject, QVector<int> *qmlTypeIds, const QMetaObject *extension) { + static_assert(std::is_base_of_v<QObject, T>); RegisterSingletonTypeAndRevisions api = { 0, @@ -849,14 +1053,16 @@ namespace QQmlPrivate template<typename T, typename E> void qmlRegisterTypeAndRevisions(const char *uri, int versionMajor, const QMetaObject *classInfoMetaObject, - QVector<int> *qmlTypeIds, const QMetaObject *extension) + QVector<int> *qmlTypeIds, const QMetaObject *extension, + bool forceAnonymous = false) { RegisterTypeAndRevisions type = { - 0, + 3, QmlMetaType<T>::self(), QmlMetaType<T>::list(), - int(sizeof(T)), - Constructors<T>::createInto, nullptr, + QmlMetaType<T>::size(), + Constructors<T>::createInto, + nullptr, ValueType<T, E>::create, uri, @@ -876,9 +1082,16 @@ namespace QQmlPrivate extension ? extension : ExtendedType<E>::staticMetaObject(), &qmlCreateCustomParser<T>, - qmlTypeIds + qmlTypeIds, + StaticCastSelector<T, QQmlFinalizerHook>::cast(), + + forceAnonymous, + QmlMetaType<T>::sequence(), }; + // Initialize the extension so that we can find it by name or ID. + qMetaTypeId<E>(); + qmlregister(TypeAndRevisionsRegistration, &type); } @@ -903,7 +1116,7 @@ namespace QQmlPrivate template<> void Q_QML_EXPORT qmlRegisterTypeAndRevisions<QQmlTypeNotAvailable, void>( const char *uri, int versionMajor, const QMetaObject *classInfoMetaObject, - QVector<int> *qmlTypeIds, const QMetaObject *); + QVector<int> *qmlTypeIds, const QMetaObject *, bool); constexpr QtPrivate::QMetaTypeInterface metaTypeForNamespace( const QtPrivate::QMetaTypeInterface::MetaObjectFn &metaObjectFunction, const char *name) @@ -929,8 +1142,26 @@ namespace QQmlPrivate }; } + Q_QML_EXPORT QObject *qmlExtendedObject(QObject *, int); + + enum QmlRegistrationWarning { + UnconstructibleType, + UnconstructibleSingleton, + NonQObjectWithAtached, + }; + + Q_QML_EXPORT void qmlRegistrationWarning(QmlRegistrationWarning warning, QMetaType type); + + Q_QML_EXPORT QMetaType compositeMetaType( + QV4::ExecutableCompilationUnit *unit, const QString &elementName); + Q_QML_EXPORT QMetaType compositeListMetaType( + QV4::ExecutableCompilationUnit *unit, const QString &elementName); + } // namespace QQmlPrivate QT_END_NAMESPACE +Q_DECLARE_OPAQUE_POINTER(QQmlV4FunctionPtr) +Q_DECLARE_OPAQUE_POINTER(QQmlV4ExecutionEnginePtr) + #endif // QQMLPRIVATE_H |