aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqml.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2022-06-24 14:40:02 +0200
committerUlf Hermann <ulf.hermann@qt.io>2022-07-11 13:37:26 +0200
commite19328fb0fefdf60a111bb662bf6ce0df901ac8f (patch)
tree8cdba6417ea5ab575e41f4c44bcbb5b5aca2d479 /src/qml/qml/qqml.cpp
parent989e05a0b8240778c9f249edea5c9d27d68f8e0f (diff)
QmlCompiler: Allow storeNameSloppy to reset a property
We should not convert from undefined on storeNameSloppy. The reset is intentional. Task-number: QTBUG-104508 Change-Id: Iede88fe6331dd173c9e8ea0ec4200df2b8bd30eb Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/qml/qqml.cpp')
-rw-r--r--src/qml/qml/qqml.cpp58
1 files changed, 53 insertions, 5 deletions
diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp
index 0fd0f9b5cd..847522f052 100644
--- a/src/qml/qml/qqml.cpp
+++ b/src/qml/qml/qqml.cpp
@@ -862,7 +862,8 @@ static ObjectPropertyResult loadFallbackProperty(
return ObjectPropertyResult::OK;
}
-static ObjectPropertyResult storeObjectProperty(QV4::Lookup *l, QObject *object, void *value)
+template<typename Op>
+static ObjectPropertyResult changeObjectProperty(QV4::Lookup *l, QObject *object, Op op)
{
const QQmlData *qmlData = QQmlData::get(object);
if (!qmlData)
@@ -874,11 +875,26 @@ static ObjectPropertyResult storeObjectProperty(QV4::Lookup *l, QObject *object,
return ObjectPropertyResult::NeedsInit;
const QQmlPropertyData *property = l->qobjectLookup.propertyData;
QQmlPropertyPrivate::removeBinding(object, QQmlPropertyIndex(property->coreIndex()));
- property->writeProperty(object, value, {});
+ op(property);
return ObjectPropertyResult::OK;
}
-static ObjectPropertyResult storeFallbackProperty(QV4::Lookup *l, QObject *object, void *value)
+static ObjectPropertyResult resetObjectProperty(QV4::Lookup *l, QObject *object)
+{
+ return changeObjectProperty(l, object, [&](const QQmlPropertyData *property) {
+ property->resetProperty(object, {});
+ });
+}
+
+static ObjectPropertyResult storeObjectProperty(QV4::Lookup *l, QObject *object, void *value)
+{
+ return changeObjectProperty(l, object, [&](const QQmlPropertyData *property) {
+ property->writeProperty(object, value, {});
+ });
+}
+
+template<typename Op>
+static ObjectPropertyResult changeFallbackProperty(QV4::Lookup *l, QObject *object, Op op)
{
const QQmlData *qmlData = QQmlData::get(object);
if (qmlData && qmlData->isQueuedForDeletion)
@@ -893,11 +909,26 @@ static ObjectPropertyResult storeFallbackProperty(QV4::Lookup *l, QObject *objec
const int coreIndex = l->qobjectFallbackLookup.coreIndex;
QQmlPropertyPrivate::removeBinding(object, QQmlPropertyIndex(coreIndex));
- void *args[] = { value, nullptr };
- metaObject->metacall(object, QMetaObject::WriteProperty, coreIndex, args);
+ op(metaObject, coreIndex);
return ObjectPropertyResult::OK;
}
+static ObjectPropertyResult storeFallbackProperty(QV4::Lookup *l, QObject *object, void *value)
+{
+ return changeFallbackProperty(l, object, [&](const QMetaObject *metaObject, int coreIndex) {
+ void *args[] = { value, nullptr };
+ metaObject->metacall(object, QMetaObject::WriteProperty, coreIndex, args);
+ });
+}
+
+static ObjectPropertyResult resetFallbackProperty(QV4::Lookup *l, QObject *object)
+{
+ return changeFallbackProperty(l, object, [&](const QMetaObject *metaObject, int coreIndex) {
+ void *args[] = { nullptr };
+ metaObject->metacall(object, QMetaObject::ResetProperty, coreIndex, args);
+ });
+}
+
static bool isTypeCompatible(QMetaType lookupType, QMetaType propertyType)
{
if (!lookupType.isValid()) {
@@ -1115,6 +1146,19 @@ QMetaType AOTCompiledContext::lookupResultMetaType(uint index) const
return QMetaType();
}
+static bool isUndefined(const void *value, QMetaType type)
+{
+ if (type == QMetaType::fromType<QVariant>())
+ return !static_cast<const QVariant *>(value)->isValid();
+ if (type == QMetaType::fromType<QJSValue>())
+ return static_cast<const QJSValue *>(value)->isUndefined();
+ if (type == QMetaType::fromType<QJSPrimitiveValue>()) {
+ return static_cast<const QJSPrimitiveValue *>(value)->type()
+ == QJSPrimitiveValue::Undefined;
+ }
+ return false;
+}
+
void AOTCompiledContext::storeNameSloppy(uint nameIndex, void *value, QMetaType type) const
{
// We don't really use any part of the lookup machinery here.
@@ -1130,6 +1174,8 @@ void AOTCompiledContext::storeNameSloppy(uint nameIndex, void *value, QMetaType
const QMetaType propType = l.qobjectLookup.propertyData->propType();
if (type == propType) {
storeResult = storeObjectProperty(&l, qmlScopeObject, value);
+ } else if (isUndefined(value, type)) {
+ storeResult = resetObjectProperty(&l, qmlScopeObject);
} else {
QVariant var(propType);
propType.convert(type, value, propType, var.data());
@@ -1146,6 +1192,8 @@ void AOTCompiledContext::storeNameSloppy(uint nameIndex, void *value, QMetaType
= metaObject->property(l.qobjectFallbackLookup.coreIndex).metaType();
if (type == propType) {
storeResult = storeFallbackProperty(&l, qmlScopeObject, value);
+ } else if (isUndefined(value, type)) {
+ storeResult = resetFallbackProperty(&l, qmlScopeObject);
} else {
QVariant var(propType);
propType.convert(type, value, propType, var.data());