aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlprivate.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml/qqmlprivate.h')
-rw-r--r--src/qml/qml/qqmlprivate.h475
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