aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml')
-rw-r--r--src/qml/qml/qqmlpropertycache.cpp112
1 files changed, 69 insertions, 43 deletions
diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp
index 0388215630..f91ba78932 100644
--- a/src/qml/qml/qqmlpropertycache.cpp
+++ b/src/qml/qml/qqmlpropertycache.cpp
@@ -889,28 +889,63 @@ struct StaticQtMetaObject : public QObject
{ return &staticQtMetaObject; }
};
-static int EnumType(const QMetaObject *metaobj, const QByteArray &str, int type)
+static bool isNamedEnumerator(const QMetaObject *metaObj, const QByteArray &scopedName)
{
QByteArray scope;
QByteArray name;
- int scopeIdx = str.lastIndexOf("::");
+ int scopeIdx = scopedName.lastIndexOf("::");
if (scopeIdx != -1) {
- scope = str.left(scopeIdx);
- name = str.mid(scopeIdx + 2);
+ scope = scopedName.left(scopeIdx);
+ name = scopedName.mid(scopeIdx + 2);
} else {
- name = str;
+ name = scopedName;
}
const QMetaObject *meta;
if (scope == "Qt")
meta = StaticQtMetaObject::get();
else
- meta = metaobj;
+ meta = metaObj;
for (int i = meta->enumeratorCount() - 1; i >= 0; --i) {
QMetaEnum m = meta->enumerator(i);
if ((m.name() == name) && (scope.isEmpty() || (m.scope() == scope)))
- return QVariant::Int;
+ return true;
}
- return type;
+ return false;
+}
+
+static bool passTypeAsInt(int type)
+{
+ // We should not encounter the unknown type here.
+ // In order to check that we need extra information.
+ Q_ASSERT(type != QMetaType::UnknownType);
+
+ const QMetaType::TypeFlags flags = QMetaType::typeFlags(type);
+
+ // Cast enumerations to int.
+ if (flags & QMetaType::IsEnumeration)
+ return true;
+
+ // Qt builtins can be handled as they are.
+ if (type < int(QMetaType::User))
+ return false;
+
+ // Pointers to QObjects and QGadgets can be handled as they are.
+ if (flags & (QMetaType::PointerToQObject | QMetaType::PointerToGadget))
+ return false;
+
+ // If it wasn't declared as metatype, better don't touch it.
+ if (!(flags & QMetaType::WasDeclaredAsMetaType))
+ return false;
+
+ // If it needs construction or destruction (that is, it is a structured type),
+ // pass as original type.
+ if (flags & (QMetaType::NeedsConstruction | QMetaType::NeedsDestruction))
+ return false;
+
+ // A single value that's not a pointer to a QObject or QGadget, not a builtin type, was declared
+ // as meta type, but we don't know it as an enumeration (although it probably is one).
+ // Pass as int if it fits into an int.
+ return QMetaType::sizeOf(type) <= int(sizeof(int));
}
QQmlPropertyCacheMethodArguments *QQmlPropertyCache::createArgumentsObject(int argc, const QList<QByteArray> &names)
@@ -1614,18 +1649,13 @@ int QQmlMetaObject::methodReturnType(const QQmlPropertyData &data, QByteArray *u
propTypeName = m.typeName();
}
- QMetaType::TypeFlags flags = QMetaType::typeFlags(type);
- if (flags & QMetaType::IsEnumeration) {
- type = QVariant::Int;
- } else if (type == QMetaType::UnknownType ||
- (type >= (int)QVariant::UserType && !(flags & QMetaType::PointerToQObject) &&
- type != qMetaTypeId<QJSValue>())) {
- //the UserType clause is to catch registered QFlags
- type = EnumType(metaObject(), propTypeName, type);
- }
-
if (type == QMetaType::UnknownType) {
- if (unknownTypeError) *unknownTypeError = propTypeName;
+ if (isNamedEnumerator(metaObject(), propTypeName))
+ type = QVariant::Int;
+ else if (unknownTypeError)
+ *unknownTypeError = propTypeName;
+ } else if (passTypeAsInt(type)) {
+ type = QVariant::Int;
}
return type;
@@ -1665,20 +1695,18 @@ int *QQmlMetaObject::methodParameterTypes(int index, ArgTypeStorage *argStorage,
for (int ii = 0; ii < argc; ++ii) {
int type = m.parameterType(ii);
- QMetaType::TypeFlags flags = QMetaType::typeFlags(type);
- if (flags & QMetaType::IsEnumeration)
- type = QVariant::Int;
- else if (type == QMetaType::UnknownType ||
- (type >= (int)QVariant::UserType && !(flags & QMetaType::PointerToQObject) &&
- type != qMetaTypeId<QJSValue>())) {
- //the UserType clause is to catch registered QFlags
+ if (type == QMetaType::UnknownType) {
if (argTypeNames.isEmpty())
argTypeNames = m.parameterTypes();
- type = EnumType(metaObject, argTypeNames.at(ii), type);
- }
- if (type == QMetaType::UnknownType) {
- if (unknownTypeError) *unknownTypeError = argTypeNames.at(ii);
- return nullptr;
+ if (isNamedEnumerator(metaObject, argTypeNames.at(ii))) {
+ type = QVariant::Int;
+ } else {
+ if (unknownTypeError)
+ *unknownTypeError = argTypeNames.at(ii);
+ return nullptr;
+ }
+ } else if (passTypeAsInt(type)) {
+ type = QVariant::Int;
}
args->arguments[ii + 1] = type;
}
@@ -1704,20 +1732,18 @@ int *QQmlMetaObject::methodParameterTypes(const QMetaMethod &m, ArgTypeStorage *
for (int ii = 0; ii < argc; ++ii) {
int type = m.parameterType(ii);
- QMetaType::TypeFlags flags = QMetaType::typeFlags(type);
- if (flags & QMetaType::IsEnumeration)
- type = QVariant::Int;
- else if (type == QMetaType::UnknownType ||
- (type >= (int)QVariant::UserType && !(flags & QMetaType::PointerToQObject) &&
- type != qMetaTypeId<QJSValue>())) {
- //the UserType clause is to catch registered QFlags)
+ if (type == QMetaType::UnknownType) {
if (argTypeNames.isEmpty())
argTypeNames = m.parameterTypes();
- type = EnumType(_m.asT2(), argTypeNames.at(ii), type);
- }
- if (type == QMetaType::UnknownType) {
- if (unknownTypeError) *unknownTypeError = argTypeNames.at(ii);
- return nullptr;
+ if (isNamedEnumerator(_m.asT2(), argTypeNames.at(ii))) {
+ type = QVariant::Int;
+ } else {
+ if (unknownTypeError)
+ *unknownTypeError = argTypeNames.at(ii);
+ return nullptr;
+ }
+ } else if (passTypeAsInt(type)) {
+ type = QVariant::Int;
}
argStorage->operator[](ii + 1) = type;
}