diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index b952888859..334ef96023 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -2728,10 +2728,20 @@ bool ExecutionEngine::metaTypeFromJS(const Value &value, QMetaType metaType, voi } const auto wrapperPrivate = wrapper->d(); - if (wrapperPrivate->propertyType() == metaType) { + if (metaType == QMetaType::fromType *>() + || metaType == wrapperPrivate->propertyType()) { *reinterpret_cast *>(data) = *wrapperPrivate->property(); return true; } + + if (metaType == QMetaType::fromType()) { + *reinterpret_cast(data) + = wrapperPrivate->property()->toList(); + return true; + } + + if (convertToIterable(metaType, data, wrapper)) + return true; } if (const QQmlValueTypeWrapper *vtw = value.as()) { diff --git a/tests/auto/qml/qmlcppcodegen/CMakeLists.txt b/tests/auto/qml/qmlcppcodegen/CMakeLists.txt index d2e248ec8a..48a89a409c 100644 --- a/tests/auto/qml/qmlcppcodegen/CMakeLists.txt +++ b/tests/auto/qml/qmlcppcodegen/CMakeLists.txt @@ -15,6 +15,7 @@ qt_internal_add_test(tst_qmlcppcodegen LIBRARIES Qt::Qml Qt::QmlPrivate + Qt::QmlMetaPrivate Qt::GuiPrivate codegen_test_module codegen_test_moduleplugin @@ -34,6 +35,7 @@ qt_internal_add_test(tst_qmlcppcodegen_interpreted LIBRARIES Qt::Qml Qt::QmlPrivate + Qt::QmlMetaPrivate Qt::GuiPrivate codegen_test_module codegen_test_moduleplugin diff --git a/tests/auto/qml/qmlcppcodegen/data/listConversion.qml b/tests/auto/qml/qmlcppcodegen/data/listConversion.qml index ca86d9a1d6..8920658f86 100644 --- a/tests/auto/qml/qmlcppcodegen/data/listConversion.qml +++ b/tests/auto/qml/qmlcppcodegen/data/listConversion.qml @@ -14,4 +14,23 @@ BirthdayParty { property list o: self.guests property list s: self.guestNames property list v: self.stuffs + + component DataSource : QtObject { + property list numbers: [1, 2] + property list objects: [ + QtObject { objectName: "a" }, + QtObject { objectName: "b" } + ] + property list bindings: [ + Binding { objectName: "c" }, + Binding { objectName: "d" } + ] + } + + property DataSource src: DataSource {} + property list numbers: src.numbers + property list objects: src.objects + property list bindings: src.bindings + property list objectsFromBindings: src.bindings + property list nulls: src.objects } diff --git a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp index 4217206307..673155119b 100644 --- a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp +++ b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp @@ -15,12 +15,15 @@ #include #include -#include -#include +#include +#include +#include + +#include +#include -#include -#include #include +#include #include #if QT_CONFIG(process) @@ -3154,9 +3157,19 @@ void tst_QmlCppCodegen::listAsArgument() void tst_QmlCppCodegen::listConversion() { QQmlEngine e; - QQmlComponent c(&e, QUrl(u"qrc:/qt/qml/TestTypes/listConversion.qml"_s)); - QVERIFY2(c.isReady(), qPrintable(c.errorString())); - QScopedPointer o(c.create()); + QQmlComponent component(&e, QUrl(u"qrc:/qt/qml/TestTypes/listConversion.qml"_s)); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + + QTest::ignoreMessage( + QtWarningMsg, + QRegularExpression(u"Cannot append QObject\\(0x[0-9a-f]+, name = \"a\"\\) " + "to a QML list of QQmlBind\\*"_s)); + QTest::ignoreMessage( + QtWarningMsg, + QRegularExpression(u"Cannot append QObject\\(0x[0-9a-f]+, name = \"b\"\\) " + "to a QML list of QQmlBind\\*"_s)); + + QScopedPointer o(component.create()); QVERIFY(!o.isNull()); QQmlListProperty list = o->property("o").value>(); @@ -3177,6 +3190,39 @@ void tst_QmlCppCodegen::listConversion() QVariant::fromValue(3), QVariant::fromValue(nullptr) })); + + QCOMPARE(o->property("numbers").value>(), (QList{1, 2})); + auto objects = o->property("objects").value>(); + QCOMPARE(objects.count(&objects), 2); + + const QObject *a = objects.at(&objects, 0); + QVERIFY(a); + QCOMPARE(a->objectName(), u"a"_s); + + const QObject *b = objects.at(&objects, 1); + QVERIFY(b); + QCOMPARE(b->objectName(), u"b"_s); + + auto bindings = o->property("bindings").value>(); + QCOMPARE(bindings.count(&bindings), 2); + + const QQmlBind *c = bindings.at(&bindings, 0); + QVERIFY(c); + QCOMPARE(c->objectName(), u"c"_s); + + const QQmlBind *d = bindings.at(&bindings, 1); + QVERIFY(d); + QCOMPARE(d->objectName(), u"d"_s); + + auto objectsFromBindings = o->property("objectsFromBindings").value>(); + QCOMPARE(objectsFromBindings.count(&objectsFromBindings), 2); + QCOMPARE(objectsFromBindings.at(&objectsFromBindings, 0), c); + QCOMPARE(objectsFromBindings.at(&objectsFromBindings, 1), d); + + auto nulls = o->property("nulls").value>(); + QCOMPARE(nulls.count(&nulls), 2); + QCOMPARE(nulls.at(&nulls, 0), nullptr); + QCOMPARE(nulls.at(&nulls, 1), nullptr); } void tst_QmlCppCodegen::listIndices()