Pass QMetaType by value rather than by ID in more places

This saves us some ping-pong between the IDs and the QMetaTypes, and
avoids possible ambiguities if multiple metatypes are registered for the
same C++ type.

Change-Id: I81cec94a9cd05d69927dc884f65574f0ab2ddc22
Reviewed-by: Maximilian Goldstein <max.goldstein@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Ulf Hermann 2021-06-07 15:28:54 +02:00
parent e5383a5d5d
commit c4addf7d0e
34 changed files with 285 additions and 276 deletions

View File

@ -1513,15 +1513,14 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMet
{ {
Q_ASSERT (!value.isEmpty()); Q_ASSERT (!value.isEmpty());
QV4::Scope scope(e); QV4::Scope scope(e);
int typeHint = metaType.id();
if (const QV4::VariantObject *v = value.as<QV4::VariantObject>()) if (const QV4::VariantObject *v = value.as<QV4::VariantObject>())
return v->d()->data(); return v->d()->data();
if (typeHint == QMetaType::Bool) if (metaType == QMetaType::fromType<bool>())
return QVariant(value.toBoolean()); return QVariant(value.toBoolean());
if (typeHint == QMetaType::QJsonValue) if (metaType == QMetaType::fromType<QJsonValue>())
return QVariant::fromValue(QV4::JsonObject::toJsonValue(value)); return QVariant::fromValue(QV4::JsonObject::toJsonValue(value));
if (metaType == QMetaType::fromType<QJSValue>()) if (metaType == QMetaType::fromType<QJSValue>())
@ -1529,7 +1528,7 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMet
if (value.as<QV4::Object>()) { if (value.as<QV4::Object>()) {
QV4::ScopedObject object(scope, value); QV4::ScopedObject object(scope, value);
if (typeHint == QMetaType::QJsonObject if (metaType == QMetaType::fromType<QJsonObject>()
&& !value.as<ArrayObject>() && !value.as<FunctionObject>()) { && !value.as<ArrayObject>() && !value.as<FunctionObject>()) {
return QVariant::fromValue(QV4::JsonObject::toJsonObject(object)); return QVariant::fromValue(QV4::JsonObject::toJsonObject(object));
} else if (QV4::QObjectWrapper *wrapper = object->as<QV4::QObjectWrapper>()) { } else if (QV4::QObjectWrapper *wrapper = object->as<QV4::QObjectWrapper>()) {
@ -1551,7 +1550,7 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMet
if (value.as<ArrayObject>()) { if (value.as<ArrayObject>()) {
QV4::ScopedArrayObject a(scope, value); QV4::ScopedArrayObject a(scope, value);
if (typeHint == qMetaTypeId<QList<QObject *> >()) { if (metaType == QMetaType::fromType<QList<QObject *>>()) {
QList<QObject *> list; QList<QObject *> list;
uint length = a->getLength(); uint length = a->getLength();
QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope); QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope);
@ -1565,14 +1564,14 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMet
} }
return QVariant::fromValue<QList<QObject*> >(list); return QVariant::fromValue<QList<QObject*> >(list);
} else if (typeHint == QMetaType::QJsonArray) { } else if (metaType == QMetaType::fromType<QJsonArray>()) {
return QVariant::fromValue(QV4::JsonObject::toJsonArray(a)); return QVariant::fromValue(QV4::JsonObject::toJsonArray(a));
} }
QVariant retn; QVariant retn;
#if QT_CONFIG(qml_sequence_object) #if QT_CONFIG(qml_sequence_object)
bool succeeded = false; bool succeeded = false;
retn = QV4::SequencePrototype::toVariant(value, typeHint, &succeeded); retn = QV4::SequencePrototype::toVariant(value, metaType, &succeeded);
if (succeeded) if (succeeded)
return retn; return retn;
#endif #endif
@ -1631,7 +1630,7 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMet
if (String *s = value.stringValue()) { if (String *s = value.stringValue()) {
const QString &str = s->toQString(); const QString &str = s->toQString();
// QChars are stored as a strings // QChars are stored as a strings
if (typeHint == QMetaType::QChar && str.size() == 1) if (metaType == QMetaType::fromType<QChar>() && str.size() == 1)
return str.at(0); return str.at(0);
return str; return str;
} }
@ -1642,7 +1641,7 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMet
if (const QV4::DateObject *d = value.as<DateObject>()) { if (const QV4::DateObject *d = value.as<DateObject>()) {
auto dt = d->toQDateTime(); auto dt = d->toQDateTime();
// See ExecutionEngine::metaTypeFromJS()'s handling of QMetaType::Date: // See ExecutionEngine::metaTypeFromJS()'s handling of QMetaType::Date:
if (typeHint == QMetaType::QDate) { if (metaType == QMetaType::fromType<QDate>()) {
const auto utc = dt.toUTC(); const auto utc = dt.toUTC();
if (utc.date() != dt.date() && utc.addSecs(-1).date() == dt.date()) if (utc.date() != dt.date() && utc.addSecs(-1).date() == dt.date())
dt = utc; dt = utc;
@ -1738,7 +1737,7 @@ static QVariant objectToVariant(QV4::ExecutionEngine *e, const QV4::Object *o, V
exactly the same as \a metaType and \a ptr. exactly the same as \a metaType and \a ptr.
*/ */
QV4::ReturnedValue ExecutionEngine::fromData( QV4::ReturnedValue ExecutionEngine::fromData(
const QMetaType &metaType, const void *ptr, const QVariant *variant) QMetaType metaType, const void *ptr, const QVariant *variant)
{ {
const int type = metaType.id(); const int type = metaType.id();
if (type < QMetaType::User) { if (type < QMetaType::User) {

View File

@ -778,8 +778,7 @@ public:
int argc, void **args, QMetaType *types); int argc, void **args, QMetaType *types);
private: private:
QV4::ReturnedValue fromData( QV4::ReturnedValue fromData(QMetaType type, const void *ptr, const QVariant *variant = nullptr);
const QMetaType &type, const void *ptr, const QVariant *variant = nullptr);
#if QT_CONFIG(qml_debug) #if QT_CONFIG(qml_debug)
QScopedPointer<QV4::Debugging::Debugger> m_debugger; QScopedPointer<QV4::Debugging::Debugger> m_debugger;

View File

@ -134,8 +134,6 @@ static QV4::ReturnedValue loadProperty(QV4::ExecutionEngine *v4, QObject *object
{ {
Q_ASSERT(!property.isFunction()); Q_ASSERT(!property.isFunction());
QV4::Scope scope(v4); QV4::Scope scope(v4);
const QMetaType propMetaType = property.propType();
const int propType = propMetaType.id();
if (property.isQObject()) { if (property.isQObject()) {
QObject *rv = nullptr; QObject *rv = nullptr;
@ -149,42 +147,54 @@ static QV4::ReturnedValue loadProperty(QV4::ExecutionEngine *v4, QObject *object
} }
} }
return ret; return ret;
}
} else if (property.isQList()) { if (property.isQList())
return QmlListWrapper::create(v4, object, property.coreIndex(), property.propType()); return QmlListWrapper::create(v4, object, property.coreIndex(), property.propType());
} else if (propType == QMetaType::QReal) {
qreal v = 0; const QMetaType propMetaType = property.propType();
property.readProperty(object, &v); switch (property.isEnum() ? QMetaType::Int : propMetaType.id()) {
return QV4::Encode(v); case QMetaType::Int: {
} else if (propType == QMetaType::Int || property.isEnum()) {
int v = 0; int v = 0;
property.readProperty(object, &v); property.readProperty(object, &v);
return QV4::Encode(v); return QV4::Encode(v);
} else if (propType == QMetaType::Bool) { }
case QMetaType::Bool: {
bool v = false; bool v = false;
property.readProperty(object, &v); property.readProperty(object, &v);
return QV4::Encode(v); return QV4::Encode(v);
} else if (propType == QMetaType::QString) { }
case QMetaType::QString: {
QString v; QString v;
property.readProperty(object, &v); property.readProperty(object, &v);
return v4->newString(v)->asReturnedValue(); return v4->newString(v)->asReturnedValue();
} else if (propType == QMetaType::UInt) { }
case QMetaType::UInt: {
uint v = 0; uint v = 0;
property.readProperty(object, &v); property.readProperty(object, &v);
return QV4::Encode(v); return QV4::Encode(v);
} else if (propType == QMetaType::Float) { }
case QMetaType::Float: {
float v = 0; float v = 0;
property.readProperty(object, &v); property.readProperty(object, &v);
return QV4::Encode(v); return QV4::Encode(v);
} else if (propType == QMetaType::Double) { }
case QMetaType::Double: {
double v = 0; double v = 0;
property.readProperty(object, &v); property.readProperty(object, &v);
return QV4::Encode(v); return QV4::Encode(v);
} else if (propType == qMetaTypeId<QJSValue>()) { }
default:
break;
}
if (propMetaType == QMetaType::fromType<QJSValue>()) {
QJSValue v; QJSValue v;
property.readProperty(object, &v); property.readProperty(object, &v);
return QJSValuePrivate::convertToReturnedValue(v4, v); return QJSValuePrivate::convertToReturnedValue(v4, v);
} else if (property.isQVariant()) { }
if (property.isQVariant()) {
QVariant v; QVariant v;
property.readProperty(object, &v); property.readProperty(object, &v);
@ -194,20 +204,24 @@ static QV4::ReturnedValue loadProperty(QV4::ExecutionEngine *v4, QObject *object
} }
return scope.engine->fromVariant(v); return scope.engine->fromVariant(v);
} else if (QQmlMetaType::isValueType(propMetaType)) { }
if (QQmlMetaType::isValueType(propMetaType)) {
if (const QMetaObject *valueTypeMetaObject = QQmlMetaType::metaObjectForValueType(propMetaType)) if (const QMetaObject *valueTypeMetaObject = QQmlMetaType::metaObjectForValueType(propMetaType))
return QV4::QQmlValueTypeWrapper::create(v4, object, property.coreIndex(), valueTypeMetaObject, propMetaType); return QV4::QQmlValueTypeWrapper::create(v4, object, property.coreIndex(), valueTypeMetaObject, propMetaType);
} else { } else {
#if QT_CONFIG(qml_sequence_object) #if QT_CONFIG(qml_sequence_object)
// see if it's a sequence type // see if it's a sequence type
bool succeeded = false; bool succeeded = false;
QV4::ScopedValue retn(scope, QV4::SequencePrototype::newSequence(v4, propType, object, property.coreIndex(), !property.isWritable(), &succeeded)); QV4::ScopedValue retn(scope, QV4::SequencePrototype::newSequence(
v4, propMetaType, object, property.coreIndex(),
!property.isWritable(), &succeeded));
if (succeeded) if (succeeded)
return retn->asReturnedValue(); return retn->asReturnedValue();
#endif #endif
} }
if (propType == QMetaType::UnknownType) { if (!propMetaType.isValid()) {
QMetaProperty p = object->metaObject()->property(property.coreIndex()); QMetaProperty p = object->metaObject()->property(property.coreIndex());
qWarning("QMetaProperty::read: Unable to handle unregistered datatype '%s' for property " qWarning("QMetaProperty::read: Unable to handle unregistered datatype '%s' for property "
"'%s::%s'", p.typeName(), object->metaObject()->className(), p.name()); "'%s::%s'", p.typeName(), object->metaObject()->className(), p.name());
@ -2004,14 +2018,13 @@ bool CallArgument::fromValue(QMetaType metaType, QV4::ExecutionEngine *engine, c
QQmlEnginePrivate *ep = engine->qmlEngine() ? QQmlEnginePrivate::get(engine->qmlEngine()) : nullptr; QQmlEnginePrivate *ep = engine->qmlEngine() ? QQmlEnginePrivate::get(engine->qmlEngine()) : nullptr;
QVariant v = scope.engine->toVariant(value, metaType); QVariant v = scope.engine->toVariant(value, metaType);
const QMetaType callMetaType(callType); if (v.metaType() == metaType) {
if (v.metaType() == callMetaType) {
*qvariantPtr = v; *qvariantPtr = v;
} else if (v.canConvert(callMetaType)) { } else if (v.canConvert(metaType)) {
*qvariantPtr = v; *qvariantPtr = v;
qvariantPtr->convert(callMetaType); qvariantPtr->convert(metaType);
} else { } else {
QQmlMetaObject mo = ep ? ep->rawMetaObjectForType(callType) : QQmlMetaObject(); QQmlMetaObject mo = ep ? ep->rawMetaObjectForType(metaType) : QQmlMetaObject();
if (!mo.isNull()) { if (!mo.isNull()) {
QObject *obj = QQmlMetaType::toQObject(v); QObject *obj = QQmlMetaType::toQObject(v);

View File

@ -605,7 +605,9 @@ ReturnedValue SequencePrototype::method_sort(const FunctionObject *b, const Valu
return o.asReturnedValue(); return o.asReturnedValue();
} }
ReturnedValue SequencePrototype::newSequence(QV4::ExecutionEngine *engine, int sequenceType, QObject *object, int propertyIndex, bool readOnly, bool *succeeded) ReturnedValue SequencePrototype::newSequence(
QV4::ExecutionEngine *engine, QMetaType sequenceType, QObject *object,
int propertyIndex, bool readOnly, bool *succeeded)
{ {
QV4::Scope scope(engine); QV4::Scope scope(engine);
// This function is called when the property is a QObject Q_PROPERTY of // This function is called when the property is a QObject Q_PROPERTY of
@ -613,9 +615,7 @@ ReturnedValue SequencePrototype::newSequence(QV4::ExecutionEngine *engine, int s
// (as well as object ptr + property index for updated-read and write-back) // (as well as object ptr + property index for updated-read and write-back)
// and so access/mutate avoids variant conversion. // and so access/mutate avoids variant conversion.
const QQmlType qmlType = QQmlMetaType::qmlType(sequenceType);
const QQmlType qmlType = QQmlMetaType::qmlType(
sequenceType, QQmlMetaType::TypeIdCategory::MetaType);
if (qmlType.isSequentialContainer()) { if (qmlType.isSequentialContainer()) {
*succeeded = true; *succeeded = true;
QV4::ScopedObject obj(scope, engine->memoryManager->allocate<QV4Sequence>( QV4::ScopedObject obj(scope, engine->memoryManager->allocate<QV4Sequence>(
@ -633,8 +633,7 @@ ReturnedValue SequencePrototype::fromVariant(
return fromData(engine, v.metaType(), v.constData(), succeeded); return fromData(engine, v.metaType(), v.constData(), succeeded);
} }
ReturnedValue SequencePrototype::fromData( ReturnedValue SequencePrototype::fromData(ExecutionEngine *engine, QMetaType type, const void *data, bool *succeeded)
ExecutionEngine *engine, const QMetaType &type, const void *data, bool *succeeded)
{ {
QV4::Scope scope(engine); QV4::Scope scope(engine);
// This function is called when assigning a sequence value to a normal JS var // This function is called when assigning a sequence value to a normal JS var
@ -642,8 +641,7 @@ ReturnedValue SequencePrototype::fromData(
// Access and mutation is extremely fast since it will not need to modify any // Access and mutation is extremely fast since it will not need to modify any
// QObject property. // QObject property.
const QQmlType qmlType = QQmlMetaType::qmlType( const QQmlType qmlType = QQmlMetaType::qmlType(type);
type.id(), QQmlMetaType::TypeIdCategory::MetaType);
if (qmlType.isSequentialContainer()) { if (qmlType.isSequentialContainer()) {
*succeeded = true; *succeeded = true;
QV4::ScopedObject obj(scope, engine->memoryManager->allocate<QV4Sequence>(qmlType, data)); QV4::ScopedObject obj(scope, engine->memoryManager->allocate<QV4Sequence>(qmlType, data));
@ -660,7 +658,7 @@ QVariant SequencePrototype::toVariant(Object *object)
return object->as<QV4Sequence>()->toVariant(); return object->as<QV4Sequence>()->toVariant();
} }
QVariant SequencePrototype::toVariant(const QV4::Value &array, int typeHint, bool *succeeded) QVariant SequencePrototype::toVariant(const QV4::Value &array, QMetaType typeHint, bool *succeeded)
{ {
*succeeded = true; *succeeded = true;
@ -671,7 +669,7 @@ QVariant SequencePrototype::toVariant(const QV4::Value &array, int typeHint, boo
QV4::Scope scope(array.as<Object>()->engine()); QV4::Scope scope(array.as<Object>()->engine());
QV4::ScopedArrayObject a(scope, array); QV4::ScopedArrayObject a(scope, array);
const QQmlType type = QQmlMetaType::qmlType(typeHint, QQmlMetaType::TypeIdCategory::MetaType); const QQmlType type = QQmlMetaType::qmlType(typeHint);
if (type.isSequentialContainer()) { if (type.isSequentialContainer()) {
const QMetaSequence *meta = type.priv()->extraData.ld; const QMetaSequence *meta = type.priv()->extraData.ld;
const QMetaType containerMetaType(type.priv()->typeId); const QMetaType containerMetaType(type.priv()->typeId);

View File

@ -79,13 +79,13 @@ struct Q_QML_PRIVATE_EXPORT SequencePrototype : public QV4::Object
static ReturnedValue method_valueOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc); static ReturnedValue method_valueOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_sort(const FunctionObject *, const Value *thisObject, const Value *argv, int argc); static ReturnedValue method_sort(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue newSequence(QV4::ExecutionEngine *engine, int sequenceTypeId, QObject *object, int propertyIndex, bool readOnly, bool *succeeded); static ReturnedValue newSequence(QV4::ExecutionEngine *engine, QMetaType sequenceType, QObject *object, int propertyIndex, bool readOnly, bool *succeeded);
static ReturnedValue fromVariant(QV4::ExecutionEngine *engine, const QVariant &v, bool *succeeded); static ReturnedValue fromVariant(QV4::ExecutionEngine *engine, const QVariant &v, bool *succeeded);
static ReturnedValue fromData(QV4::ExecutionEngine *engine, const QMetaType &type, const void *data, bool *succeeded); static ReturnedValue fromData(QV4::ExecutionEngine *engine, QMetaType type, const void *data, bool *succeeded);
static int metaTypeForSequence(const Object *object); static int metaTypeForSequence(const Object *object);
static QVariant toVariant(Object *object); static QVariant toVariant(Object *object);
static QVariant toVariant(const Value &array, int typeHint, bool *succeeded); static QVariant toVariant(const Value &array, QMetaType typeHint, bool *succeeded);
static void* getRawContainerPtr(const Object *object, int typeHint); static void* getRawContainerPtr(const Object *object, int typeHint);
}; };

View File

@ -806,7 +806,7 @@ static bool initObjectLookup(
if (!foundMetaObject) { if (!foundMetaObject) {
if (QQmlEngine *engine = aotContext->qmlEngine()) { if (QQmlEngine *engine = aotContext->qmlEngine()) {
foundMetaObject = QQmlEnginePrivate::get(engine)->metaObjectForType( foundMetaObject = QQmlEnginePrivate::get(engine)->metaObjectForType(
propType.id()).metaObject(); propType).metaObject();
} }
} }

View File

@ -586,7 +586,7 @@ void QQmlBinding::handleWriteError(const void *result, QMetaType resultType, QMe
if (QObject *o = *(QObject *const *)result) { if (QObject *o = *(QObject *const *)result) {
valueType = o->metaObject()->className(); valueType = o->metaObject()->className();
QQmlMetaObject propertyMetaObject = QQmlPropertyPrivate::rawMetaObjectForType( QQmlMetaObject propertyMetaObject = QQmlPropertyPrivate::rawMetaObjectForType(
QQmlEnginePrivate::get(engine()), metaType.id()); QQmlEnginePrivate::get(engine()), metaType);
if (!propertyMetaObject.isNull()) if (!propertyMetaObject.isNull())
propertyType = propertyMetaObject.className(); propertyType = propertyMetaObject.className();
} }
@ -781,7 +781,7 @@ class QObjectPointerBinding: public QQmlNonbindingBinding
QQmlMetaObject targetMetaObject; QQmlMetaObject targetMetaObject;
public: public:
QObjectPointerBinding(QQmlEnginePrivate *engine, int propertyType) QObjectPointerBinding(QQmlEnginePrivate *engine, QMetaType propertyType)
: targetMetaObject(QQmlPropertyPrivate::rawMetaObjectForType(engine, propertyType)) : targetMetaObject(QQmlPropertyPrivate::rawMetaObjectForType(engine, propertyType))
{} {}
@ -815,7 +815,7 @@ protected:
QQmlEngine *qmlEngine = engine(); QQmlEngine *qmlEngine = engine();
Q_ASSERT(qmlEngine); Q_ASSERT(qmlEngine);
resultMo = QQmlPropertyPrivate::rawMetaObjectForType( resultMo = QQmlPropertyPrivate::rawMetaObjectForType(
QQmlEnginePrivate::get(qmlEngine), value.userType()); QQmlEnginePrivate::get(qmlEngine), value.metaType());
if (resultMo.isNull()) if (resultMo.isNull())
return slowWrite(*pd, vtpd, result, type, isUndefined, flags); return slowWrite(*pd, vtpd, result, type, isUndefined, flags);
resultObject = *static_cast<QObject *const *>(value.constData()); resultObject = *static_cast<QObject *const *>(value.constData());
@ -857,7 +857,7 @@ protected:
QQmlEngine *qmlEngine = engine(); QQmlEngine *qmlEngine = engine();
Q_ASSERT(qmlEngine); Q_ASSERT(qmlEngine);
resultMo = QQmlPropertyPrivate::rawMetaObjectForType( resultMo = QQmlPropertyPrivate::rawMetaObjectForType(
QQmlEnginePrivate::get(qmlEngine), value.userType()); QQmlEnginePrivate::get(qmlEngine), value.metaType());
if (resultMo.isNull()) if (resultMo.isNull())
return slowWrite(*pd, vtpd, result, isUndefined, flags); return slowWrite(*pd, vtpd, result, isUndefined, flags);
resultObject = *static_cast<QObject *const *>(value.constData()); resultObject = *static_cast<QObject *const *>(value.constData());
@ -898,15 +898,12 @@ QQmlBinding *QQmlBinding::newBinding(QQmlEnginePrivate *engine, const QQmlProper
QQmlBinding *QQmlBinding::newBinding(QQmlEnginePrivate *engine, QMetaType propertyType) QQmlBinding *QQmlBinding::newBinding(QQmlEnginePrivate *engine, QMetaType propertyType)
{ {
if (propertyType.flags() & QMetaType::PointerToQObject) if (propertyType.flags() & QMetaType::PointerToQObject)
return new QObjectPointerBinding(engine, propertyType.id()); return new QObjectPointerBinding(engine, propertyType);
const int type = propertyType.id(); if (propertyType == QMetaType::fromType<QQmlBinding *>())
if (type == qMetaTypeId<QQmlBinding *>()) {
return new QQmlBindingBinding; return new QQmlBindingBinding;
}
switch (type) { switch (propertyType.id()) {
case QMetaType::Bool: case QMetaType::Bool:
return new GenericBinding<QMetaType::Bool>; return new GenericBinding<QMetaType::Bool>;
case QMetaType::Int: case QMetaType::Int:

View File

@ -1343,7 +1343,7 @@ template<>
QJSValue QQmlEngine::singletonInstance<QJSValue>(int qmlTypeId) QJSValue QQmlEngine::singletonInstance<QJSValue>(int qmlTypeId)
{ {
Q_D(QQmlEngine); Q_D(QQmlEngine);
QQmlType type = QQmlMetaType::qmlType(qmlTypeId, QQmlMetaType::TypeIdCategory::QmlType); QQmlType type = QQmlMetaType::qmlTypeById(qmlTypeId);
if (!type.isValid() || !type.isSingleton()) if (!type.isValid() || !type.isSingleton())
return QJSValue(); return QJSValue();
@ -2062,13 +2062,12 @@ static QQmlPropertyCache *propertyCacheForPotentialInlineComponentType(int t, co
* *
* Look up by type's baseMetaObject. * Look up by type's baseMetaObject.
*/ */
QQmlMetaObject QQmlEnginePrivate::rawMetaObjectForType(int t) const QQmlMetaObject QQmlEnginePrivate::rawMetaObjectForType(QMetaType metaType) const
{ {
if (QQmlPropertyCache *composite = findPropertyCacheInCompositeTypes(t)) if (QQmlPropertyCache *composite = findPropertyCacheInCompositeTypes(metaType.id()))
return QQmlMetaObject(composite); return QQmlMetaObject(composite);
QQmlType type = QQmlMetaType::qmlType(t); return QQmlMetaObject(QQmlMetaType::qmlType(metaType).baseMetaObject());
return QQmlMetaObject(type.baseMetaObject());
} }
/*! /*!
@ -2076,13 +2075,12 @@ QQmlMetaObject QQmlEnginePrivate::rawMetaObjectForType(int t) const
* *
* Look up by type's metaObject. * Look up by type's metaObject.
*/ */
QQmlMetaObject QQmlEnginePrivate::metaObjectForType(int t) const QQmlMetaObject QQmlEnginePrivate::metaObjectForType(QMetaType metaType) const
{ {
if (QQmlPropertyCache *composite = findPropertyCacheInCompositeTypes(t)) if (QQmlPropertyCache *composite = findPropertyCacheInCompositeTypes(metaType.id()))
return QQmlMetaObject(composite); return QQmlMetaObject(composite);
QQmlType type = QQmlMetaType::qmlType(t); return QQmlMetaObject(QQmlMetaType::qmlType(metaType).metaObject());
return QQmlMetaObject(type.metaObject());
} }
/*! /*!
@ -2090,12 +2088,12 @@ QQmlMetaObject QQmlEnginePrivate::metaObjectForType(int t) const
* *
* Look up by type's metaObject and version. * Look up by type's metaObject and version.
*/ */
QQmlPropertyCache *QQmlEnginePrivate::propertyCacheForType(int t) QQmlPropertyCache *QQmlEnginePrivate::propertyCacheForType(QMetaType metaType)
{ {
if (QQmlPropertyCache *composite = findPropertyCacheInCompositeTypes(t)) if (QQmlPropertyCache *composite = findPropertyCacheInCompositeTypes(metaType.id()))
return composite; return composite;
QQmlType type = QQmlMetaType::qmlType(t); const QQmlType type = QQmlMetaType::qmlType(metaType);
return type.isValid() ? cache(type.metaObject(), type.version()) : nullptr; return type.isValid() ? cache(type.metaObject(), type.version()) : nullptr;
} }
@ -2106,12 +2104,12 @@ QQmlPropertyCache *QQmlEnginePrivate::propertyCacheForType(int t)
* TODO: Is this correct? Passing a plain QTypeRevision() rather than QTypeRevision::zero() or * TODO: Is this correct? Passing a plain QTypeRevision() rather than QTypeRevision::zero() or
* the actual type's version seems strange. The behavior has been in place for a while. * the actual type's version seems strange. The behavior has been in place for a while.
*/ */
QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t) QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(QMetaType metaType)
{ {
if (QQmlPropertyCache *composite = findPropertyCacheInCompositeTypes(t)) if (QQmlPropertyCache *composite = findPropertyCacheInCompositeTypes(metaType.id()))
return composite; return composite;
QQmlType type = QQmlMetaType::qmlType(t); const QQmlType type = QQmlMetaType::qmlType(metaType);
return type.isValid() ? cache(type.baseMetaObject(), QTypeRevision()) : nullptr; return type.isValid() ? cache(type.baseMetaObject(), QTypeRevision()) : nullptr;
} }
@ -2121,12 +2119,13 @@ QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t)
* Look up by QQmlType and version. We only fall back to lookup by metaobject if the type * Look up by QQmlType and version. We only fall back to lookup by metaobject if the type
* has no revisiononed attributes here. Unspecified versions are interpreted as "any". * has no revisiononed attributes here. Unspecified versions are interpreted as "any".
*/ */
QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t, QTypeRevision version) QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(
QMetaType metaType, QTypeRevision version)
{ {
if (QQmlPropertyCache *composite = findPropertyCacheInCompositeTypes(t)) if (QQmlPropertyCache *composite = findPropertyCacheInCompositeTypes(metaType.id()))
return composite; return composite;
QQmlType type = QQmlMetaType::qmlType(t); const QQmlType type = QQmlMetaType::qmlType(metaType);
if (!type.isValid()) if (!type.isValid())
return nullptr; return nullptr;

View File

@ -235,11 +235,11 @@ public:
using QJSEnginePrivate::cache; using QJSEnginePrivate::cache;
// These methods may be called from the loader thread // These methods may be called from the loader thread
QQmlMetaObject rawMetaObjectForType(int) const; QQmlMetaObject rawMetaObjectForType(QMetaType metaType) const;
QQmlMetaObject metaObjectForType(int) const; QQmlMetaObject metaObjectForType(QMetaType metaType) const;
QQmlPropertyCache *propertyCacheForType(int); QQmlPropertyCache *propertyCacheForType(QMetaType metaType);
QQmlPropertyCache *rawPropertyCacheForType(int); QQmlPropertyCache *rawPropertyCacheForType(QMetaType metaType);
QQmlPropertyCache *rawPropertyCacheForType(int, QTypeRevision version); QQmlPropertyCache *rawPropertyCacheForType(QMetaType metaType, QTypeRevision version);
void registerInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit); void registerInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit);
void unregisterInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit); void unregisterInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit);
QV4::ExecutableCompilationUnit *obtainExecutableCompilationUnit(int typeId); QV4::ExecutableCompilationUnit *obtainExecutableCompilationUnit(int typeId);

View File

@ -48,21 +48,20 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
bool QQmlValueTypeProvider::initValueType(int type, QVariant& dst) bool QQmlValueTypeProvider::initValueType(QMetaType metaType, QVariant &dst)
{ {
const QMetaType metaType(type);
if (!metaType.isValid()) if (!metaType.isValid())
return false; return false;
dst = QVariant(QMetaType(type)); dst = QVariant(metaType);
return true; return true;
} }
bool QQmlValueTypeProvider::createValueType(int type, const QJSValue &s, QVariant &data) bool QQmlValueTypeProvider::createValueType(QMetaType metaType, const QJSValue &s, QVariant &data)
{ {
const QQmlType qmlType = QQmlMetaType::qmlType(type, QQmlMetaType::TypeIdCategory::MetaType); const QQmlType qmlType = QQmlMetaType::qmlType(metaType);
if (auto valueTypeFunction = qmlType.createValueTypeFunction()) { if (auto valueTypeFunction = qmlType.createValueTypeFunction()) {
QVariant result = valueTypeFunction(s); QVariant result = valueTypeFunction(s);
if (result.userType() == type) { if (result.metaType() == metaType) {
data = std::move(result); data = std::move(result);
return true; return true;
} }
@ -71,32 +70,34 @@ bool QQmlValueTypeProvider::createValueType(int type, const QJSValue &s, QVarian
return false; return false;
} }
bool QQmlValueTypeProvider::equalValueType(int type, const void *lhs, const QVariant& rhs) bool QQmlValueTypeProvider::equalValueType(QMetaType metaType, const void *lhs, const QVariant &rhs)
{ {
Q_ASSERT(lhs); Q_ASSERT(lhs);
return QMetaType(type).equals(lhs, rhs.constData()); return metaType.equals(lhs, rhs.constData());
} }
bool QQmlValueTypeProvider::readValueType(const QVariant& src, void *dst, int type) bool QQmlValueTypeProvider::readValueType(QMetaType metaType, const QVariant &src, void *dst)
{ {
Q_ASSERT(dst); Q_ASSERT(dst);
const QMetaType dstType(type); if (!metaType.isValid()
if (!dstType.isValid() || (src.metaType() == dstType && dstType.equals(src.constData(), dst))) || (src.metaType() == metaType && metaType.equals(src.constData(), dst))) {
return false; return false;
}
dstType.destruct(dst); metaType.destruct(dst);
dstType.construct(dst, src.metaType() == dstType ? src.constData() : nullptr); metaType.construct(dst, src.metaType() == metaType ? src.constData() : nullptr);
return true; return true;
} }
bool QQmlValueTypeProvider::writeValueType(int type, const void *src, QVariant& dst) bool QQmlValueTypeProvider::writeValueType(QMetaType metaType, const void *src, QVariant &dst)
{ {
Q_ASSERT(src); Q_ASSERT(src);
const QMetaType srcType(type); if (!metaType.isValid()
if (!srcType.isValid() || (dst.metaType() == srcType && srcType.equals(src, dst.constData()))) || (dst.metaType() == metaType && metaType.equals(src, dst.constData()))) {
return false; return false;
}
dst = QVariant(srcType, src); dst = QVariant(metaType, src);
return true; return true;
} }

View File

@ -220,11 +220,11 @@ inline void QQml_setParent_noEvent(QObject *object, QObject *parent)
class Q_QML_PRIVATE_EXPORT QQmlValueTypeProvider class Q_QML_PRIVATE_EXPORT QQmlValueTypeProvider
{ {
public: public:
bool initValueType(int, QVariant&); bool initValueType(QMetaType, QVariant &);
bool createValueType(int, const QJSValue &, QVariant &); bool createValueType(QMetaType, const QJSValue &, QVariant &);
bool equalValueType(int, const void *, const QVariant&); bool equalValueType(QMetaType, const void *, const QVariant &);
bool readValueType(const QVariant&, void *, int); bool readValueType(QMetaType, const QVariant &, void *);
bool writeValueType(int, const void *, QVariant&); bool writeValueType(QMetaType, const void *, QVariant &);
}; };
Q_AUTOTEST_EXPORT QQmlValueTypeProvider *QQml_valueTypeProvider(); Q_AUTOTEST_EXPORT QQmlValueTypeProvider *QQml_valueTypeProvider();

View File

@ -85,7 +85,7 @@ public:
const QMetaObject *elementType() const QMetaObject *elementType()
{ {
if (m_elementTypeOrEngine.isT2()) { if (m_elementTypeOrEngine.isT2()) {
const int listType = QQmlMetaType::listType(propertyType).id(); const QMetaType listType = QQmlMetaType::listType(propertyType);
const QQmlEngine *engine = m_elementTypeOrEngine.asT2(); const QQmlEngine *engine = m_elementTypeOrEngine.asT2();
const QQmlEnginePrivate *p = engine ? QQmlEnginePrivate::get(engine) : nullptr; const QQmlEnginePrivate *p = engine ? QQmlEnginePrivate::get(engine) : nullptr;
m_elementTypeOrEngine = p ? p->rawMetaObjectForType(listType).metaObject() m_elementTypeOrEngine = p ? p->rawMetaObjectForType(listType).metaObject()

View File

@ -1059,10 +1059,9 @@ QMetaType QQmlMetaType::listType(QMetaType metaType)
const auto iface = metaType.iface(); const auto iface = metaType.iface();
if (iface->metaObjectFn == &dynamicQmlListMarker) if (iface->metaObjectFn == &dynamicQmlListMarker)
return QMetaType(static_cast<const QQmlListMetaTypeInterface *>(iface)->valueType); return QMetaType(static_cast<const QQmlListMetaTypeInterface *>(iface)->valueType);
auto id = metaType.id();
QQmlMetaTypeDataPtr data; QQmlMetaTypeDataPtr data;
QQmlTypePrivate *type = data->idToType.value(id); QQmlTypePrivate *type = data->idToType.value(metaType.id());
if (type && type->listId.id() == id) if (type && type->listId == metaType)
return type->typeId; return type->typeId;
else else
return QMetaType {}; return QMetaType {};
@ -1132,26 +1131,17 @@ QMetaMethod QQmlMetaType::defaultMethod(QObject *obj)
/*! /*!
See qmlRegisterInterface() for information about when this will return true. See qmlRegisterInterface() for information about when this will return true.
*/ */
bool QQmlMetaType::isInterface(int userType) bool QQmlMetaType::isInterface(QMetaType type)
{ {
const QQmlMetaTypeDataPtr data; const QQmlMetaTypeDataPtr data;
return data->interfaces.contains(userType); return data->interfaces.contains(type.id());
} }
const char *QQmlMetaType::interfaceIId(int userType) const char *QQmlMetaType::interfaceIId(QMetaType metaType)
{ {
const QQmlMetaTypeDataPtr data;
QQmlTypePrivate *typePrivate = nullptr; const QQmlType type(data->idToType.value(metaType.id()));
{ return (type.isInterface() && type.typeId() == metaType) ? type.interfaceIId() : nullptr;
QQmlMetaTypeDataPtr data;
typePrivate = data->idToType.value(userType);
}
QQmlType type(typePrivate);
if (type.isInterface() && type.typeId().id() == userType)
return type.interfaceIId();
else
return nullptr;
} }
bool QQmlMetaType::isList(QMetaType type) bool QQmlMetaType::isList(QMetaType type)
@ -1200,8 +1190,8 @@ QQmlType QQmlMetaType::qmlType(const QHashedStringRef &name, const QHashedString
} }
/*! /*!
Returns the type (if any) that corresponds to the \a metaObject. Returns null if no Returns the type (if any) that corresponds to the \a metaObject. Returns an invalid type if no
type is registered. such type is registered.
*/ */
QQmlType QQmlMetaType::qmlType(const QMetaObject *metaObject) QQmlType QQmlMetaType::qmlType(const QMetaObject *metaObject)
{ {
@ -1231,26 +1221,29 @@ QQmlType QQmlMetaType::qmlType(const QMetaObject *metaObject, const QHashedStrin
} }
/*! /*!
Returns the type (if any) that corresponds to \a typeId. Depending on \a category, the Returns the type (if any) that corresponds to \a qmlTypeId.
\a typeId is interpreted either as QVariant::Type or as QML type id returned by one of the Returns an invalid QQmlType if no such type is registered.
qml type registration functions. Returns null if no type is registered.
*/ */
QQmlType QQmlMetaType::qmlType(int typeId, TypeIdCategory category) QQmlType QQmlMetaType::qmlTypeById(int qmlTypeId)
{ {
const QQmlMetaTypeDataPtr data; const QQmlMetaTypeDataPtr data;
QQmlType type = data->types.value(qmlTypeId);
if (category == TypeIdCategory::MetaType) { if (type.isValid())
QQmlTypePrivate *type = data->idToType.value(typeId); return type;
if (type && type->typeId.id() == typeId)
return QQmlType(type);
} else if (category == TypeIdCategory::QmlType) {
QQmlType type = data->types.value(typeId);
if (type.isValid())
return type;
}
return QQmlType(); return QQmlType();
} }
/*!
Returns the type (if any) that corresponds to \a metaType.
Returns an invalid QQmlType if no such type is registered.
*/
QQmlType QQmlMetaType::qmlType(QMetaType metaType)
{
const QQmlMetaTypeDataPtr data;
QQmlTypePrivate *type = data->idToType.value(metaType.id());
return (type && type->typeId == metaType) ? QQmlType(type) : QQmlType();
}
/*! /*!
Returns the type (if any) that corresponds to the given \a url in the set of Returns the type (if any) that corresponds to the given \a url in the set of
composite types added through file imports. composite types added through file imports.
@ -1491,7 +1484,7 @@ QString QQmlMetaType::prettyTypeName(const QObject *object)
marker = typeName.indexOf(QLatin1String("_QML_")); marker = typeName.indexOf(QLatin1String("_QML_"));
if (marker != -1) { if (marker != -1) {
typeName = QStringView{typeName}.left(marker) + QLatin1Char('*'); typeName = QStringView{typeName}.left(marker) + QLatin1Char('*');
type = QQmlMetaType::qmlType(QMetaType::fromName(typeName.toLatin1()).id()); type = QQmlMetaType::qmlType(QMetaType::fromName(typeName.toUtf8()));
if (type.isValid()) { if (type.isValid()) {
QString qmlTypeName = type.qmlTypeName(); QString qmlTypeName = type.qmlTypeName();
const int lastSlash = qmlTypeName.lastIndexOf(QLatin1Char('/')); const int lastSlash = qmlTypeName.lastIndexOf(QLatin1Char('/'));
@ -1580,8 +1573,7 @@ bool QQmlMetaType::isValueType(QMetaType type)
const QMetaObject *QQmlMetaType::metaObjectForValueType(QMetaType metaType) const QMetaObject *QQmlMetaType::metaObjectForValueType(QMetaType metaType)
{ {
const int t = metaType.id(); switch (metaType.id()) {
switch (t) {
case QMetaType::QPoint: case QMetaType::QPoint:
return &QQmlPointValueType::staticMetaObject; return &QQmlPointValueType::staticMetaObject;
case QMetaType::QPointF: case QMetaType::QPointF:
@ -1616,7 +1608,7 @@ const QMetaObject *QQmlMetaType::metaObjectForValueType(QMetaType metaType)
// call QObject pointers value types. Explicitly registered types also override // call QObject pointers value types. Explicitly registered types also override
// the implicit use of gadgets. // the implicit use of gadgets.
if (!(metaType.flags() & QMetaType::PointerToQObject)) { if (!(metaType.flags() & QMetaType::PointerToQObject)) {
const QQmlType qmlType = QQmlMetaType::qmlType(t, QQmlMetaType::TypeIdCategory::MetaType); const QQmlType qmlType = QQmlMetaType::qmlType(metaType);
// Prefer the extension meta object. // Prefer the extension meta object.
// Extensions allow registration of non-gadget value types. // Extensions allow registration of non-gadget value types.
@ -1636,16 +1628,15 @@ const QMetaObject *QQmlMetaType::metaObjectForValueType(QMetaType metaType)
QQmlValueType *QQmlMetaType::valueType(QMetaType type) QQmlValueType *QQmlMetaType::valueType(QMetaType type)
{ {
const int idx = type.id();
QQmlMetaTypeDataPtr data; QQmlMetaTypeDataPtr data;
const auto it = data->metaTypeToValueType.constFind(idx); const auto it = data->metaTypeToValueType.constFind(type.id());
if (it != data->metaTypeToValueType.constEnd()) if (it != data->metaTypeToValueType.constEnd())
return *it; return *it;
if (const QMetaObject *mo = metaObjectForValueType(type)) if (const QMetaObject *mo = metaObjectForValueType(type))
return *data->metaTypeToValueType.insert(idx, new QQmlValueType(idx, mo)); return *data->metaTypeToValueType.insert(type.id(), new QQmlValueType(type, mo));
return *data->metaTypeToValueType.insert(idx, nullptr); return *data->metaTypeToValueType.insert(type.id(), nullptr);
} }
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -164,16 +164,13 @@ public:
static QList<QQmlType> qmlSingletonTypes(); static QList<QQmlType> qmlSingletonTypes();
static QList<QQmlType> qmlAllTypes(); static QList<QQmlType> qmlAllTypes();
enum class TypeIdCategory {
MetaType,
QmlType
};
static QQmlType qmlType(const QString &qualifiedName, QTypeRevision version); static QQmlType qmlType(const QString &qualifiedName, QTypeRevision version);
static QQmlType qmlType(const QHashedStringRef &name, const QHashedStringRef &module, QTypeRevision version); static QQmlType qmlType(const QHashedStringRef &name, const QHashedStringRef &module, QTypeRevision version);
static QQmlType qmlType(const QMetaObject *); static QQmlType qmlType(const QMetaObject *);
static QQmlType qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, QTypeRevision version); static QQmlType qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, QTypeRevision version);
static QQmlType qmlType(int typeId, TypeIdCategory category = TypeIdCategory::MetaType); static QQmlType qmlTypeById(int qmlTypeId);
static QQmlType qmlType(QMetaType metaType);
static QQmlType qmlType(const QUrl &unNormalizedUrl, bool includeNonFileImports = false); static QQmlType qmlType(const QUrl &unNormalizedUrl, bool includeNonFileImports = false);
static QQmlPropertyCache *propertyCache(const QMetaObject *metaObject, static QQmlPropertyCache *propertyCache(const QMetaObject *metaObject,
@ -192,8 +189,8 @@ public:
static QMetaType listType(QMetaType type); static QMetaType listType(QMetaType type);
static QQmlAttachedPropertiesFunc attachedPropertiesFunc(QQmlEnginePrivate *, static QQmlAttachedPropertiesFunc attachedPropertiesFunc(QQmlEnginePrivate *,
const QMetaObject *); const QMetaObject *);
static bool isInterface(int); static bool isInterface(QMetaType type);
static const char *interfaceIId(int); static const char *interfaceIId(QMetaType type);
static bool isList(QMetaType type); static bool isList(QMetaType type);
static QTypeRevision latestModuleVersion(const QString &uri); static QTypeRevision latestModuleVersion(const QString &uri);

View File

@ -349,11 +349,11 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
QQmlPropertyData::WriteFlags propertyWriteFlags = QQmlPropertyData::BypassInterceptor | QQmlPropertyData::RemoveBindingOnAliasWrite; QQmlPropertyData::WriteFlags propertyWriteFlags = QQmlPropertyData::BypassInterceptor | QQmlPropertyData::RemoveBindingOnAliasWrite;
QV4::Scope scope(v4); QV4::Scope scope(v4);
int propertyType = property->propType().id(); QMetaType propertyType = property->propType();
if (property->isEnum()) { if (property->isEnum()) {
if (binding->flags & QV4::CompiledData::Binding::IsResolvedEnum) { if (binding->flags & QV4::CompiledData::Binding::IsResolvedEnum) {
propertyType = QMetaType::Int; propertyType = QMetaType::fromType<int>();
} else { } else {
// ### This should be resolved earlier at compile time and the binding value should be changed accordingly. // ### This should be resolved earlier at compile time and the binding value should be changed accordingly.
QVariant value = compilationUnit->bindingValueAsString(binding); QVariant value = compilationUnit->bindingValueAsString(binding);
@ -386,7 +386,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
} }
} }
switch (propertyType) { switch (propertyType.id()) {
case QMetaType::QVariant: { case QMetaType::QVariant: {
if (binding->type == QV4::CompiledData::Binding::Type_Number) { if (binding->type == QV4::CompiledData::Binding::Type_Number) {
double n = compilationUnit->bindingValueAsNumber(binding); double n = compilationUnit->bindingValueAsNumber(binding);
@ -488,7 +488,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
case QMetaType::QColor: { case QMetaType::QColor: {
QVariant data; QVariant data;
if (QQml_valueTypeProvider()->createValueType( if (QQml_valueTypeProvider()->createValueType(
QMetaType::QColor, compilationUnit->bindingValueAsString(binding), data)) { propertyType, compilationUnit->bindingValueAsString(binding), data)) {
property->writeProperty(_qobject, data.data(), propertyWriteFlags); property->writeProperty(_qobject, data.data(), propertyWriteFlags);
} }
} }
@ -579,37 +579,37 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
} }
default: { default: {
// generate single literal value assignment to a list property if required // generate single literal value assignment to a list property if required
if (propertyType == qMetaTypeId<QList<qreal> >()) { if (propertyType == QMetaType::fromType<QList<qreal>>()) {
assertType(QV4::CompiledData::Binding::Type_Number); assertType(QV4::CompiledData::Binding::Type_Number);
QList<qreal> value; QList<qreal> value;
value.append(compilationUnit->bindingValueAsNumber(binding)); value.append(compilationUnit->bindingValueAsNumber(binding));
property->writeProperty(_qobject, &value, propertyWriteFlags); property->writeProperty(_qobject, &value, propertyWriteFlags);
break; break;
} else if (propertyType == qMetaTypeId<QList<int> >()) { } else if (propertyType == QMetaType::fromType<QList<int>>()) {
assertType(QV4::CompiledData::Binding::Type_Number); assertType(QV4::CompiledData::Binding::Type_Number);
double n = compilationUnit->bindingValueAsNumber(binding); double n = compilationUnit->bindingValueAsNumber(binding);
QList<int> value; QList<int> value;
value.append(int(n)); value.append(int(n));
property->writeProperty(_qobject, &value, propertyWriteFlags); property->writeProperty(_qobject, &value, propertyWriteFlags);
break; break;
} else if (propertyType == qMetaTypeId<QList<bool> >()) { } else if (propertyType == QMetaType::fromType<QList<bool>>()) {
assertType(QV4::CompiledData::Binding::Type_Boolean); assertType(QV4::CompiledData::Binding::Type_Boolean);
QList<bool> value; QList<bool> value;
value.append(binding->valueAsBoolean()); value.append(binding->valueAsBoolean());
property->writeProperty(_qobject, &value, propertyWriteFlags); property->writeProperty(_qobject, &value, propertyWriteFlags);
break; break;
} else if (propertyType == qMetaTypeId<QList<QUrl> >()) { } else if (propertyType == QMetaType::fromType<QList<QUrl>>()) {
assertType(QV4::CompiledData::Binding::Type_String); assertType(QV4::CompiledData::Binding::Type_String);
QList<QUrl> value { QUrl(compilationUnit->bindingValueAsString(binding)) }; QList<QUrl> value { QUrl(compilationUnit->bindingValueAsString(binding)) };
property->writeProperty(_qobject, &value, propertyWriteFlags); property->writeProperty(_qobject, &value, propertyWriteFlags);
break; break;
} else if (propertyType == qMetaTypeId<QList<QString> >()) { } else if (propertyType == QMetaType::fromType<QList<QString>>()) {
assertOrNull(binding->evaluatesToString()); assertOrNull(binding->evaluatesToString());
QList<QString> value; QList<QString> value;
value.append(compilationUnit->bindingValueAsString(binding)); value.append(compilationUnit->bindingValueAsString(binding));
property->writeProperty(_qobject, &value, propertyWriteFlags); property->writeProperty(_qobject, &value, propertyWriteFlags);
break; break;
} else if (propertyType == qMetaTypeId<QJSValue>()) { } else if (propertyType == QMetaType::fromType<QJSValue>()) {
QJSValue value; QJSValue value;
if (binding->type == QV4::CompiledData::Binding::Type_Boolean) { if (binding->type == QV4::CompiledData::Binding::Type_Boolean) {
value = QJSValue(binding->valueAsBoolean()); value = QJSValue(binding->valueAsBoolean());
@ -1063,7 +1063,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper
int propertyWriteStatus = -1; int propertyWriteStatus = -1;
void *argv[] = { nullptr, nullptr, &propertyWriteStatus, &propertyWriteFlags }; void *argv[] = { nullptr, nullptr, &propertyWriteStatus, &propertyWriteFlags };
if (const char *iid = QQmlMetaType::interfaceIId(bindingProperty->propType().id())) { if (const char *iid = QQmlMetaType::interfaceIId(bindingProperty->propType())) {
void *ptr = createdSubObject->qt_metacast(iid); void *ptr = createdSubObject->qt_metacast(iid);
if (ptr) { if (ptr) {
argv[0] = &ptr; argv[0] = &ptr;
@ -1100,7 +1100,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper
QMetaType listItemType = QQmlMetaType::listType(bindingProperty->propType()); QMetaType listItemType = QQmlMetaType::listType(bindingProperty->propType());
if (listItemType.isValid()) { if (listItemType.isValid()) {
const char *iid = QQmlMetaType::interfaceIId(listItemType.id()); const char *iid = QQmlMetaType::interfaceIId(listItemType);
if (iid) if (iid)
itemToAdd = createdSubObject->qt_metacast(iid); itemToAdd = createdSubObject->qt_metacast(iid);
} }

View File

@ -1251,8 +1251,7 @@ bool QQmlPropertyPrivate::write(
const QQmlRefPointer<QQmlContextData> &context, QQmlPropertyData::WriteFlags flags) const QQmlRefPointer<QQmlContextData> &context, QQmlPropertyData::WriteFlags flags)
{ {
const QMetaType propertyMetaType = property.propType(); const QMetaType propertyMetaType = property.propType();
const int propertyType = propertyMetaType.id(); const QMetaType variantMetaType = value.metaType();
const int variantType = value.userType();
// we need to prevent new-style bindings from being removed // we need to prevent new-style bindings from being removed
QUntypedPropertyBinding untypedBinding; QUntypedPropertyBinding untypedBinding;
@ -1276,7 +1275,7 @@ bool QQmlPropertyPrivate::write(
QMetaProperty prop = object->metaObject()->property(property.coreIndex()); QMetaProperty prop = object->metaObject()->property(property.coreIndex());
QVariant v = value; QVariant v = value;
// Enum values come through the script engine as doubles // Enum values come through the script engine as doubles
if (variantType == QMetaType::Double) { if (variantMetaType == QMetaType::fromType<double>()) {
double integral; double integral;
double fractional = std::modf(value.toDouble(), &integral); double fractional = std::modf(value.toDouble(), &integral);
if (qFuzzyIsNull(fractional)) if (qFuzzyIsNull(fractional))
@ -1286,25 +1285,28 @@ bool QQmlPropertyPrivate::write(
} }
QQmlEnginePrivate *enginePriv = QQmlEnginePrivate::get(context); QQmlEnginePrivate *enginePriv = QQmlEnginePrivate::get(context);
const bool isUrl = propertyType == QMetaType::QUrl; // handled separately const bool isUrl = propertyMetaType == QMetaType::fromType<QUrl>(); // handled separately
// The cases below are in approximate order of likelyhood: // The cases below are in approximate order of likelyhood:
if (propertyType == variantType && !isUrl && propertyType != qMetaTypeId<QList<QUrl>>() && !property.isQList()) { if (propertyMetaType == variantMetaType && !isUrl
&& propertyMetaType != QMetaType::fromType<QList<QUrl>>() && !property.isQList()) {
return property.writeProperty(object, const_cast<void *>(value.constData()), flags); return property.writeProperty(object, const_cast<void *>(value.constData()), flags);
} else if (property.isQObject()) { } else if (property.isQObject()) {
QVariant val = value; QVariant val = value;
int varType = variantType; QMetaType varType;
if (variantType == QMetaType::Nullptr) { if (variantMetaType == QMetaType::fromType<std::nullptr_t>()) {
// This reflects the fact that you can assign a nullptr to a QObject pointer // This reflects the fact that you can assign a nullptr to a QObject pointer
// Without the change to QObjectStar, rawMetaObjectForType would not give us a QQmlMetaObject // Without the change to QObjectStar, rawMetaObjectForType would not give us a QQmlMetaObject
varType = QMetaType::QObjectStar; varType = QMetaType::fromType<QObject*>();
val = QVariant(QMetaType::fromType<QObject *>(), nullptr); val = QVariant(varType, nullptr);
} else {
varType = variantMetaType;
} }
QQmlMetaObject valMo = rawMetaObjectForType(enginePriv, varType); QQmlMetaObject valMo = rawMetaObjectForType(enginePriv, varType);
if (valMo.isNull()) if (valMo.isNull())
return false; return false;
QObject *o = *static_cast<QObject *const *>(val.constData()); QObject *o = *static_cast<QObject *const *>(val.constData());
QQmlMetaObject propMo = rawMetaObjectForType(enginePriv, propertyType); QQmlMetaObject propMo = rawMetaObjectForType(enginePriv, propertyMetaType);
if (o) if (o)
valMo = o; valMo = o;
@ -1320,10 +1322,10 @@ bool QQmlPropertyPrivate::write(
return false; return false;
} }
} else if (value.canConvert(propertyMetaType) } else if (value.canConvert(propertyMetaType)
&& !isUrl && variantType != QMetaType::QString && !isUrl && variantMetaType != QMetaType::fromType<QString>()
&& propertyType != qMetaTypeId<QList<QUrl>>() && !property.isQList()) { && propertyMetaType != QMetaType::fromType<QList<QUrl>>() && !property.isQList()) {
// common cases: // common cases:
switch (propertyType) { switch (propertyMetaType.id()) {
case QMetaType::Bool: { case QMetaType::Bool: {
bool b = value.toBool(); bool b = value.toBool();
return property.writeProperty(object, &b, flags); return property.writeProperty(object, &b, flags);
@ -1350,30 +1352,30 @@ bool QQmlPropertyPrivate::write(
return property.writeProperty(object, const_cast<void *>(v.constData()), flags); return property.writeProperty(object, const_cast<void *>(v.constData()), flags);
} }
} }
} else if (propertyType == qMetaTypeId<QVariant>()) { } else if (propertyMetaType == QMetaType::fromType<QVariant>()) {
return property.writeProperty(object, const_cast<QVariant *>(&value), flags); return property.writeProperty(object, const_cast<QVariant *>(&value), flags);
} else if (isUrl) { } else if (isUrl) {
QUrl u; QUrl u;
if (variantType == QMetaType::QUrl) if (variantMetaType == QMetaType::fromType<QUrl>())
u = value.toUrl(); u = value.toUrl();
else if (variantType == QMetaType::QByteArray) else if (variantMetaType == QMetaType::fromType<QByteArray>())
u = QUrl(QString::fromUtf8(value.toByteArray())); u = QUrl(QString::fromUtf8(value.toByteArray()));
else if (variantType == QMetaType::QString) else if (variantMetaType == QMetaType::fromType<QString>())
u = QUrl(value.toString()); u = QUrl(value.toString());
else else
return false; return false;
return property.writeProperty(object, &u, flags); return property.writeProperty(object, &u, flags);
} else if (propertyType == qMetaTypeId<QList<QUrl>>()) { } else if (propertyMetaType == QMetaType::fromType<QList<QUrl>>()) {
QList<QUrl> urlSeq = urlSequence(value).value<QList<QUrl>>(); QList<QUrl> urlSeq = urlSequence(value).value<QList<QUrl>>();
return property.writeProperty(object, &urlSeq, flags); return property.writeProperty(object, &urlSeq, flags);
} else if (property.isQList()) { } else if (property.isQList()) {
QQmlMetaObject listType; QQmlMetaObject listType;
if (enginePriv) { if (enginePriv) {
listType = enginePriv->rawMetaObjectForType(QQmlMetaType::listType(propertyMetaType).id()); listType = enginePriv->rawMetaObjectForType(QQmlMetaType::listType(propertyMetaType));
} else { } else {
QQmlType type = QQmlMetaType::qmlType(QQmlMetaType::listType(propertyMetaType).id()); const QQmlType type = QQmlMetaType::qmlType(QQmlMetaType::listType(propertyMetaType));
if (!type.isValid()) if (!type.isValid())
return false; return false;
listType = type.baseMetaObject(); listType = type.baseMetaObject();
@ -1389,7 +1391,7 @@ bool QQmlPropertyPrivate::write(
prop.clear(&prop); prop.clear(&prop);
if (variantType == qMetaTypeId<QQmlListReference>()) { if (variantMetaType == QMetaType::fromType<QQmlListReference>()) {
QQmlListReference qdlr = value.value<QQmlListReference>(); QQmlListReference qdlr = value.value<QQmlListReference>();
for (qsizetype ii = 0; ii < qdlr.count(); ++ii) { for (qsizetype ii = 0; ii < qdlr.count(); ++ii) {
@ -1398,7 +1400,7 @@ bool QQmlPropertyPrivate::write(
o = nullptr; o = nullptr;
prop.append(&prop, o); prop.append(&prop, o);
} }
} else if (variantType == qMetaTypeId<QList<QObject *> >()) { } else if (variantMetaType == QMetaType::fromType<QList<QObject *>>()) {
const QList<QObject *> &list = qvariant_cast<QList<QObject *> >(value); const QList<QObject *> &list = qvariant_cast<QList<QObject *> >(value);
for (qsizetype ii = 0; ii < list.count(); ++ii) { for (qsizetype ii = 0; ii < list.count(); ++ii) {
@ -1414,12 +1416,12 @@ bool QQmlPropertyPrivate::write(
prop.append(&prop, o); prop.append(&prop, o);
} }
} else { } else {
Q_ASSERT(variantType != propertyType); Q_ASSERT(variantMetaType != propertyMetaType);
bool ok = false; bool ok = false;
QVariant v; QVariant v;
if (variantType == QMetaType::QString) if (variantMetaType == QMetaType::fromType<QString>())
v = QQmlStringConverters::variantFromString(value.toString(), propertyType, &ok); v = QQmlStringConverters::variantFromString(value.toString(), propertyMetaType, &ok);
if (!ok) { if (!ok) {
v = value; v = value;
@ -1432,28 +1434,33 @@ bool QQmlPropertyPrivate::write(
// to a sequence type property (eg, an int to a QList<int> property). // to a sequence type property (eg, an int to a QList<int> property).
// or that we encountered an interface type // or that we encountered an interface type
// Note that we've already handled single-value assignment to QList<QUrl> properties. // Note that we've already handled single-value assignment to QList<QUrl> properties.
if (variantType == QMetaType::Int && propertyType == qMetaTypeId<QList<int> >()) { if (variantMetaType == QMetaType::fromType<int>()
&& propertyMetaType == QMetaType::fromType<QList<int>>()) {
QList<int> list; QList<int> list;
list << value.toInt(); list << value.toInt();
v = QVariant::fromValue<QList<int> >(list); v = QVariant::fromValue<QList<int> >(list);
ok = true; ok = true;
} else if ((variantType == QMetaType::Double || variantType == QMetaType::Int) } else if ((variantMetaType == QMetaType::fromType<double>()
&& (propertyType == qMetaTypeId<QList<qreal> >())) { || variantMetaType == QMetaType::fromType<int>())
&& (propertyMetaType == QMetaType::fromType<QList<qreal>>())) {
QList<qreal> list; QList<qreal> list;
list << value.toReal(); list << value.toReal();
v = QVariant::fromValue<QList<qreal> >(list); v = QVariant::fromValue<QList<qreal> >(list);
ok = true; ok = true;
} else if (variantType == QMetaType::Bool && propertyType == qMetaTypeId<QList<bool> >()) { } else if (variantMetaType == QMetaType::fromType<bool>()
&& propertyMetaType == QMetaType::fromType<QList<bool>>()) {
QList<bool> list; QList<bool> list;
list << value.toBool(); list << value.toBool();
v = QVariant::fromValue<QList<bool> >(list); v = QVariant::fromValue<QList<bool> >(list);
ok = true; ok = true;
} else if (variantType == QMetaType::QString && propertyType == qMetaTypeId<QList<QString> >()) { } else if (variantMetaType == QMetaType::fromType<QString>()
&& propertyMetaType == QMetaType::fromType<QList<QString>>()) {
QList<QString> list; QList<QString> list;
list << value.toString(); list << value.toString();
v = QVariant::fromValue<QList<QString> >(list); v = QVariant::fromValue<QList<QString> >(list);
ok = true; ok = true;
} else if (variantType == QMetaType::QString && propertyType == qMetaTypeId<QStringList>()) { } else if (variantMetaType == QMetaType::fromType<QString>()
&& propertyMetaType == QMetaType::fromType<QStringList>()) {
QStringList list; QStringList list;
list << value.toString(); list << value.toString();
v = QVariant::fromValue<QStringList>(list); v = QVariant::fromValue<QStringList>(list);
@ -1461,11 +1468,11 @@ bool QQmlPropertyPrivate::write(
} }
} }
if (!ok && QQmlMetaType::isInterface(propertyType)) { if (!ok && QQmlMetaType::isInterface(propertyMetaType)) {
auto valueAsQObject = qvariant_cast<QObject *>(value); auto valueAsQObject = qvariant_cast<QObject *>(value);
if (void *interface = valueAsQObject if (void *interface = valueAsQObject
? valueAsQObject->qt_metacast(QQmlMetaType::interfaceIId(propertyType)) ? valueAsQObject->qt_metacast(QQmlMetaType::interfaceIId(propertyMetaType))
: nullptr; : nullptr;
interface) { interface) {
// this case can occur when object has an interface type // this case can occur when object has an interface type
@ -1484,14 +1491,16 @@ bool QQmlPropertyPrivate::write(
return true; return true;
} }
QQmlMetaObject QQmlPropertyPrivate::rawMetaObjectForType(QQmlEnginePrivate *engine, int userType) QQmlMetaObject QQmlPropertyPrivate::rawMetaObjectForType(
QQmlEnginePrivate *engine, QMetaType metaType)
{ {
QMetaType metaType(userType); if (metaType.flags() & QMetaType::PointerToQObject) {
if ((metaType.flags() & QMetaType::PointerToQObject) && metaType.metaObject()) if (const QMetaObject *metaObject = metaType.metaObject())
return metaType.metaObject(); return metaObject;
}
if (engine) if (engine)
return engine->rawMetaObjectForType(userType); return engine->rawMetaObjectForType(metaType);
QQmlType type = QQmlMetaType::qmlType(userType); const QQmlType type = QQmlMetaType::qmlType(metaType);
if (type.isValid()) if (type.isValid())
return QQmlMetaObject(type.baseMetaObject()); return QQmlMetaObject(type.baseMetaObject());
return QQmlMetaObject(); return QQmlMetaObject();

View File

@ -102,7 +102,7 @@ public:
QVariant readValueProperty(); QVariant readValueProperty();
bool writeValueProperty(const QVariant &, QQmlPropertyData::WriteFlags); bool writeValueProperty(const QVariant &, QQmlPropertyData::WriteFlags);
static QQmlMetaObject rawMetaObjectForType(QQmlEnginePrivate *, int); static QQmlMetaObject rawMetaObjectForType(QQmlEnginePrivate *, QMetaType metaType);
static bool writeEnumProperty(const QMetaProperty &prop, int idx, QObject *object, static bool writeEnumProperty(const QMetaProperty &prop, int idx, QObject *object,
const QVariant &value, int flags); const QVariant &value, int flags);
static bool writeValueProperty(QObject *, static bool writeValueProperty(QObject *,

View File

@ -448,12 +448,12 @@ void QQmlPropertyBinding::bindingErrorCallback(QPropertyBindingPrivate *that)
QUntypedPropertyBinding QQmlTranslationPropertyBinding::create(const QQmlPropertyData *pd, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QV4::CompiledData::Binding *binding) QUntypedPropertyBinding QQmlTranslationPropertyBinding::create(const QQmlPropertyData *pd, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QV4::CompiledData::Binding *binding)
{ {
auto translationBinding = [compilationUnit, binding](const QMetaType &metaType, void *dataPtr) -> bool { auto translationBinding = [compilationUnit, binding](QMetaType metaType, void *dataPtr) -> bool {
// Create a dependency to the uiLanguage // Create a dependency to the uiLanguage
QJSEnginePrivate::get(compilationUnit->engine)->uiLanguage.value(); QJSEnginePrivate::get(compilationUnit->engine)->uiLanguage.value();
QVariant resultVariant(compilationUnit->bindingValueAsString(binding)); QVariant resultVariant(compilationUnit->bindingValueAsString(binding));
if (metaType.id() != QMetaType::QString) if (metaType != QMetaType::fromType<QString>())
resultVariant.convert(metaType); resultVariant.convert(metaType);
const bool hasChanged = !metaType.equals(resultVariant.constData(), dataPtr); const bool hasChanged = !metaType.equals(resultVariant.constData(), dataPtr);

View File

@ -130,7 +130,7 @@ QQmlRefPointer<QQmlPropertyCache> QQmlBindingInstantiationContext::instantiating
if (instantiatingProperty->isQObject()) { if (instantiatingProperty->isQObject()) {
// rawPropertyCacheForType assumes a given unspecified version means "any version". // rawPropertyCacheForType assumes a given unspecified version means "any version".
// There is another overload that takes no version, which we shall not use here. // There is another overload that takes no version, which we shall not use here.
return enginePrivate->rawPropertyCacheForType(instantiatingProperty->propType().id(), return enginePrivate->rawPropertyCacheForType(instantiatingProperty->propType(),
instantiatingProperty->typeVersion()); instantiatingProperty->typeVersion());
} else if (const QMetaObject *vtmo = QQmlMetaType::metaObjectForValueType(instantiatingProperty->propType())) { } else if (const QMetaObject *vtmo = QQmlMetaType::metaObjectForValueType(instantiatingProperty->propType())) {
return enginePrivate->cache(vtmo, instantiatingProperty->typeVersion()); return enginePrivate->cache(vtmo, instantiatingProperty->typeVersion());

View File

@ -919,7 +919,7 @@ inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataFor
if (!QQmlMetaType::isValueType(targetProperty->propType()) && valueTypeIndex != -1) { if (!QQmlMetaType::isValueType(targetProperty->propType()) && valueTypeIndex != -1) {
// deep alias property // deep alias property
*type = targetProperty->propType(); *type = targetProperty->propType();
targetCache = enginePriv->propertyCacheForType(type->id()); targetCache = enginePriv->propertyCacheForType(*type);
Q_ASSERT(targetCache); Q_ASSERT(targetCache);
targetProperty = targetCache->property(valueTypeIndex); targetProperty = targetCache->property(valueTypeIndex);

View File

@ -49,9 +49,9 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
static bool isPrimitiveType(int typeId) static bool isPrimitiveType(QMetaType metaType)
{ {
switch (typeId) { switch (metaType.id()) {
#define HANDLE_PRIMITIVE(Type, id, T) \ #define HANDLE_PRIMITIVE(Type, id, T) \
case QMetaType::Type: case QMetaType::Type:
QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(HANDLE_PRIMITIVE); QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(HANDLE_PRIMITIVE);
@ -309,21 +309,21 @@ QVector<QQmlError> QQmlPropertyValidator::validateObject(
return recordError(binding->location, tr("Invalid grouped property access")); return recordError(binding->location, tr("Invalid grouped property access"));
} }
} else { } else {
const int typeId = pd->propType().id(); const QMetaType type = pd->propType();
if (isPrimitiveType(typeId)) { if (isPrimitiveType(type)) {
return recordError( return recordError(
binding->location, binding->location,
tr("Invalid grouped property access: Property \"%1\" with primitive type \"%2\".") tr("Invalid grouped property access: Property \"%1\" with primitive type \"%2\".")
.arg(name) .arg(name)
.arg(QString::fromLatin1(QMetaType(typeId).name())) .arg(QString::fromUtf8(type.name()))
); );
} }
if (!enginePrivate->propertyCacheForType(typeId)) { if (!enginePrivate->propertyCacheForType(type)) {
return recordError(binding->location, return recordError(binding->location,
tr("Invalid grouped property access: Property \"%1\" with type \"%2\", which is not a value type") tr("Invalid grouped property access: Property \"%1\" with type \"%2\", which is not a value type")
.arg(name) .arg(name)
.arg(QString::fromLatin1(QMetaType(typeId).name())) .arg(QString::fromUtf8(type.name()))
); );
} }
} }
@ -586,7 +586,7 @@ QQmlError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache *prope
}; };
QVariant result; QVariant result;
if (!QQml_valueTypeProvider()->createValueType( if (!QQml_valueTypeProvider()->createValueType(
property->propType().id(), property->propType(),
compilationUnit->bindingValueAsString(binding), result)) { compilationUnit->bindingValueAsString(binding), result)) {
return warnOrError(tr("Invalid property assignment: %1 expected") return warnOrError(tr("Invalid property assignment: %1 expected")
.arg(typeName())); .arg(typeName()));
@ -647,7 +647,7 @@ QQmlError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache *prope
Returns true if from can be assigned to a (QObject) property of type Returns true if from can be assigned to a (QObject) property of type
to. to.
*/ */
bool QQmlPropertyValidator::canCoerce(int to, QQmlPropertyCache *fromMo) const bool QQmlPropertyValidator::canCoerce(QMetaType to, QQmlPropertyCache *fromMo) const
{ {
QQmlPropertyCache *toMo = enginePrivate->rawPropertyCacheForType(to); QQmlPropertyCache *toMo = enginePrivate->rawPropertyCacheForType(to);
@ -657,7 +657,7 @@ bool QQmlPropertyValidator::canCoerce(int to, QQmlPropertyCache *fromMo) const
// only occurs after the whole file has been validated // only occurs after the whole file has been validated
// Therefore we need to check the ICs here // Therefore we need to check the ICs here
for (const auto& icDatum : compilationUnit->inlineComponentData) { for (const auto& icDatum : compilationUnit->inlineComponentData) {
if (icDatum.typeIds.id.id() == to) { if (icDatum.typeIds.id == to) {
toMo = compilationUnit->propertyCaches.at(icDatum.objectIndex); toMo = compilationUnit->propertyCaches.at(icDatum.objectIndex);
break; break;
} }
@ -718,7 +718,7 @@ QQmlError QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *propert
return noError; return noError;
} }
const int propType = property->propType().id(); const QMetaType propType = property->propType();
const auto rhsType = [&]() { const auto rhsType = [&]() {
return stringAt(compilationUnit->objectAt(binding->value.objectIndex) return stringAt(compilationUnit->objectAt(binding->value.objectIndex)
->inheritedTypeNameIndex); ->inheritedTypeNameIndex);
@ -728,11 +728,12 @@ QQmlError QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *propert
// Can only check at instantiation time if the created sub-object successfully casts to the // Can only check at instantiation time if the created sub-object successfully casts to the
// target interface. // target interface.
return noError; return noError;
} else if (propType == QMetaType::QVariant || propType == qMetaTypeId<QJSValue>()) { } else if (propType == QMetaType::fromType<QVariant>()
|| propType == QMetaType::fromType<QJSValue>()) {
// We can convert everything to QVariant :) // We can convert everything to QVariant :)
return noError; return noError;
} else if (property->isQList()) { } else if (property->isQList()) {
const int listType = QQmlMetaType::listType(property->propType()).id(); const QMetaType listType = QQmlMetaType::listType(property->propType());
if (!QQmlMetaType::isInterface(listType)) { if (!QQmlMetaType::isInterface(listType)) {
QQmlPropertyCache *source = propertyCaches.at(binding->value.objectIndex); QQmlPropertyCache *source = propertyCaches.at(binding->value.objectIndex);
if (!canCoerce(listType, source)) { if (!canCoerce(listType, source)) {
@ -748,7 +749,7 @@ QQmlError QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *propert
.arg(rhsType()) .arg(rhsType())
.arg(propertyName) .arg(propertyName)
.arg(typeName)); .arg(typeName));
} else if (propType == qMetaTypeId<QQmlScriptString>()) { } else if (propType == QMetaType::fromType<QQmlScriptString>()) {
return qQmlCompileError(binding->valueLocation, tr("Invalid property assignment: script expected")); return qQmlCompileError(binding->valueLocation, tr("Invalid property assignment: script expected"));
} else if (QQmlMetaType::isValueType(property->propType())) { } else if (QQmlMetaType::isValueType(property->propType())) {
return qQmlCompileError(binding->location, tr("Cannot assign value of type \"%1\" to property \"%2\", expecting an object") return qQmlCompileError(binding->location, tr("Cannot assign value of type \"%1\" to property \"%2\", expecting an object")

View File

@ -79,7 +79,7 @@ private:
QQmlPropertyData *property, const QString &propertyName, QQmlPropertyData *property, const QString &propertyName,
const QV4::CompiledData::Binding *binding) const; const QV4::CompiledData::Binding *binding) const;
bool canCoerce(int to, QQmlPropertyCache *fromMo) const; bool canCoerce(QMetaType to, QQmlPropertyCache *fromMo) const;
Q_REQUIRED_RESULT QVector<QQmlError> recordError( Q_REQUIRED_RESULT QVector<QQmlError> recordError(
const QV4::CompiledData::Location &location, const QString &description) const; const QV4::CompiledData::Location &location, const QString &description) const;

View File

@ -48,9 +48,9 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
QVariant QQmlStringConverters::variantFromString(const QString &s, int preferredType, bool *ok) QVariant QQmlStringConverters::variantFromString(const QString &s, QMetaType preferredType, bool *ok)
{ {
switch (preferredType) { switch (preferredType.id()) {
case QMetaType::Int: case QMetaType::Int:
return QVariant(int(qRound(s.toDouble(ok)))); return QVariant(int(qRound(s.toDouble(ok))));
case QMetaType::UInt: case QMetaType::UInt:

View File

@ -66,7 +66,7 @@ class QByteArray;
namespace QQmlStringConverters namespace QQmlStringConverters
{ {
Q_QML_PRIVATE_EXPORT QVariant variantFromString(const QString &, int preferredType, bool *ok = nullptr); Q_QML_PRIVATE_EXPORT QVariant variantFromString(const QString &, QMetaType preferredType, bool *ok = nullptr);
Q_QML_PRIVATE_EXPORT QVariant colorFromString(const QString &, bool *ok = nullptr); Q_QML_PRIVATE_EXPORT QVariant colorFromString(const QString &, bool *ok = nullptr);
Q_QML_PRIVATE_EXPORT unsigned rgbaFromString(const QString &, bool *ok = nullptr); Q_QML_PRIVATE_EXPORT unsigned rgbaFromString(const QString &, bool *ok = nullptr);

View File

@ -807,8 +807,8 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI
// Otherwise, make sure we look up by metaobject. // Otherwise, make sure we look up by metaobject.
// TODO: Is this correct? // TODO: Is this correct?
QQmlPropertyCache *pc = pd->typeVersion().hasMinorVersion() QQmlPropertyCache *pc = pd->typeVersion().hasMinorVersion()
? enginePrivate->rawPropertyCacheForType(pd->propType().id(), pd->typeVersion()) ? enginePrivate->rawPropertyCacheForType(pd->propType(), pd->typeVersion())
: enginePrivate->rawPropertyCacheForType(pd->propType().id()); : enginePrivate->rawPropertyCacheForType(pd->propType());
const QMetaObject *mo = pc ? pc->firstCppMetaObject() : nullptr; const QMetaObject *mo = pc ? pc->firstCppMetaObject() : nullptr;
while (mo) { while (mo) {
if (mo == &QQmlComponent::staticMetaObject) if (mo == &QQmlComponent::staticMetaObject)

View File

@ -936,11 +936,11 @@ QQmlError QQmlTypeData::buildTypeResolutionCaches(
if (qmlType.isValid()) { if (qmlType.isValid()) {
// this is required for inline components in singletons // this is required for inline components in singletons
auto type = qmlType.lookupInlineComponentById(qmlType.inlineComponentId()).typeId(); auto type = qmlType.lookupInlineComponentById(qmlType.inlineComponentId()).typeId();
auto typeID = type.isValid() ? type.id() : -1; auto exUnit = engine->obtainExecutableCompilationUnit(
auto exUnit = engine->obtainExecutableCompilationUnit(typeID); type.isValid() ? type.id() : -1);
if (exUnit) { if (exUnit) {
ref->setCompilationUnit(exUnit); ref->setCompilationUnit(exUnit);
ref->setTypePropertyCache(engine->propertyCacheForType(typeID)); ref->setTypePropertyCache(engine->propertyCacheForType(type));
} }
} }
} else { } else {

View File

@ -412,9 +412,9 @@ ReturnedValue QQmlTypeWrapper::virtualInstanceOf(const Object *typeObject, const
QQmlRefPointer<QQmlTypeData> td = qenginepriv->typeLoader.getType(typeWrapper->d()->type().sourceUrl()); QQmlRefPointer<QQmlTypeData> td = qenginepriv->typeLoader.getType(typeWrapper->d()->type().sourceUrl());
ExecutableCompilationUnit *cu = td->compilationUnit(); ExecutableCompilationUnit *cu = td->compilationUnit();
myQmlType = qenginepriv->metaObjectForType(cu->typeIds.id.id()); myQmlType = qenginepriv->metaObjectForType(cu->typeIds.id);
} else { } else {
myQmlType = qenginepriv->metaObjectForType(myTypeId.id()); myQmlType = qenginepriv->metaObjectForType(myTypeId);
} }
const QMetaObject *theirType = wrapperObject->metaObject(); const QMetaObject *theirType = wrapperObject->metaObject();

View File

@ -47,8 +47,8 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
QQmlValueType::QQmlValueType(int typeId, const QMetaObject *gadgetMetaObject) QQmlValueType::QQmlValueType(QMetaType type, const QMetaObject *gadgetMetaObject)
: metaType(typeId) : metaType(type)
{ {
QMetaObjectBuilder builder(gadgetMetaObject); QMetaObjectBuilder builder(gadgetMetaObject);
dynamicMetaObject = builder.toMetaObject(); dynamicMetaObject = builder.toMetaObject();

View File

@ -71,7 +71,7 @@ class Q_QML_PRIVATE_EXPORT QQmlValueType : public QAbstractDynamicMetaObject
{ {
public: public:
QQmlValueType() : metaType(QMetaType::UnknownType) {} QQmlValueType() : metaType(QMetaType::UnknownType) {}
QQmlValueType(int userType, const QMetaObject *metaObject); QQmlValueType(QMetaType type, const QMetaObject *metaObject);
~QQmlValueType(); ~QQmlValueType();
void *create() const { return metaType.create(); } void *create() const { return metaType.create(); }

View File

@ -250,7 +250,7 @@ void QQmlVMEMetaObjectEndpoint::tryConnect()
if (pd && valueTypeIndex != -1 && !QQmlMetaType::valueType(pd->propType())) { if (pd && valueTypeIndex != -1 && !QQmlMetaType::valueType(pd->propType())) {
// deep alias // deep alias
QQmlEnginePrivate *enginePriv = QQmlEnginePrivate::get(metaObject->compilationUnit->engine->qmlEngine()); QQmlEnginePrivate *enginePriv = QQmlEnginePrivate::get(metaObject->compilationUnit->engine->qmlEngine());
auto const *newPropertyCache = enginePriv->propertyCacheForType(pd->propType().id()); auto const *newPropertyCache = enginePriv->propertyCacheForType(pd->propType());
void *argv[1] = { &target }; void *argv[1] = { &target };
QMetaObject::metacall(target, QMetaObject::ReadProperty, coreIndex, argv); QMetaObject::metacall(target, QMetaObject::ReadProperty, coreIndex, argv);
Q_ASSERT(newPropertyCache); Q_ASSERT(newPropertyCache);
@ -708,7 +708,8 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
? nullptr ? nullptr
: QQmlEnginePrivate::get(ctxt->engine()); : QQmlEnginePrivate::get(ctxt->engine());
const int fallbackMetaType = QQmlPropertyCacheCreatorBase::metaTypeForPropertyType(t).id(); const QMetaType fallbackMetaType
= QQmlPropertyCacheCreatorBase::metaTypeForPropertyType(t);
if (c == QMetaObject::ReadProperty) { if (c == QMetaObject::ReadProperty) {
switch (t) { switch (t) {
@ -750,12 +751,13 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
case QV4::CompiledData::BuiltinType::Vector4D: case QV4::CompiledData::BuiltinType::Vector4D:
case QV4::CompiledData::BuiltinType::Matrix4x4: case QV4::CompiledData::BuiltinType::Matrix4x4:
case QV4::CompiledData::BuiltinType::Quaternion: case QV4::CompiledData::BuiltinType::Quaternion:
Q_ASSERT(fallbackMetaType != QMetaType::UnknownType); Q_ASSERT(fallbackMetaType.isValid());
if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) { if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
QVariant propertyAsVariant; QVariant propertyAsVariant;
if (const QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>()) if (const QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>())
propertyAsVariant = v->d()->data(); propertyAsVariant = v->d()->data();
QQml_valueTypeProvider()->readValueType(propertyAsVariant, a[0], fallbackMetaType); QQml_valueTypeProvider()->readValueType(
fallbackMetaType, propertyAsVariant, a[0]);
} }
break; break;
case QV4::CompiledData::BuiltinType::Var: case QV4::CompiledData::BuiltinType::Var:
@ -855,7 +857,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
case QV4::CompiledData::BuiltinType::Vector4D: case QV4::CompiledData::BuiltinType::Vector4D:
case QV4::CompiledData::BuiltinType::Matrix4x4: case QV4::CompiledData::BuiltinType::Matrix4x4:
case QV4::CompiledData::BuiltinType::Quaternion: case QV4::CompiledData::BuiltinType::Quaternion:
Q_ASSERT(fallbackMetaType != QMetaType::UnknownType); Q_ASSERT(fallbackMetaType.isValid());
if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) { if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
const QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>(); const QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>();
if (!v) { if (!v) {

View File

@ -294,8 +294,10 @@ QVariant QtObject::font(const QJSValue &fontSpecifier) const
{ {
QVariant v; QVariant v;
if (QQml_valueTypeProvider()->createValueType(QMetaType::QFont, fontSpecifier, v)) if (QQml_valueTypeProvider()->createValueType(
QMetaType(QMetaType::QFont), fontSpecifier, v)) {
return v; return v;
}
} }
v4Engine()->throwError(QStringLiteral("Qt.font(): Invalid argument: " v4Engine()->throwError(QStringLiteral("Qt.font(): Invalid argument: "
@ -323,7 +325,7 @@ void addParameters(QJSEngine *e, QJSValue &result, int i, T parameter, Others...
} }
template<typename ...T> template<typename ...T>
static QVariant createValueType(QJSEngine *e, QMetaType::Type type, T... parameters) static QVariant createValueType(QJSEngine *e, QMetaType type, T... parameters)
{ {
if (!e) if (!e)
return QVariant(); return QVariant();
@ -341,7 +343,7 @@ static QVariant createValueType(QJSEngine *e, QMetaType::Type type, T... paramet
*/ */
QVariant QtObject::vector2d(double x, double y) const QVariant QtObject::vector2d(double x, double y) const
{ {
return createValueType(jsEngine(), QMetaType::QVector2D, x, y); return createValueType(jsEngine(), QMetaType(QMetaType::QVector2D), x, y);
} }
/*! /*!
@ -351,7 +353,7 @@ QVariant QtObject::vector2d(double x, double y) const
*/ */
QVariant QtObject::vector3d(double x, double y, double z) const QVariant QtObject::vector3d(double x, double y, double z) const
{ {
return createValueType(jsEngine(), QMetaType::QVector3D, x, y, z); return createValueType(jsEngine(), QMetaType(QMetaType::QVector3D), x, y, z);
} }
/*! /*!
@ -361,7 +363,7 @@ QVariant QtObject::vector3d(double x, double y, double z) const
*/ */
QVariant QtObject::vector4d(double x, double y, double z, double w) const QVariant QtObject::vector4d(double x, double y, double z, double w) const
{ {
return createValueType(jsEngine(), QMetaType::QVector4D, x, y, z, w); return createValueType(jsEngine(), QMetaType(QMetaType::QVector4D), x, y, z, w);
} }
/*! /*!
@ -371,7 +373,7 @@ QVariant QtObject::vector4d(double x, double y, double z, double w) const
*/ */
QVariant QtObject::quaternion(double scalar, double x, double y, double z) const QVariant QtObject::quaternion(double scalar, double x, double y, double z) const
{ {
return createValueType(jsEngine(), QMetaType::QQuaternion, scalar, x, y, z); return createValueType(jsEngine(), QMetaType(QMetaType::QQuaternion), scalar, x, y, z);
} }
/*! /*!
@ -398,7 +400,8 @@ QVariant QtObject::quaternion(double scalar, double x, double y, double z) const
QVariant QtObject::matrix4x4() const QVariant QtObject::matrix4x4() const
{ {
QVariant variant; QVariant variant;
QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, QJSValue(), variant); QQml_valueTypeProvider()->createValueType(
QMetaType(QMetaType::QMatrix4x4), QJSValue(), variant);
return variant; return variant;
} }
@ -406,7 +409,7 @@ QVariant QtObject::matrix4x4(const QJSValue &value) const
{ {
if (value.isObject()) { if (value.isObject()) {
QVariant v; QVariant v;
if (QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, value, v)) if (QQml_valueTypeProvider()->createValueType(QMetaType(QMetaType::QMatrix4x4), value, v))
return v; return v;
} }
@ -420,7 +423,7 @@ QVariant QtObject::matrix4x4(double m11, double m12, double m13, double m14,
double m31, double m32, double m33, double m34, double m31, double m32, double m33, double m34,
double m41, double m42, double m43, double m44) const double m41, double m42, double m43, double m44) const
{ {
return createValueType(jsEngine(), QMetaType::QMatrix4x4, return createValueType(jsEngine(), QMetaType(QMetaType::QMatrix4x4),
m11, m12, m13, m14, m21, m22, m23, m24, m11, m12, m13, m14, m21, m22, m23, m24,
m31, m32, m33, m34, m41, m42, m43, m44); m31, m32, m33, m34, m41, m42, m43, m44);
} }

View File

@ -435,7 +435,7 @@ ReturnedValue Serialize::deserialize(const char *&data, ExecutionEngine *engine)
array->arrayPut(ii, value); array->arrayPut(ii, value);
} }
array->setArrayLengthUnchecked(seqLength); array->setArrayLengthUnchecked(seqLength);
QVariant seqVariant = QV4::SequencePrototype::toVariant(array, sequenceType, &succeeded); QVariant seqVariant = QV4::SequencePrototype::toVariant(array, QMetaType(sequenceType), &succeeded);
return QV4::SequencePrototype::fromVariant(engine, seqVariant, &succeeded); return QV4::SequencePrototype::fromVariant(engine, seqVariant, &succeeded);
} }
#endif #endif

View File

@ -1978,7 +1978,7 @@ void QQuickPropertyAnimationPrivate::convertVariant(QVariant &variant, QMetaType
case QMetaType::QVector3D: case QMetaType::QVector3D:
{ {
bool ok = false; bool ok = false;
variant = QQmlStringConverters::variantFromString(variant.toString(), type.id(), &ok); variant = QQmlStringConverters::variantFromString(variant.toString(), type, &ok);
} }
break; break;
default: default:

View File

@ -160,14 +160,14 @@ void tst_qqmlmetatype::initTestCase()
void tst_qqmlmetatype::qmlParserStatusCast() void tst_qqmlmetatype::qmlParserStatusCast()
{ {
QVERIFY(!QQmlMetaType::qmlType(QMetaType::Int).isValid()); QVERIFY(!QQmlMetaType::qmlType(QMetaType::fromType<int>()).isValid());
QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).isValid()); QVERIFY(QQmlMetaType::qmlType(QMetaType::fromType<TestType *>()).isValid());
QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).parserStatusCast(), -1); QCOMPARE(QQmlMetaType::qmlType(QMetaType::fromType<TestType *>()).parserStatusCast(), -1);
QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ValueSourceTestType *>()).isValid()); QVERIFY(QQmlMetaType::qmlType(QMetaType::fromType<ValueSourceTestType *>()).isValid());
QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<ValueSourceTestType *>()).parserStatusCast(), -1); QCOMPARE(QQmlMetaType::qmlType(QMetaType::fromType<ValueSourceTestType *>()).parserStatusCast(), -1);
QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()).isValid()); QVERIFY(QQmlMetaType::qmlType(QMetaType::fromType<ParserStatusTestType *>()).isValid());
int cast = QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()).parserStatusCast(); int cast = QQmlMetaType::qmlType(QMetaType::fromType<ParserStatusTestType *>()).parserStatusCast();
QVERIFY(cast != -1); QVERIFY(cast != -1);
QVERIFY(cast != 0); QVERIFY(cast != 0);
@ -180,14 +180,14 @@ void tst_qqmlmetatype::qmlParserStatusCast()
void tst_qqmlmetatype::qmlPropertyValueSourceCast() void tst_qqmlmetatype::qmlPropertyValueSourceCast()
{ {
QVERIFY(!QQmlMetaType::qmlType(QMetaType::Int).isValid()); QVERIFY(!QQmlMetaType::qmlType(QMetaType::fromType<int>()).isValid());
QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).isValid()); QVERIFY(QQmlMetaType::qmlType(QMetaType::fromType<TestType *>()).isValid());
QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).propertyValueSourceCast(), -1); QCOMPARE(QQmlMetaType::qmlType(QMetaType::fromType<TestType *>()).propertyValueSourceCast(), -1);
QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()).isValid()); QVERIFY(QQmlMetaType::qmlType(QMetaType::fromType<ParserStatusTestType *>()).isValid());
QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()).propertyValueSourceCast(), -1); QCOMPARE(QQmlMetaType::qmlType(QMetaType::fromType<ParserStatusTestType *>()).propertyValueSourceCast(), -1);
QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ValueSourceTestType *>()).isValid()); QVERIFY(QQmlMetaType::qmlType(QMetaType::fromType<ValueSourceTestType *>()).isValid());
int cast = QQmlMetaType::qmlType(qMetaTypeId<ValueSourceTestType *>()).propertyValueSourceCast(); int cast = QQmlMetaType::qmlType(QMetaType::fromType<ValueSourceTestType *>()).propertyValueSourceCast();
QVERIFY(cast != -1); QVERIFY(cast != -1);
QVERIFY(cast != 0); QVERIFY(cast != 0);
@ -200,14 +200,14 @@ void tst_qqmlmetatype::qmlPropertyValueSourceCast()
void tst_qqmlmetatype::qmlPropertyValueInterceptorCast() void tst_qqmlmetatype::qmlPropertyValueInterceptorCast()
{ {
QVERIFY(!QQmlMetaType::qmlType(QMetaType::Int).isValid()); QVERIFY(!QQmlMetaType::qmlType(QMetaType::fromType<int>()).isValid());
QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).isValid()); QVERIFY(QQmlMetaType::qmlType(QMetaType::fromType<TestType *>()).isValid());
QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).propertyValueInterceptorCast(), -1); QCOMPARE(QQmlMetaType::qmlType(QMetaType::fromType<TestType *>()).propertyValueInterceptorCast(), -1);
QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()).isValid()); QVERIFY(QQmlMetaType::qmlType(QMetaType::fromType<ParserStatusTestType *>()).isValid());
QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()).propertyValueInterceptorCast(), -1); QCOMPARE(QQmlMetaType::qmlType(QMetaType::fromType<ParserStatusTestType *>()).propertyValueInterceptorCast(), -1);
QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ValueInterceptorTestType *>()).isValid()); QVERIFY(QQmlMetaType::qmlType(QMetaType::fromType<ValueInterceptorTestType *>()).isValid());
int cast = QQmlMetaType::qmlType(qMetaTypeId<ValueInterceptorTestType *>()).propertyValueInterceptorCast(); int cast = QQmlMetaType::qmlType(QMetaType::fromType<ValueInterceptorTestType *>()).propertyValueInterceptorCast();
QVERIFY(cast != -1); QVERIFY(cast != -1);
QVERIFY(cast != 0); QVERIFY(cast != 0);