diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2021-06-16 15:01:00 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2021-06-17 13:05:24 +0200 |
commit | 94063d0c01b1471554773c00c2f6dd4a916fe0ac (patch) | |
tree | 1f767eb384312193d805e4e3c8feb6efe37b0be1 | |
parent | aa7a10ce8b062bad4df40afc63d2fea34744a2fb (diff) |
Fix conversion of entries to be added to QVariantLists
We should pass the variants themselves, not their constData().
Fixes: QTBUG-94502
Change-Id: I92688348d7b46d74935dc11080b26290f5e8be86
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit dbe34dfa0d42510b804c898b77d6fe145473c31b)
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 10 | ||||
-rw-r--r-- | tests/auto/qml/qqmllanguage/data/variantListConversion.qml | 7 | ||||
-rw-r--r-- | tests/auto/qml/qqmllanguage/testtypes.cpp | 3 | ||||
-rw-r--r-- | tests/auto/qml/qqmllanguage/testtypes.h | 48 | ||||
-rw-r--r-- | tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 19 |
5 files changed, 83 insertions, 4 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 958a994cc3..6883c219bc 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1597,9 +1597,11 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMet continue; } } - asVariant = toVariant(e, arrayValue, valueMetaType, false, - visitedObjects); - if (valueMetaType.id() != QMetaType::QVariant) { + + asVariant = toVariant(e, arrayValue, valueMetaType, false, visitedObjects); + if (valueMetaType == QMetaType::fromType<QVariant>()) { + retnAsIterable.metaContainer().addValue(retn.data(), &asVariant); + } else { auto originalType = asVariant.metaType(); bool couldConvert = asVariant.convert(valueMetaType); if (!couldConvert) { @@ -1610,8 +1612,8 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMet // create default constructed value asVariant = QVariant(valueMetaType, nullptr); } + retnAsIterable.metaContainer().addValue(retn.data(), asVariant.constData()); } - retnAsIterable.metaContainer().addValue(retn.data(), asVariant.constData()); } return retn; } diff --git a/tests/auto/qml/qqmllanguage/data/variantListConversion.qml b/tests/auto/qml/qqmllanguage/data/variantListConversion.qml new file mode 100644 index 0000000000..334bf17393 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/variantListConversion.qml @@ -0,0 +1,7 @@ +import Test + +Foo { + a.a: 12 + b.a: 13 + fooProperty: [a, b] +} diff --git a/tests/auto/qml/qqmllanguage/testtypes.cpp b/tests/auto/qml/qqmllanguage/testtypes.cpp index 80ec4900c7..fd541fd36a 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.cpp +++ b/tests/auto/qml/qqmllanguage/testtypes.cpp @@ -122,6 +122,9 @@ void registerTypes() qmlRegisterTypesAndRevisions<Extended, Foreign, ForeignExtended>("Test", 1); qmlRegisterTypesAndRevisions<BareSingleton>("Test", 1); qmlRegisterTypesAndRevisions<UncreatableSingleton>("Test", 1); + + qmlRegisterTypesAndRevisions<Large>("Test", 1); + qmlRegisterTypesAndRevisions<Foo>("Test", 1); } QVariant myCustomVariantTypeConverter(const QString &data) diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h index 25950acb74..2ffc324cae 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.h +++ b/tests/auto/qml/qqmllanguage/testtypes.h @@ -1725,6 +1725,54 @@ public: Q_INVOKABLE QList<EnumList::Enum> list() const { return { Alpha, Beta, Gamma }; } }; +struct Large { + Q_GADGET + QML_VALUE_TYPE(large) + + Q_PROPERTY(uint a MEMBER a) + Q_PROPERTY(uint b MEMBER b) + Q_PROPERTY(uint c MEMBER c) + Q_PROPERTY(uint d MEMBER d) + Q_PROPERTY(uint e MEMBER e) + Q_PROPERTY(uint f MEMBER f) + +public: + quint64 a; + quint64 b; + quint64 c; + quint64 d; + quint64 e; + quint64 f; +}; + +inline bool operator==(const Large &a, const Large &b) +{ + return a.a == b.a && a.b == b.b && a.c == b.c && a.d == b.d && a.e == b.e && a.f == b.f; +} + +inline bool operator!=(const Large &a, const Large &b) { return !(a == b); } + +class Foo: public QObject { + + Q_OBJECT + Q_PROPERTY(QVariantList fooProperty READ getList WRITE setList) + Q_PROPERTY(Large a MEMBER a BINDABLE aBindable) + Q_PROPERTY(Large b MEMBER b BINDABLE bBindable) + QML_ELEMENT + +public: + QVariantList getList() const { return mFooProperty;} + void setList(QVariantList list) { mFooProperty = list;} + + QBindable<Large> aBindable() { return QBindable<Large>(&a); } + QBindable<Large> bBindable() { return QBindable<Large>(&b); } + +private: + QProperty<Large> a; + QProperty<Large> b; + QVariantList mFooProperty; +}; + void registerTypes(); #endif // TESTTYPES_H diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index f95db6136d..478f236ee2 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -363,6 +363,8 @@ private slots: void propertyObserverOnReadonly(); + void variantListConversion(); + private: QQmlEngine engine; QStringList defaultImportPathList; @@ -6353,6 +6355,23 @@ void tst_qqmllanguage::propertyObserverOnReadonly() QCOMPARE(o->property("height").toDouble(), 54.2); } +void tst_qqmllanguage::variantListConversion() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("variantListConversion.qml")); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer<QObject> o(c.create()); + + Foo *foo = qobject_cast<Foo *>(o.data()); + QVERIFY(foo); + const QVariantList list = foo->getList(); + QCOMPARE(list.length(), 2); + const Large l0 = qvariant_cast<Large>(list.at(0)); + QCOMPARE(l0.a, 12ull); + const Large l1 = qvariant_cast<Large>(list.at(1)); + QCOMPARE(l1.a, 13ull); +} + QTEST_MAIN(tst_qqmllanguage) #include "tst_qqmllanguage.moc" |