aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2023-06-14 08:32:13 +0200
committerUlf Hermann <ulf.hermann@qt.io>2023-06-17 08:06:07 +0200
commitc07cc979335216a034a3958780150d301e996f67 (patch)
tree2c20e2b7da0857a11dcc5105fd8b9dd9117e7f4d
parent185888c6a82d6e11cd9f6614ef7616a28a87efc0 (diff)
QML: Allow creating constructible value types from variant objects
VariantObject as source for value type constructions should work the same way as other types. Change-Id: I35770adf0486b404673ee00800fb1d3e429a23cf Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit 0bb0eeeb09580de8bccef996f9b4099fb7d1b482)
-rw-r--r--src/qml/jsruntime/qv4engine.cpp2
-rw-r--r--tests/auto/qml/qqmlvaluetypeproviders/data/structuredValueTypes.qml4
-rw-r--r--tests/auto/qml/qqmlvaluetypeproviders/testtypes.h15
-rw-r--r--tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp84
4 files changed, 105 insertions, 0 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index dc26d6a93a..8d3d5e6b46 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -2685,6 +2685,8 @@ bool ExecutionEngine::metaTypeFromJS(const Value &value, QMetaType metaType, voi
proto = proto->getPrototypeOf();
}
}
+ } else if (QQmlValueTypeProvider::createValueType(var, metaType, data)) {
+ return true;
}
} else if (value.isNull() && isPointer) {
*reinterpret_cast<void* *>(data) = nullptr;
diff --git a/tests/auto/qml/qqmlvaluetypeproviders/data/structuredValueTypes.qml b/tests/auto/qml/qqmlvaluetypeproviders/data/structuredValueTypes.qml
index a6f05d7981..b0ae1cda1c 100644
--- a/tests/auto/qml/qqmlvaluetypeproviders/data/structuredValueTypes.qml
+++ b/tests/auto/qml/qqmlvaluetypeproviders/data/structuredValueTypes.qml
@@ -49,4 +49,8 @@ MyTypeObject {
property QtObject object: QtObject {}
property constructible fromObject: object
+ property int listResult: acceptConstructibles([Qt.resolvedUrl("foo/bar.baz"), fromObject, 12])
+
+ property var insanity: ({})
+ property structured fromInsanity: acceptStructured(insanity)
}
diff --git a/tests/auto/qml/qqmlvaluetypeproviders/testtypes.h b/tests/auto/qml/qqmlvaluetypeproviders/testtypes.h
index 7b308ff338..424995b594 100644
--- a/tests/auto/qml/qqmlvaluetypeproviders/testtypes.h
+++ b/tests/auto/qml/qqmlvaluetypeproviders/testtypes.h
@@ -34,6 +34,7 @@ public:
ConstructibleValueType() = default;
Q_INVOKABLE ConstructibleValueType(int foo) : m_foo(foo) {}
Q_INVOKABLE ConstructibleValueType(QObject *) : m_foo(67) {}
+ Q_INVOKABLE ConstructibleValueType(const QUrl &) : m_foo(68) {}
int foo() const { return m_foo; }
@@ -356,6 +357,20 @@ public:
setAVariant(QVariant::fromValue(a));
}
+ Q_INVOKABLE int acceptConstructibles(const QList<ConstructibleValueType> &constructibles)
+ {
+ int result = 0;
+ for (const auto &c: constructibles) {
+ result += c.foo();
+ }
+ return result;
+ }
+
+ Q_INVOKABLE StructuredValueType acceptStructured(const StructuredValueType &a)
+ {
+ return a;
+ }
+
signals:
void changed();
void runScript();
diff --git a/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp b/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp
index 1100827f34..fa4bf6e058 100644
--- a/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp
+++ b/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp
@@ -362,6 +362,90 @@ void tst_qqmlvaluetypeproviders::structured()
ConstructibleValueType(nullptr));
QCOMPARE(o->property("aVariant").value<ConstructibleValueType>(),
ConstructibleValueType(nullptr));
+
+ QCOMPARE(o->property("listResult").toInt(), 12 + 67 + 68);
+
+
+ // You can store all kinds of insanity in a VariantObject, but we generally don't.
+ // Since we cannot rule out the possibility of there being such VariantObjects, we need to test
+ // their conversions.
+
+
+ QCOMPARE(o->property("fromInsanity").value<StructuredValueType>(), StructuredValueType());
+
+ QV4::Scope scope(e.handle());
+ QV4::ScopedString name(scope, scope.engine->newString("insanity"));
+
+ QObject *po = o.data();
+ QV4::ScopedObject js(
+ scope, scope.engine->metaTypeToJS(QMetaType::fromType<MyTypeObject *>(), &po));
+
+ const QVariantHash hash {
+ {"i", 12},
+ {"c", QUrl("http://example.com")},
+ {"p", QVariantMap {
+ {"x", 17},
+ {"y", 18}
+ }}
+ };
+ QV4::ScopedValue hashValue(
+ scope, e.handle()->newVariantObject(QMetaType::fromType<QVariantHash>(), &hash));
+
+ js->put(name, hashValue);
+
+ StructuredValueType fromHash;
+ fromHash.setI(12);
+ fromHash.setC(ConstructibleValueType(QUrl()));
+ fromHash.setP(QPointF(17, 18));
+
+ QCOMPARE(o->property("fromInsanity").value<StructuredValueType>(), fromHash);
+
+ const QVariantMap map {
+ {"i", 13},
+ {"c", QVariant::fromValue(po) },
+ {"p", QVariantMap {
+ {"x", 19},
+ {"y", 20}
+ }}
+ };
+ QV4::ScopedValue mapValue(
+ scope, e.handle()->newVariantObject(QMetaType::fromType<QVariantMap>(), &map));
+ js->put(name, mapValue);
+
+ StructuredValueType fromMap;
+ fromMap.setI(13);
+ fromMap.setC(ConstructibleValueType(po));
+ fromMap.setP(QPointF(19, 20));
+
+ QCOMPARE(o->property("fromInsanity").value<StructuredValueType>(), fromMap);
+
+ BarrenValueType immediate;
+ immediate.setI(14);
+ QV4::ScopedValue immediateValue(
+ scope, e.handle()->newVariantObject(QMetaType::fromType<BarrenValueType>(), &immediate));
+ js->put(name, immediateValue);
+
+ StructuredValueType fromImmediate;
+ fromImmediate.setI(14);
+
+ QCOMPARE(o->property("fromInsanity").value<StructuredValueType>(), fromImmediate);
+
+ QQmlComponent c2(&e);
+ c2.setData(
+ "import QtQml; QtObject { property int i: 99; property point p: ({x: 3, y: 4}) }", QUrl());
+ QVERIFY(c2.isReady());
+ QScopedPointer<QObject> o2(c2.create());
+ QVERIFY(!o2.isNull());
+ QObject *object = o2.data();
+ QV4::ScopedValue objectValue(
+ scope, e.handle()->newVariantObject(QMetaType::fromType<QObject *>(), &object));
+ js->put(name, objectValue);
+
+ StructuredValueType fromObject;
+ fromObject.setI(99);
+ fromObject.setP(QPointF(3, 4));
+
+ QCOMPARE(o->property("fromInsanity").value<StructuredValueType>(), fromObject);
}
void tst_qqmlvaluetypeproviders::recursive()