QObjectWrapper: Use metaTypeFromJS for call arguments
We want the precise type there, not some approximation that happens to be a QVariant. This exposes that we had a few conversions that were possible with QVariant::convert() but not with our builtin type coercion. Pick-to: 6.5 6.6 Change-Id: I44c57a22bad8268de3d4398721e1c63b18009dfc Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
7bcac62265
commit
67d0c08212
|
@ -2192,37 +2192,10 @@ bool CallArgument::fromValue(QMetaType metaType, ExecutionEngine *engine, const
|
|||
}
|
||||
|
||||
// Convert via QVariant through the QML engine.
|
||||
qvariantPtr = new (&allocData) QVariant();
|
||||
qvariantPtr = new (&allocData) QVariant(metaType);
|
||||
type = QVariantWrappedType;
|
||||
|
||||
QVariant v = ExecutionEngine::toVariant(value, metaType);
|
||||
|
||||
if (v.metaType() == metaType) {
|
||||
*qvariantPtr = std::move(v);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (v.canConvert(metaType)) {
|
||||
*qvariantPtr = std::move(v);
|
||||
qvariantPtr->convert(metaType);
|
||||
return true;
|
||||
}
|
||||
|
||||
const QQmlMetaObject mo = QQmlMetaType::rawMetaObjectForType(metaType);
|
||||
if (!mo.isNull() && v.metaType().flags().testFlag(QMetaType::PointerToQObject)) {
|
||||
QObject *obj = QQmlMetaType::toQObject(v);
|
||||
|
||||
if (obj != nullptr && !QQmlMetaObject::canConvert(obj, mo)) {
|
||||
*qvariantPtr = QVariant(metaType, nullptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
*qvariantPtr = QVariant(metaType, &obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
*qvariantPtr = QVariant(metaType, (void *)nullptr);
|
||||
return false;
|
||||
return ExecutionEngine::metaTypeFromJS(value, metaType, qvariantPtr->data());
|
||||
}
|
||||
|
||||
ReturnedValue CallArgument::toValue(ExecutionEngine *engine)
|
||||
|
|
|
@ -40,10 +40,13 @@ MyTypeObject {
|
|||
r2 = {x: 9, y: 10, width: 11, height: 12};
|
||||
c3 = 99;
|
||||
b2 = {i: 11, c: 15, p: {x: 4} }
|
||||
|
||||
acceptConstructible(object)
|
||||
c4 = {foo: 11};
|
||||
}
|
||||
|
||||
barren: ({i: 17})
|
||||
function changeBarren() { barren = "foos" }
|
||||
|
||||
property QtObject object: QtObject {}
|
||||
property constructible fromObject: object
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ struct ConstructibleValueType
|
|||
public:
|
||||
ConstructibleValueType() = default;
|
||||
Q_INVOKABLE ConstructibleValueType(int foo) : m_foo(foo) {}
|
||||
Q_INVOKABLE ConstructibleValueType(QObject *) : m_foo(67) {}
|
||||
|
||||
int foo() const { return m_foo; }
|
||||
|
||||
|
@ -350,6 +351,11 @@ public:
|
|||
emit barrenChanged();
|
||||
}
|
||||
|
||||
Q_INVOKABLE void acceptConstructible(const ConstructibleValueType &a)
|
||||
{
|
||||
setAVariant(QVariant::fromValue(a));
|
||||
}
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
void runScript();
|
||||
|
|
|
@ -358,6 +358,11 @@ void tst_qqmlvaluetypeproviders::structured()
|
|||
|
||||
QMetaObject::invokeMethod(o.data(), "changeBarren");
|
||||
QCOMPARE(o->property("barren").value<BarrenValueType>(), BarrenValueType(QString()));
|
||||
|
||||
QCOMPARE(o->property("fromObject").value<ConstructibleValueType>(),
|
||||
ConstructibleValueType(nullptr));
|
||||
QCOMPARE(o->property("aVariant").value<ConstructibleValueType>(),
|
||||
ConstructibleValueType(nullptr));
|
||||
}
|
||||
|
||||
void tst_qqmlvaluetypeproviders::recursive()
|
||||
|
|
Loading…
Reference in New Issue