diff options
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 13 | ||||
-rw-r--r-- | tests/auto/qml/qqmllanguage/data/arrayToContainer.qml | 1 | ||||
-rw-r--r-- | tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 26 |
3 files changed, 39 insertions, 1 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index b308737434..4d4013db48 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1576,7 +1576,18 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int QV4::ScopedValue arrayValue(scope); for (qint64 i = 0; i < length; ++i) { arrayValue = a->get(i); - QVariant asVariant = toVariant(e, arrayValue, retnAsIterable._metaType_id, false, visitedObjects); + QVariant asVariant; + if (QMetaType::hasRegisteredConverterFunction(qMetaTypeId<QJSValue>(), retnAsIterable._metaType_id)) { + // before attempting a conversion from the concrete types, + // check if there exists a conversion from QJSValue -> out type + // prefer that one for compatibility reasons + asVariant = QVariant::fromValue(QJSValuePrivate::fromReturnedValue(arrayValue->asReturnedValue())); + if (asVariant.convert(retnAsIterable._metaType_id)) { + retnAsIterable.append(asVariant.constData()); + continue; + } + } + asVariant = toVariant(e, arrayValue, retnAsIterable._metaType_id, false, visitedObjects); auto originalType = asVariant.userType(); bool couldConvert = asVariant.convert(retnAsIterable._metaType_id); if (!couldConvert) { diff --git a/tests/auto/qml/qqmllanguage/data/arrayToContainer.qml b/tests/auto/qml/qqmllanguage/data/arrayToContainer.qml index d8e278a7a1..bc1b0d51e0 100644 --- a/tests/auto/qml/qqmllanguage/data/arrayToContainer.qml +++ b/tests/auto/qml/qqmllanguage/data/arrayToContainer.qml @@ -6,4 +6,5 @@ TestItem { property var myset positions: vector barrays: myset + convertibles: ["hello", "world"] } diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index b4888f6fa7..77e545722a 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -5775,23 +5775,47 @@ void tst_qqmllanguage::inlineComponentDuplicateNameError() QCOMPARE(component.errorString(), message); } +struct QJSValueConvertible { + + Q_GADGET + +public: + QString msg; +}; + +bool operator==(const QJSValueConvertible &lhs, const QJSValueConvertible &rhs) { + return lhs.msg == rhs.msg; +} + class TestItem : public QObject { Q_OBJECT Q_PROPERTY( QVector<QPointF> positions MEMBER m_points ) Q_PROPERTY( QSet<QByteArray> barrays MEMBER m_barrays ) + Q_PROPERTY( QVector<QJSValueConvertible> convertibles MEMBER m_convertibles) public: TestItem() = default; QVector< QPointF > m_points; QSet<QByteArray> m_barrays; + QVector<QJSValueConvertible> m_convertibles; }; Q_DECLARE_METATYPE(QVector<QPointF>); Q_DECLARE_METATYPE(QSet<QByteArray>); +Q_DECLARE_METATYPE(QJSValueConvertible); +Q_DECLARE_METATYPE(QVector<QJSValueConvertible>); + void tst_qqmllanguage::arrayToContainer() { + QMetaType::registerConverter< QJSValue, QJSValueConvertible >( + + [](const QJSValue& value) + { + return QJSValueConvertible{value.toString()}; + } + ); QQmlEngine engine; qmlRegisterType<TestItem>("qt.test", 1, 0, "TestItem"); QVector<QPointF> points { QPointF (2.0, 3.0) }; @@ -5804,6 +5828,8 @@ void tst_qqmllanguage::arrayToContainer() QCOMPARE(root->m_points.at(0), QPointF (2.0, 3.0) ); QVERIFY(root->m_barrays.contains("hello")); QVERIFY(root->m_barrays.contains("world")); + QCOMPARE(root->m_convertibles.at(0).msg, QLatin1String("hello")); + QCOMPARE(root->m_convertibles.at(1).msg, QLatin1String("world")); } class EnumTester : public QObject |