aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlpropertycache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml/qqmlpropertycache.cpp')
-rw-r--r--src/qml/qml/qqmlpropertycache.cpp108
1 files changed, 50 insertions, 58 deletions
diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp
index 20d5c76029..73bfd7bbaa 100644
--- a/src/qml/qml/qqmlpropertycache.cpp
+++ b/src/qml/qml/qqmlpropertycache.cpp
@@ -898,6 +898,17 @@ struct StaticQtMetaObject : public QObject
{ return &staticQtMetaObject; }
};
+static bool isNamedEnumeratorInScope(const QMetaObject *resolvedMetaObject, const QByteArray &scope,
+ const QByteArray &name)
+{
+ for (int i = resolvedMetaObject->enumeratorCount() - 1; i >= 0; --i) {
+ QMetaEnum m = resolvedMetaObject->enumerator(i);
+ if ((m.name() == name) && (scope.isEmpty() || (m.scope() == scope)))
+ return true;
+ }
+ return false;
+}
+
static bool isNamedEnumerator(const QMetaObject *metaObj, const QByteArray &scopedName)
{
QByteArray scope;
@@ -909,52 +920,21 @@ static bool isNamedEnumerator(const QMetaObject *metaObj, const QByteArray &scop
} else {
name = scopedName;
}
- const QMetaObject *meta;
- if (scope == "Qt")
- meta = StaticQtMetaObject::get();
- else
- 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 true;
- }
- 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);
+ if (scope == "Qt")
+ return isNamedEnumeratorInScope(StaticQtMetaObject::get(), scope, name);
- // Cast enumerations to int.
- if (flags & QMetaType::IsEnumeration)
+ if (isNamedEnumeratorInScope(metaObj, scope, name))
return true;
- // Qt builtins can be handled as they are.
- if (type < int(QMetaType::User))
- return false;
-
- // Pointers to QObjects and QGadgets, and QGadgets themselves can be handled as they are.
- if (flags & (QMetaType::PointerToQObject | QMetaType::PointerToGadget | QMetaType::IsGadget))
- 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;
+ if (metaObj->d.relatedMetaObjects && !scope.isEmpty()) {
+ for (auto related = metaObj->d.relatedMetaObjects; *related; ++related) {
+ if (isNamedEnumeratorInScope(*related, scope, name))
+ return true;
+ }
+ }
- // 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));
+ return false;
}
QQmlPropertyCacheMethodArguments *QQmlPropertyCache::createArgumentsObject(int argc, const QList<QByteArray> &names)
@@ -1658,14 +1638,18 @@ int QQmlMetaObject::methodReturnType(const QQmlPropertyData &data, QByteArray *u
propTypeName = m.typeName();
}
- if (type == QMetaType::UnknownType) {
+ if (QMetaType::sizeOf(type) <= int(sizeof(int))) {
+ if (QMetaType::typeFlags(type) & QMetaType::IsEnumeration)
+ return QMetaType::Int;
+
if (isNamedEnumerator(metaObject(), propTypeName))
- type = QVariant::Int;
- else if (unknownTypeError)
- *unknownTypeError = propTypeName;
- } else if (passTypeAsInt(type)) {
- type = QVariant::Int;
- }
+ return QMetaType::Int;
+
+ if (type == QMetaType::UnknownType) {
+ if (unknownTypeError)
+ *unknownTypeError = propTypeName;
+ }
+ } // else we know that it's a known type, as sizeOf(UnknownType) == 0
return type;
}
@@ -1704,18 +1688,23 @@ int *QQmlMetaObject::methodParameterTypes(int index, ArgTypeStorage *argStorage,
for (int ii = 0; ii < argc; ++ii) {
int type = m.parameterType(ii);
- if (type == QMetaType::UnknownType) {
+
+ if (QMetaType::sizeOf(type) > int(sizeof(int))) {
+ // Cannot be passed as int
+ // We know that it's a known type, as sizeOf(UnknownType) == 0
+ } else if (QMetaType::typeFlags(type) & QMetaType::IsEnumeration) {
+ type = QMetaType::Int;
+ } else {
if (argTypeNames.isEmpty())
argTypeNames = m.parameterTypes();
if (isNamedEnumerator(metaObject, argTypeNames.at(ii))) {
- type = QVariant::Int;
- } else {
+ type = QMetaType::Int;
+ } else if (type == QMetaType::UnknownType){
if (unknownTypeError)
*unknownTypeError = argTypeNames.at(ii);
return nullptr;
}
- } else if (passTypeAsInt(type)) {
- type = QVariant::Int;
+
}
args->arguments[ii + 1] = type;
}
@@ -1741,18 +1730,21 @@ int *QQmlMetaObject::methodParameterTypes(const QMetaMethod &m, ArgTypeStorage *
for (int ii = 0; ii < argc; ++ii) {
int type = m.parameterType(ii);
- if (type == QMetaType::UnknownType) {
+ if (QMetaType::sizeOf(type) > int(sizeof(int))) {
+ // Cannot be passed as int
+ // We know that it's a known type, as sizeOf(UnknownType) == 0
+ } else if (QMetaType::typeFlags(type) & QMetaType::IsEnumeration) {
+ type = QMetaType::Int;
+ } else {
if (argTypeNames.isEmpty())
argTypeNames = m.parameterTypes();
if (isNamedEnumerator(_m.asT2(), argTypeNames.at(ii))) {
- type = QVariant::Int;
- } else {
+ type = QMetaType::Int;
+ } else if (type == QMetaType::UnknownType) {
if (unknownTypeError)
*unknownTypeError = argTypeNames.at(ii);
return nullptr;
}
- } else if (passTypeAsInt(type)) {
- type = QVariant::Int;
}
argStorage->operator[](ii + 1) = type;
}