QtQml: Properly handle someObject as someValueType

This should return undefined, not null.

Amends commit 71e2598379.

Change-Id: I750b674f03b35d3a5493bbc40625e37d651c73fe
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Ulf Hermann 2024-05-27 11:38:05 +02:00
parent ad22f5f499
commit fd4b87d455
2 changed files with 24 additions and 6 deletions

View File

@ -490,15 +490,16 @@ bool QQmlTypeWrapper::virtualIsEqualTo(Managed *a, Managed *b)
return false;
}
static ReturnedValue instanceOfQObject(const QV4::QQmlTypeWrapper *typeWrapper, const QObjectWrapper *objectWrapper)
static ReturnedValue instanceOfQObject(
const QV4::QQmlTypeWrapper *typeWrapper, QObject *wrapperObject)
{
QV4::ExecutionEngine *engine = typeWrapper->internalClass()->engine;
// in case the wrapper outlived the QObject*
const QObject *wrapperObject = objectWrapper->object();
if (!wrapperObject)
return engine->throwTypeError();
const QMetaType myTypeId = typeWrapper->d()->type().typeId();
const QQmlType type = typeWrapper->d()->type();
const QMetaType myTypeId = type.typeId();
QQmlMetaObject myQmlType;
if (!myTypeId.isValid()) {
// we're a composite type; a composite type cannot be equal to a
@ -523,7 +524,12 @@ static ReturnedValue instanceOfQObject(const QV4::QQmlTypeWrapper *typeWrapper,
const QMetaObject *theirType = wrapperObject->metaObject();
return QV4::Encode(QQmlMetaObject::canConvert(theirType, myQmlType));
if (QQmlMetaObject::canConvert(theirType, myQmlType))
return Encode(true);
else if (type.isValueType())
return Encode::undefined();
else
return Encode(false);
}
ReturnedValue QQmlTypeWrapper::virtualInstanceOf(const Object *typeObject, const Value &var)
@ -532,7 +538,13 @@ ReturnedValue QQmlTypeWrapper::virtualInstanceOf(const Object *typeObject, const
const QV4::QQmlTypeWrapper *typeWrapper = static_cast<const QV4::QQmlTypeWrapper *>(typeObject);
if (const QObjectWrapper *objectWrapper = var.as<QObjectWrapper>())
return instanceOfQObject(typeWrapper, objectWrapper);
return instanceOfQObject(typeWrapper, objectWrapper->object());
if (const QQmlTypeWrapper *varTypeWrapper = var.as<QQmlTypeWrapper>()) {
// Singleton or attachment
if (QObject *varObject = varTypeWrapper->object())
return instanceOfQObject(typeWrapper, varObject);
}
const QQmlType type = typeWrapper->d()->type();

View File

@ -8089,6 +8089,13 @@ void tst_qqmllanguage::asValueType()
"yields null rather than undefined. Add 'pragma "
"ValueTypeBehavior: Assertable' to prevent this."_L1));
QTest::ignoreMessage(
QtWarningMsg,
qPrintable(url.toString() + ":15: Coercing from instances of object types to value "
"types mistakenly yields null rather than undefined. Add "
"'pragma ValueTypeBehavior: Assertable' to prevent "
"this."_L1));
QTest::ignoreMessage(
QtWarningMsg,
qPrintable(url.toString() + ":16: Coercing a value to QtQml.Base/size using a type "
@ -8212,7 +8219,6 @@ void tst_qqmllanguage::asValueTypeGood()
QVERIFY(!o->property("n").isValid());
QVERIFY(!o->property("o").isValid());
QVERIFY(!o->property("p").isValid());
QEXPECT_FAIL("", "Needs proper handling of object types", Continue);
QVERIFY(!o->property("q").isValid());
QVERIFY(!o->property("r").isValid());
QVERIFY(!o->property("s").isValid());