diff options
-rw-r--r-- | src/qml/qml/qqmlmetatype.cpp | 16 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatype_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmltype.cpp | 1 | ||||
-rw-r--r-- | tests/auto/qml/qqmllanguage/testtypes.h | 32 | ||||
-rw-r--r-- | tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 23 |
5 files changed, 71 insertions, 3 deletions
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index db4ecc6397..110363ae3b 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -1430,6 +1430,14 @@ void QQmlMetaType::unregisterType(int typeIndex) } } +void QQmlMetaType::registerMetaObjectForType(const QMetaObject *metaobject, QQmlTypePrivate *type) +{ + Q_ASSERT(type); + + QQmlMetaTypeDataPtr data; + data->metaObjectToType.insert(metaobject, type); +} + static bool hasActiveInlineComponents(const QQmlTypePrivate *d) { for (const QQmlType &ic : qAsConst(d->objectIdToICType)) { @@ -1635,7 +1643,8 @@ QList<QQmlProxyMetaObject::ProxyData> QQmlMetaType::proxyData(const QMetaObject const QQmlMetaTypeDataPtr data; - auto createProxyMetaObject = [&](const QMetaObject *superdataBaseMetaObject, + auto createProxyMetaObject = [&](QQmlTypePrivate *This, + const QMetaObject *superdataBaseMetaObject, const QMetaObject *extMetaObject, QObject *(*extFunc)(QObject *)) { if (!extMetaObject) @@ -1652,16 +1661,17 @@ QList<QQmlProxyMetaObject::ProxyData> QQmlMetaType::proxyData(const QMetaObject lastMetaObject->d.superdata = mmo; QQmlProxyMetaObject::ProxyData data = { mmo, extFunc, 0, 0 }; metaObjects << data; + registerMetaObjectForType(mmo, This); }; while (mo) { QQmlTypePrivate *t = data->metaObjectToType.value(mo); if (t) { if (t->regType == QQmlType::CppType) { - createProxyMetaObject(t->baseMetaObject, t->extraData.cd->extMetaObject, + createProxyMetaObject(t, t->baseMetaObject, t->extraData.cd->extMetaObject, t->extraData.cd->extFunc); } else if (t->regType == QQmlType::SingletonType) { - createProxyMetaObject(t->baseMetaObject, t->extraData.sd->extMetaObject, + createProxyMetaObject(t, t->baseMetaObject, t->extraData.sd->extMetaObject, t->extraData.sd->extFunc); } } diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index 2c010f516d..b9bf78b0a7 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -148,6 +148,8 @@ public: 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); diff --git a/src/qml/qml/qqmltype.cpp b/src/qml/qml/qqmltype.cpp index 1d34b57fed..0bc817845d 100644 --- a/src/qml/qml/qqmltype.cpp +++ b/src/qml/qml/qqmltype.cpp @@ -232,6 +232,7 @@ void QQmlTypePrivate::init() const mmo->d.superdata = mo; QQmlProxyMetaObject::ProxyData data = { mmo, extFunc, 0, 0 }; metaObjects << data; + QQmlMetaType::registerMetaObjectForType(mmo, const_cast<QQmlTypePrivate *>(this)); }; if (regType == QQmlType::SingletonType) diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h index 54022b268f..bcc6a9d9eb 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.h +++ b/tests/auto/qml/qqmllanguage/testtypes.h @@ -1888,6 +1888,38 @@ public: } }; +class RevisionedExtension : public QObject +{ + Q_OBJECT + Q_PROPERTY(int extension READ extension WRITE setExtension REVISION(1, 0)) +public: + RevisionedExtension(QObject *parent = nullptr) : QObject(parent) {} + int extension() const { return m_ext; } + void setExtension(int e) { m_ext = e; } +private: + int m_ext = 42; +}; + +class ExtendedWithRevisionOld : public QObject +{ + Q_OBJECT + QML_ELEMENT + QML_EXTENDED(RevisionedExtension) + QML_ADDED_IN_VERSION(0, 5) +public: + ExtendedWithRevisionOld(QObject *parent = nullptr) : QObject(parent) { } +}; + +class ExtendedWithRevisionNew : public QObject +{ + Q_OBJECT + QML_ELEMENT + QML_EXTENDED(RevisionedExtension) + QML_ADDED_IN_VERSION(1, 0) +public: + ExtendedWithRevisionNew(QObject *parent = nullptr) : QObject(parent) { } +}; + class StringSignaler : public QObject { Q_OBJECT diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 81d6e6f6a0..73f886e217 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -369,6 +369,7 @@ private slots: void multiExtensionIndirect(); void multiExtensionQmlTypes(); void extensionSpecial(); + void extensionRevision(); void invalidInlineComponent(); void warnOnInjectedParameters(); #if QT_CONFIG(wheelevent) @@ -6540,6 +6541,28 @@ void tst_qqmllanguage::extensionSpecial() } } +void tst_qqmllanguage::extensionRevision() +{ + QQmlEngine engine; + { + QQmlComponent c(&engine); + c.setData("import StaticTest 0.5\nExtendedWithRevisionOld { extension: 40\n}", QUrl()); + QVERIFY(!c.isReady()); + QRegularExpression error( + ".*\"ExtendedWithRevisionOld.extension\" is not available in StaticTest 0.5.*"); + QVERIFY2(error.match(c.errorString()).hasMatch(), + qPrintable(u"Unmatched error: "_s + c.errorString())); + } + + { + QQmlComponent c(&engine); + c.setData("import StaticTest 1.0\nExtendedWithRevisionNew { extension: 40\n}", QUrl()); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer<QObject> o(c.create()); + QVERIFY(o); + } +} + void tst_qqmllanguage::invalidInlineComponent() { QQmlEngine e; |