aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/qml/qqmlmetatype.cpp174
-rw-r--r--src/qml/qml/qqmlmetatype_p.h3
-rw-r--r--src/qml/qml/qqmlmetatypedata.cpp6
-rw-r--r--src/qml/qml/qqmlmetatypedata_p.h19
-rw-r--r--src/qml/qml/qqmltype.cpp125
-rw-r--r--src/qml/qml/qqmltype_p.h17
-rw-r--r--src/qml/qml/qqmltype_p_p.h2
7 files changed, 183 insertions, 163 deletions
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index f7b5ee8bf0..35340aed47 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -81,6 +81,129 @@ private:
LockedData *data = nullptr;
};
+static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data,
+ const QQmlPrivate::RegisterInterface &type)
+{
+ auto *d = new QQmlTypePrivate(QQmlType::InterfaceType);
+ d->iid = type.iid;
+ d->typeId = type.typeId;
+ d->listId = type.listId;
+ d->isSetup = true;
+ d->version_maj = 0;
+ d->version_min = 0;
+ data->registerType(d);
+ return d;
+}
+
+static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data, const QString &elementName,
+ const QQmlPrivate::RegisterSingletonType &type)
+{
+ auto *d = new QQmlTypePrivate(QQmlType::SingletonType);
+ data->registerType(d);
+
+ d->elementName = elementName;
+ d->module = QString::fromUtf8(type.uri);
+
+ d->version_maj = type.versionMajor;
+ d->version_min = type.versionMinor;
+
+ if (type.qobjectApi) {
+ if (type.version >= 1) // static metaobject added in version 1
+ d->baseMetaObject = type.instanceMetaObject;
+ if (type.version >= 2) // typeId added in version 2
+ d->typeId = type.typeId;
+ if (type.version >= 2) // revisions added in version 2
+ d->revision = type.revision;
+ }
+
+ d->extraData.sd->singletonInstanceInfo = new QQmlType::SingletonInstanceInfo;
+ d->extraData.sd->singletonInstanceInfo->scriptCallback = type.scriptApi;
+ d->extraData.sd->singletonInstanceInfo->qobjectCallback = type.qobjectApi;
+ d->extraData.sd->singletonInstanceInfo->typeName = QString::fromUtf8(type.typeName);
+ d->extraData.sd->singletonInstanceInfo->instanceMetaObject
+ = (type.qobjectApi && type.version >= 1) ? type.instanceMetaObject : nullptr;
+
+ return d;
+}
+
+static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data, const QString &elementName,
+ const QQmlPrivate::RegisterType &type)
+{
+ QQmlTypePrivate *d = new QQmlTypePrivate(QQmlType::CppType);
+ data->registerType(d);
+ d->elementName = elementName;
+ d->module = QString::fromUtf8(type.uri);
+
+ d->version_maj = type.versionMajor;
+ d->version_min = type.versionMinor;
+ if (type.version >= 1) // revisions added in version 1
+ d->revision = type.revision;
+ d->typeId = type.typeId;
+ d->listId = type.listId;
+ d->extraData.cd->allocationSize = type.objectSize;
+ d->extraData.cd->newFunc = type.create;
+ d->extraData.cd->noCreationReason = type.noCreationReason;
+ d->baseMetaObject = type.metaObject;
+ d->extraData.cd->attachedPropertiesFunc = type.attachedPropertiesFunction;
+ d->extraData.cd->attachedPropertiesType = type.attachedPropertiesMetaObject;
+ if (d->extraData.cd->attachedPropertiesType) {
+ d->extraData.cd->attachedPropertiesId = data->attachedPropertyId(d->baseMetaObject,
+ d->index);
+ } else {
+ d->extraData.cd->attachedPropertiesId = -1;
+ }
+ d->extraData.cd->parserStatusCast = type.parserStatusCast;
+ d->extraData.cd->propertyValueSourceCast = type.valueSourceCast;
+ d->extraData.cd->propertyValueInterceptorCast = type.valueInterceptorCast;
+ d->extraData.cd->extFunc = type.extensionObjectCreate;
+ d->extraData.cd->customParser = type.customParser;
+ d->extraData.cd->registerEnumClassesUnscoped = true;
+
+ if (type.extensionMetaObject)
+ d->extraData.cd->extMetaObject = type.extensionMetaObject;
+
+ // Check if the user wants only scoped enum classes
+ if (d->baseMetaObject) {
+ auto indexOfClassInfo = d->baseMetaObject->indexOfClassInfo("RegisterEnumClassesUnscoped");
+ if (indexOfClassInfo != -1 && QString::fromUtf8(d->baseMetaObject->classInfo(indexOfClassInfo).value()) == QLatin1String("false"))
+ d->extraData.cd->registerEnumClassesUnscoped = false;
+ }
+
+ return d;
+}
+
+static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data, const QString &elementName,
+ const QQmlPrivate::RegisterCompositeType &type)
+{
+ auto *d = new QQmlTypePrivate(QQmlType::CompositeType);
+ data->registerType(d);
+ d->elementName = elementName;
+
+ d->module = QString::fromUtf8(type.uri);
+ d->version_maj = type.versionMajor;
+ d->version_min = type.versionMinor;
+
+ d->extraData.fd->url = QQmlTypeLoader::normalize(type.url);
+ return d;
+}
+
+static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data, const QString &elementName,
+ const QQmlPrivate::RegisterCompositeSingletonType &type)
+{
+ auto *d = new QQmlTypePrivate(QQmlType::CompositeSingletonType);
+ data->registerType(d);
+ d->elementName = elementName;
+ d->module = QString::fromUtf8(type.uri);
+
+ d->version_maj = type.versionMajor;
+ d->version_min = type.versionMinor;
+
+ d->extraData.sd->singletonInstanceInfo = new QQmlType::SingletonInstanceInfo;
+ d->extraData.sd->singletonInstanceInfo->url = QQmlTypeLoader::normalize(type.url);
+ d->extraData.sd->singletonInstanceInfo->typeName = QString::fromUtf8(type.typeName);
+ return d;
+}
+
void QQmlMetaType::clone(QMetaObjectBuilder &builder, const QMetaObject *mo,
const QMetaObject *ignoreStart, const QMetaObject *ignoreEnd)
{
@@ -182,9 +305,7 @@ QQmlType QQmlMetaType::registerInterface(const QQmlPrivate::RegisterInterface &t
qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
QQmlMetaTypeDataPtr data;
-
- QQmlType dtype(data, type);
- QQmlTypePrivate *priv = dtype.priv();
+ QQmlTypePrivate *priv = createQQmlType(data, type);
Q_ASSERT(priv);
data->idToType.insert(priv->typeId, priv);
@@ -200,7 +321,7 @@ QQmlType QQmlMetaType::registerInterface(const QQmlPrivate::RegisterInterface &t
data->interfaces.setBit(type.typeId, true);
data->lists.setBit(type.listId, true);
- return dtype;
+ return QQmlType(priv);
}
QString registrationTypeString(QQmlType::RegistrationType typeType)
@@ -321,13 +442,13 @@ QQmlType QQmlMetaType::registerType(const QQmlPrivate::RegisterType &type)
if (!checkRegistration(QQmlType::CppType, data, type.uri, elementName, type.versionMajor))
return QQmlType();
- QQmlType dtype(data, elementName, type);
+ QQmlTypePrivate *priv = createQQmlType(data, elementName, type);
- addTypeToData(dtype.priv(), data);
+ addTypeToData(priv, data);
if (!type.typeId)
- data->idToType.insert(dtype.typeId(), dtype.priv());
+ data->idToType.insert(priv->typeId, priv);
- return dtype;
+ return QQmlType(priv);
}
QQmlType QQmlMetaType::registerSingletonType(const QQmlPrivate::RegisterSingletonType &type)
@@ -338,11 +459,11 @@ QQmlType QQmlMetaType::registerSingletonType(const QQmlPrivate::RegisterSingleto
if (!checkRegistration(QQmlType::SingletonType, data, type.uri, typeName, type.versionMajor))
return QQmlType();
- QQmlType dtype(data, typeName, type);
+ QQmlTypePrivate *priv = createQQmlType(data, typeName, type);
- addTypeToData(dtype.priv(), data);
+ addTypeToData(priv, data);
- return dtype;
+ return QQmlType(priv);
}
QQmlType QQmlMetaType::registerCompositeSingletonType(const QQmlPrivate::RegisterCompositeSingletonType &type)
@@ -357,14 +478,13 @@ QQmlType QQmlMetaType::registerCompositeSingletonType(const QQmlPrivate::Registe
if (!checkRegistration(QQmlType::CompositeSingletonType, data, fileImport ? nullptr : type.uri, typeName))
return QQmlType();
- QQmlType dtype(data, typeName, type);
-
- addTypeToData(dtype.priv(), data);
+ QQmlTypePrivate *priv = createQQmlType(data, typeName, type);
+ addTypeToData(priv, data);
QQmlMetaTypeData::Files *files = fileImport ? &(data->urlToType) : &(data->urlToNonFileImportType);
- files->insertMulti(QQmlTypeLoader::normalize(type.url), dtype.priv());
+ files->insertMulti(QQmlTypeLoader::normalize(type.url), priv);
- return dtype;
+ return QQmlType(priv);
}
QQmlType QQmlMetaType::registerCompositeType(const QQmlPrivate::RegisterCompositeType &type)
@@ -379,13 +499,13 @@ QQmlType QQmlMetaType::registerCompositeType(const QQmlPrivate::RegisterComposit
if (!checkRegistration(QQmlType::CompositeType, data, fileImport?nullptr:type.uri, typeName, type.versionMajor))
return QQmlType();
- QQmlType dtype(data, typeName, type);
- addTypeToData(dtype.priv(), data);
+ QQmlTypePrivate *priv = createQQmlType(data, typeName, type);
+ addTypeToData(priv, data);
QQmlMetaTypeData::Files *files = fileImport ? &(data->urlToType) : &(data->urlToNonFileImportType);
- files->insertMulti(QQmlTypeLoader::normalize(type.url), dtype.priv());
+ files->insertMulti(QQmlTypeLoader::normalize(type.url), priv);
- return dtype;
+ return QQmlType(priv);
}
void QQmlMetaType::registerInternalCompositeType(QV4::CompiledData::CompilationUnit *compilationUnit)
@@ -484,6 +604,19 @@ void QQmlMetaType::registerUndeletableType(const QQmlType &dtype)
data->undeletableTypes.insert(dtype);
}
+int QQmlMetaType::registerAttachedPropertyId(const QMetaObject *metaObject, int index)
+{
+ QQmlMetaTypeDataPtr data;
+ return data->attachedPropertyId(metaObject, index);
+}
+
+bool QQmlMetaType::unregisterAttachedPropertyId(const QMetaObject *metaObject, int index)
+{
+ QQmlMetaTypeDataPtr data;
+ // This is run from the QQmlType dtor. QQmlTypes in user code can outlive QQmlMetaTypeData.
+ return data ? data->removeAttachedPropertyId(metaObject, index) : false;
+}
+
static bool namespaceContainsRegistrations(const QQmlMetaTypeData *data, const QString &uri,
int majorVersion)
{
@@ -664,7 +797,6 @@ QQmlType QQmlMetaType::typeForUrl(const QString &urlString,
}
data->registerType(priv);
- priv->refCount.deref();
addTypeToData(priv, data);
data->urlToType.insertMulti(url, priv);
return QQmlType(priv);
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index 2d22eb519f..dbfa10d044 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -88,6 +88,9 @@ public:
static void registerUndeletableType(const QQmlType &dtype);
+ static int registerAttachedPropertyId(const QMetaObject *metaObject, int index);
+ static bool unregisterAttachedPropertyId(const QMetaObject *metaObject, int index);
+
static QList<QString> qmlTypeNames();
static QList<QQmlType> qmlTypes();
static QList<QQmlType> qmlSingletonTypes();
diff --git a/src/qml/qml/qqmlmetatypedata.cpp b/src/qml/qml/qqmlmetatypedata.cpp
index 989f1adf7c..f4f127ab9a 100644
--- a/src/qml/qml/qqmlmetatypedata.cpp
+++ b/src/qml/qml/qqmlmetatypedata.cpp
@@ -56,8 +56,13 @@ QQmlMetaTypeData::~QQmlMetaTypeData()
for (QHash<const QMetaObject *, QQmlPropertyCache *>::Iterator it = propertyCaches.begin(), end = propertyCaches.end();
it != end; ++it)
(*it)->release();
+
+ // Do this before the attached properties disappear.
+ types.clear();
+ undeletableTypes.clear();
}
+// This expects a "fresh" QQmlTypePrivate and adopts its reference.
void QQmlMetaTypeData::registerType(QQmlTypePrivate *priv)
{
for (int i = 0; i < types.count(); ++i) {
@@ -69,6 +74,7 @@ void QQmlMetaTypeData::registerType(QQmlTypePrivate *priv)
}
types.append(QQmlType(priv));
priv->index = types.count() - 1;
+ priv->refCount.deref();
}
QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QMetaObject *metaObject)
diff --git a/src/qml/qml/qqmlmetatypedata_p.h b/src/qml/qml/qqmlmetatypedata_p.h
index cde6294c37..f61adada2c 100644
--- a/src/qml/qml/qqmlmetatypedata_p.h
+++ b/src/qml/qml/qqmlmetatypedata_p.h
@@ -128,8 +128,27 @@ struct QQmlMetaTypeData
qWarning("%s", message.toUtf8().constData());
}
+ int attachedPropertyId(const QMetaObject *metaObject, int ownIndex)
+ {
+ auto iter = attachedPropertyIds.find(metaObject);
+ return (iter == attachedPropertyIds.end())
+ ? *attachedPropertyIds.insert(metaObject, ownIndex)
+ : *iter;
+ }
+
+ bool removeAttachedPropertyId(const QMetaObject *metaObject, int ownIndex)
+ {
+ auto iter = attachedPropertyIds.find(metaObject);
+ if (iter != attachedPropertyIds.end() && *iter == ownIndex) {
+ attachedPropertyIds.erase(iter);
+ return true;
+ }
+ return false;
+ }
+
private:
QStringList *m_typeRegistrationFailures = nullptr;
+ QHash<const QMetaObject *, int> attachedPropertyIds;
};
inline uint qHash(const QQmlMetaTypeData::VersionedUri &v)
diff --git a/src/qml/qml/qqmltype.cpp b/src/qml/qml/qqmltype.cpp
index 1c69cedcd6..2a1b4715d0 100644
--- a/src/qml/qml/qqmltype.cpp
+++ b/src/qml/qml/qqmltype.cpp
@@ -115,8 +115,6 @@ QJSValue QQmlType::SingletonInstanceInfo::scriptApi(QQmlEngine *e) const
return scriptApis.value(e);
}
-QHash<const QMetaObject *, int> QQmlTypePrivate::attachedPropertyIds;
-
QQmlTypePrivate::QQmlTypePrivate(QQmlType::RegistrationType type)
: refCount(1), regType(type), iid(nullptr), typeId(0), listId(0), revision(0),
containsRevisionedAttributes(false), baseMetaObject(nullptr),
@@ -173,122 +171,6 @@ QQmlTypePrivate::~QQmlTypePrivate()
}
}
-QQmlType::QQmlType(QQmlMetaTypeData *data, const QQmlPrivate::RegisterInterface &interface)
- : d(new QQmlTypePrivate(InterfaceType))
-{
- d->iid = interface.iid;
- d->typeId = interface.typeId;
- d->listId = interface.listId;
- d->isSetup = true;
- d->version_maj = 0;
- d->version_min = 0;
- data->registerType(d);
-}
-
-QQmlType::QQmlType(QQmlMetaTypeData *data, const QString &elementName, const QQmlPrivate::RegisterSingletonType &type)
- : d(new QQmlTypePrivate(SingletonType))
-{
- data->registerType(d);
-
- d->elementName = elementName;
- d->module = QString::fromUtf8(type.uri);
-
- d->version_maj = type.versionMajor;
- d->version_min = type.versionMinor;
-
- if (type.qobjectApi) {
- if (type.version >= 1) // static metaobject added in version 1
- d->baseMetaObject = type.instanceMetaObject;
- if (type.version >= 2) // typeId added in version 2
- d->typeId = type.typeId;
- if (type.version >= 2) // revisions added in version 2
- d->revision = type.revision;
- }
-
- d->extraData.sd->singletonInstanceInfo = new SingletonInstanceInfo;
- d->extraData.sd->singletonInstanceInfo->scriptCallback = type.scriptApi;
- d->extraData.sd->singletonInstanceInfo->qobjectCallback = type.qobjectApi;
- d->extraData.sd->singletonInstanceInfo->typeName = QString::fromUtf8(type.typeName);
- d->extraData.sd->singletonInstanceInfo->instanceMetaObject
- = (type.qobjectApi && type.version >= 1) ? type.instanceMetaObject : nullptr;
-}
-
-QQmlType::QQmlType(QQmlMetaTypeData *data, const QString &elementName, const QQmlPrivate::RegisterCompositeSingletonType &type)
- : d(new QQmlTypePrivate(CompositeSingletonType))
-{
- data->registerType(d);
-
- d->elementName = elementName;
- d->module = QString::fromUtf8(type.uri);
-
- d->version_maj = type.versionMajor;
- d->version_min = type.versionMinor;
-
- d->extraData.sd->singletonInstanceInfo = new SingletonInstanceInfo;
- d->extraData.sd->singletonInstanceInfo->url = QQmlTypeLoader::normalize(type.url);
- d->extraData.sd->singletonInstanceInfo->typeName = QString::fromUtf8(type.typeName);
-}
-
-QQmlType::QQmlType(QQmlMetaTypeData *data, const QString &elementName, const QQmlPrivate::RegisterType &type)
- : d(new QQmlTypePrivate(CppType))
-{
- data->registerType(d);
-
- d->elementName = elementName;
- d->module = QString::fromUtf8(type.uri);
-
- d->version_maj = type.versionMajor;
- d->version_min = type.versionMinor;
- if (type.version >= 1) // revisions added in version 1
- d->revision = type.revision;
- d->typeId = type.typeId;
- d->listId = type.listId;
- d->extraData.cd->allocationSize = type.objectSize;
- d->extraData.cd->newFunc = type.create;
- d->extraData.cd->noCreationReason = type.noCreationReason;
- d->baseMetaObject = type.metaObject;
- d->extraData.cd->attachedPropertiesFunc = type.attachedPropertiesFunction;
- d->extraData.cd->attachedPropertiesType = type.attachedPropertiesMetaObject;
- if (d->extraData.cd->attachedPropertiesType) {
- auto iter = QQmlTypePrivate::attachedPropertyIds.find(d->baseMetaObject);
- if (iter == QQmlTypePrivate::attachedPropertyIds.end())
- iter = QQmlTypePrivate::attachedPropertyIds.insert(d->baseMetaObject, d->index);
- d->extraData.cd->attachedPropertiesId = *iter;
- } else {
- d->extraData.cd->attachedPropertiesId = -1;
- }
- d->extraData.cd->parserStatusCast = type.parserStatusCast;
- d->extraData.cd->propertyValueSourceCast = type.valueSourceCast;
- d->extraData.cd->propertyValueInterceptorCast = type.valueInterceptorCast;
- d->extraData.cd->extFunc = type.extensionObjectCreate;
- d->extraData.cd->customParser = type.customParser;
- d->extraData.cd->registerEnumClassesUnscoped = true;
-
- if (type.extensionMetaObject)
- d->extraData.cd->extMetaObject = type.extensionMetaObject;
-
- // Check if the user wants only scoped enum classes
- if (d->baseMetaObject) {
- auto indexOfClassInfo = d->baseMetaObject->indexOfClassInfo("RegisterEnumClassesUnscoped");
- if (indexOfClassInfo != -1 && QString::fromUtf8(d->baseMetaObject->classInfo(indexOfClassInfo).value()) == QLatin1String("false"))
- d->extraData.cd->registerEnumClassesUnscoped = false;
- }
-}
-
-QQmlType::QQmlType(QQmlMetaTypeData *data, const QString &elementName, const QQmlPrivate::RegisterCompositeType &type)
- : d(new QQmlTypePrivate(CompositeType))
-{
- data->registerType(d);
-
- d->elementName = elementName;
-
- d->module = QString::fromUtf8(type.uri);
- d->version_maj = type.versionMajor;
- d->version_min = type.versionMinor;
-
- d->extraData.fd->url = QQmlTypeLoader::normalize(type.url);
-}
-
QQmlType::QQmlType()
: d(nullptr)
{
@@ -325,11 +207,8 @@ QQmlType::~QQmlType()
if (d && !d->refCount.deref()) {
// If attached properties were successfully registered, deregister them.
// (They may not have been registered if some other type used the same baseMetaObject)
- if (d->regType == CppType && d->extraData.cd->attachedPropertiesType) {
- auto it = QQmlTypePrivate::attachedPropertyIds.find(d->baseMetaObject);
- if (it != QQmlTypePrivate::attachedPropertyIds.end() && *it == d->index)
- QQmlTypePrivate::attachedPropertyIds.erase(it);
- }
+ if (d->regType == CppType && d->extraData.cd->attachedPropertiesType)
+ QQmlMetaType::unregisterAttachedPropertyId(d->baseMetaObject, d->index);
delete d;
}
}
diff --git a/src/qml/qml/qqmltype_p.h b/src/qml/qml/qqmltype_p.h
index edc1b01a07..969c096aeb 100644
--- a/src/qml/qml/qqmltype_p.h
+++ b/src/qml/qml/qqmltype_p.h
@@ -60,7 +60,6 @@
QT_BEGIN_NAMESPACE
-struct QQmlMetaTypeData;
class QHashedCStringRef;
class QQmlTypePrivate;
class QHashedString;
@@ -194,23 +193,7 @@ private:
QQmlType resolveCompositeBaseType(QQmlEnginePrivate *engine) const;
int resolveCompositeEnumValue(QQmlEnginePrivate *engine, const QString &name, bool *ok) const;
QQmlPropertyCache *compositePropertyCache(QQmlEnginePrivate *engine) const;
- friend class QQmlTypePrivate;
-
- friend QString registrationTypeString(RegistrationType);
- friend bool checkRegistration(RegistrationType, QQmlMetaTypeData *, const char *, const QString &, int);
- friend QQmlType registerType(const QQmlPrivate::RegisterType &);
- friend QQmlType registerSingletonType(const QQmlPrivate::RegisterSingletonType &);
- friend QQmlType registerInterface(const QQmlPrivate::RegisterInterface &);
- friend int registerQmlUnitCacheHook(const QQmlPrivate::RegisterQmlUnitCacheHook &);
friend uint qHash(const QQmlType &t, uint seed);
- friend Q_QML_EXPORT void qmlClearTypeRegistrations();
- friend class QQmlMetaType;
-
- QQmlType(QQmlMetaTypeData *data, const QQmlPrivate::RegisterInterface &);
- QQmlType(QQmlMetaTypeData *data, const QString &, const QQmlPrivate::RegisterSingletonType &);
- QQmlType(QQmlMetaTypeData *data, const QString &, const QQmlPrivate::RegisterType &);
- QQmlType(QQmlMetaTypeData *data, const QString &, const QQmlPrivate::RegisterCompositeType &);
- QQmlType(QQmlMetaTypeData *data, const QString &, const QQmlPrivate::RegisterCompositeSingletonType &);
QQmlTypePrivate *d;
};
diff --git a/src/qml/qml/qqmltype_p_p.h b/src/qml/qml/qqmltype_p_p.h
index fd9b28c322..faff0808ec 100644
--- a/src/qml/qml/qqmltype_p_p.h
+++ b/src/qml/qml/qqmltype_p_p.h
@@ -129,8 +129,6 @@ public:
mutable QStringHash<int> scopedEnumIndex; // maps from enum name to index in scopedEnums
mutable QList<QStringHash<int>*> scopedEnums;
- static QHash<const QMetaObject *, int> attachedPropertyIds;
-
struct PropertyCacheByMinorVersion
{
PropertyCacheByMinorVersion() : cache(nullptr), minorVersion(-1) {}