aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKai Uwe Broulik <kde@privat.broulik.de>2023-08-17 23:09:21 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-08-22 11:16:07 +0000
commit6325e4d27f94bbee0dcab9f268836f24f7803a6e (patch)
tree1592085377e1f5c5339ccf2606f8e31432ffdfba
parent51f31ec915a0eaae5d83bf7f0a4583ac9ff274e1 (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. 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> (cherry picked from commit 139d45c062ce6061b96f7ffe206babde4b596a98) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp6
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.cpp2
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.h44
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp23
4 files changed, 71 insertions, 4 deletions
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 40e9a1dc5a..dcb4887511 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 3c14d67bf4..df09d43653 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.cpp
+++ b/tests/auto/qml/qqmllanguage/testtypes.cpp
@@ -162,6 +162,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 24cab1e3bc..19bc979968 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.h
+++ b/tests/auto/qml/qqmllanguage/testtypes.h
@@ -2684,4 +2684,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 82eb505a80..1c6143f5df 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -424,6 +424,8 @@ private slots:
void attachedInCtor();
void byteArrayConversion();
+ void callMethodOfAttachedDerived();
+
private:
QQmlEngine engine;
QStringList defaultImportPathList;
@@ -8133,6 +8135,27 @@ void tst_qqmllanguage::byteArrayConversion()
QCOMPARE(receiver->byteArrays[1], QByteArray("\4\5\6"));
}
+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"