diff options
author | Kai Uwe Broulik <kde@privat.broulik.de> | 2023-08-17 23:09:21 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2023-08-22 09:12:56 +0200 |
commit | 139d45c062ce6061b96f7ffe206babde4b596a98 (patch) | |
tree | baa682f5741d8284731798f5c20e217b5c0f156d | |
parent | 5789ae5da56b4f17fd126154f8a55bc7fcd936d8 (diff) |
QV4::QObjectWrapper: Use the object's actual meta type
Otherwise, a derived type's methods will not be found.
In our particular case we tried to call a method of 'B*' on a
QML attached property declared as 'A*'.
This restores the previous behavior of using the object()
for the meta type except for when it's a value type wrapper.
Amends commit 63b622d5908ec2960ce5dfa301e9d3fd4d92fdb4.
Pick-to: 6.6 6.5 6.2
Change-Id: I08b9f4b97a58c15fdc3703dd3c5d927cd1beb3ce
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Semih Yavuz <semih.yavuz@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r-- | src/qml/jsruntime/qv4qobjectwrapper.cpp | 6 | ||||
-rw-r--r-- | tests/auto/qml/qqmllanguage/testtypes.cpp | 2 | ||||
-rw-r--r-- | tests/auto/qml/qqmllanguage/testtypes.h | 44 | ||||
-rw-r--r-- | tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 23 |
4 files changed, 71 insertions, 4 deletions
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index d62675a2f4..868b799e57 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -2412,12 +2412,10 @@ const QMetaObject *Heap::QObjectMethod::metaObject() const { Scope scope(internalClass->engine); - if (Scoped<QV4::QObjectWrapper> objectWrapper(scope, wrapper); objectWrapper) - return objectWrapper->metaObject(); - if (Scoped<QV4::QQmlTypeWrapper> typeWrapper(scope, wrapper); typeWrapper) - return typeWrapper->metaObject(); if (Scoped<QV4::QQmlValueTypeWrapper> valueWrapper(scope, wrapper); valueWrapper) return valueWrapper->metaObject(); + if (QObject *self = object()) + return self->metaObject(); return nullptr; } diff --git a/tests/auto/qml/qqmllanguage/testtypes.cpp b/tests/auto/qml/qqmllanguage/testtypes.cpp index 26cbd4a96b..c8954ed089 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.cpp +++ b/tests/auto/qml/qqmllanguage/testtypes.cpp @@ -165,6 +165,8 @@ void registerTypes() qmlRegisterTypesAndRevisions<AttachedInCtor>("Test", 1); qmlRegisterTypesAndRevisions<ByteArrayReceiver>("Test", 1); + + qmlRegisterTypesAndRevisions<Counter>("Test", 1); } QVariant myCustomVariantTypeConverter(const QString &data) diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h index 9574b127c0..90503751a8 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.h +++ b/tests/auto/qml/qqmllanguage/testtypes.h @@ -2698,4 +2698,48 @@ public: } }; +class CounterAttachedBaseType: public QObject +{ + Q_OBJECT + QML_ANONYMOUS + Q_PROPERTY (int value READ value NOTIFY valueChanged) + +public: + CounterAttachedBaseType(QObject *parent = nullptr) : QObject(parent) {} + + int value() { return m_value; } + Q_SIGNAL void valueChanged(); + +protected: + int m_value = 98; +}; + + +class CounterAttachedType: public CounterAttachedBaseType +{ + Q_OBJECT + QML_ANONYMOUS + +public: + CounterAttachedType(QObject *parent = nullptr) : CounterAttachedBaseType(parent) {} + + Q_INVOKABLE void increase() { + ++m_value; + Q_EMIT valueChanged(); + } +}; + +class Counter : public QObject +{ + Q_OBJECT + QML_ATTACHED(CounterAttachedBaseType) + QML_ELEMENT + +public: + static CounterAttachedBaseType *qmlAttachedProperties(QObject *o) + { + return new CounterAttachedType(o); + } +}; + #endif // TESTTYPES_H diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index a7458af7ed..339f881e71 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -431,6 +431,8 @@ private slots: void signalNames_data(); void signalNames(); + void callMethodOfAttachedDerived(); + private: QQmlEngine engine; QStringList defaultImportPathList; @@ -8253,6 +8255,27 @@ Item { QVERIFY(changeSignal.size() == 2); } +void tst_qqmllanguage::callMethodOfAttachedDerived() +{ + QQmlEngine engine; + QQmlComponent c(&engine); + c.setData(R"( + import QtQml + import Test + + QtObject { + Component.onCompleted: Counter.increase() + property int v: Counter.value + } + )", QUrl()); + + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer<QObject> o(c.create()); + QVERIFY(!o.isNull()); + + QCOMPARE(o->property("v").toInt(), 99); +} + QTEST_MAIN(tst_qqmllanguage) #include "tst_qqmllanguage.moc" |