Move methodParameterTypes and methodReturnType helper functions
authorSimon Hausmann <simon.hausmann@theqtcompany.com>
Fri, 14 Nov 2014 20:39:08 +0000 (21:39 +0100)
committerSimon Hausmann <simon.hausmann@digia.com>
Tue, 23 Dec 2014 13:51:04 +0000 (14:51 +0100)
These can extract the type information from either a property cache (through
QQmlData from a QObject) or (fallback) from a QMetaObject.  The difference
between a QMetaObject and a QQmlPropertyCache is what QQmlMetaObject abstracts
and therefore we can move the functions there.  This is in preparation for
gadget support and also avoids the repeated QQmlData::get() dance but allows
the re-use of a QQmlMetaObject instance in the future to do that dance only
once.

Change-Id: Ibff6ce498d09fabc97e0801653edc5b1ff446c6a
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/qml/jsruntime/qv4qobjectwrapper.cpp
src/qml/qml/qqmlboundsignal.cpp
src/qml/qml/qqmlpropertycache.cpp
src/qml/qml/qqmlpropertycache_p.h

index 4b33ab3..04c6fc3 100644 (file)
@@ -796,7 +796,7 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase
                 break;
 
             QVarLengthArray<int, 9> dummy;
-            int *argsTypes = QQmlPropertyCache::methodParameterTypes(r, This->signalIndex, dummy, 0);
+            int *argsTypes = QQmlMetaObject(r).methodParameterTypes(This->signalIndex, dummy, 0);
 
             int argCount = argsTypes ? argsTypes[0]:0;
 
@@ -1370,7 +1370,7 @@ static QV4::ReturnedValue CallPrecise(QObject *object, const QQmlPropertyData &d
 {
     QByteArray unknownTypeError;
 
-    int returnType = QQmlPropertyCache::methodReturnType(object, data, &unknownTypeError);
+    int returnType = QQmlMetaObject(object).methodReturnType(data, &unknownTypeError);
 
     if (returnType == QMetaType::UnknownType) {
         QString typeName = QString::fromLatin1(unknownTypeError);
@@ -1383,8 +1383,7 @@ static QV4::ReturnedValue CallPrecise(QObject *object, const QQmlPropertyData &d
         int *args = 0;
         QVarLengthArray<int, 9> dummy;
 
-        args = QQmlPropertyCache::methodParameterTypes(object, data.coreIndex, dummy,
-                                                               &unknownTypeError);
+        args = QQmlMetaObject(object).methodParameterTypes(data.coreIndex, dummy, &unknownTypeError);
 
         if (!args) {
             QString typeName = QString::fromLatin1(unknownTypeError);
@@ -1439,8 +1438,7 @@ static QV4::ReturnedValue CallOverloaded(QObject *object, const QQmlPropertyData
         int methodArgumentCount = 0;
         int *methodArgTypes = 0;
         if (attempt->hasArguments()) {
-            typedef QQmlPropertyCache PC;
-            int *args = PC::methodParameterTypes(object, attempt->coreIndex, dummy, 0);
+            int *args = QQmlMetaObject(object).methodParameterTypes(attempt->coreIndex, dummy, 0);
             if (!args) // Must be an unknown argument
                 continue;
 
index cabb76d..f8718ad 100644 (file)
@@ -251,7 +251,7 @@ void QQmlBoundSignalExpression::evaluate(void **a)
         QVarLengthArray<int, 9> dummy;
         //TODO: lookup via signal index rather than method index as an optimization
         int methodIndex = QMetaObjectPrivate::signal(m_target->metaObject(), m_index).methodIndex();
-        int *argsTypes = QQmlPropertyCache::methodParameterTypes(m_target, methodIndex, dummy, 0);
+        int *argsTypes = QQmlMetaObject(m_target).methodParameterTypes(methodIndex, dummy, 0);
         int argCount = argsTypes ? *argsTypes : 0;
 
         QV4::ScopedValue f(scope, m_v8function.value());
index 535fb33..74a24f8 100644 (file)
@@ -1181,146 +1181,6 @@ QString QQmlPropertyCache::signalParameterStringForJS(QQmlEngine *engine, const
     return parameters;
 }
 
-// Returns an array of the arguments for method \a index.  The first entry in the array
-// is the number of arguments.
-int *QQmlPropertyCache::methodParameterTypes(QObject *object, int index,
-                                                     QVarLengthArray<int, 9> &dummy,
-                                                     QByteArray *unknownTypeError)
-{
-    Q_ASSERT(object && index >= 0);
-
-    QQmlData *ddata = QQmlData::get(object, false);
-
-    if (ddata && ddata->propertyCache) {
-        typedef QQmlPropertyCacheMethodArguments A;
-
-        QQmlPropertyCache *c = ddata->propertyCache;
-        Q_ASSERT(index < c->methodIndexCacheStart + c->methodIndexCache.count());
-
-        while (index < c->methodIndexCacheStart)
-            c = c->_parent;
-
-        QQmlPropertyData *rv = const_cast<QQmlPropertyData *>(&c->methodIndexCache.at(index - c->methodIndexCacheStart));
-
-        if (rv->arguments && static_cast<A *>(rv->arguments)->argumentsValid)
-            return static_cast<A *>(rv->arguments)->arguments;
-
-        const QMetaObject *metaObject = c->createMetaObject();
-        Q_ASSERT(metaObject);
-        QMetaMethod m = metaObject->method(index);
-
-        int argc = m.parameterCount();
-        if (!rv->arguments) {
-            A *args = c->createArgumentsObject(argc, m.parameterNames());
-            rv->arguments = args;
-        }
-        A *args = static_cast<A *>(rv->arguments);
-
-        QList<QByteArray> argTypeNames; // Only loaded if needed
-
-        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 (argTypeNames.isEmpty())
-                    argTypeNames = m.parameterTypes();
-                type = EnumType(object->metaObject(), argTypeNames.at(ii), type);
-            }
-            if (type == QMetaType::UnknownType) {
-                if (unknownTypeError) *unknownTypeError = argTypeNames.at(ii);
-                return 0;
-            }
-            args->arguments[ii + 1] = type;
-        }
-        args->argumentsValid = true;
-        return static_cast<A *>(rv->arguments)->arguments;
-
-    } else {
-        QMetaMethod m = object->metaObject()->method(index);
-        int argc = m.parameterCount();
-        dummy.resize(argc + 1);
-        dummy[0] = argc;
-        QList<QByteArray> argTypeNames; // Only loaded if needed
-
-        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 (argTypeNames.isEmpty())
-                    argTypeNames = m.parameterTypes();
-                type = EnumType(object->metaObject(), argTypeNames.at(ii), type);
-            }
-            if (type == QMetaType::UnknownType) {
-                if (unknownTypeError) *unknownTypeError = argTypeNames.at(ii);
-                return 0;
-            }
-            dummy[ii + 1] = type;
-        }
-
-        return dummy.data();
-    }
-}
-
-// Returns the return type of the method.
-int QQmlPropertyCache::methodReturnType(QObject *object, const QQmlPropertyData &data,
-                                        QByteArray *unknownTypeError)
-{
-    Q_ASSERT(object && data.coreIndex >= 0);
-
-    int type = data.propType;
-
-    const char *propTypeName = 0;
-
-    if (type == QMetaType::UnknownType) {
-        // Find the return type name from the method info
-        QMetaMethod m;
-
-        QQmlData *ddata = QQmlData::get(object, false);
-        if (ddata && ddata->propertyCache) {
-            QQmlPropertyCache *c = ddata->propertyCache;
-            Q_ASSERT(data.coreIndex < c->methodIndexCacheStart + c->methodIndexCache.count());
-
-            while (data.coreIndex < c->methodIndexCacheStart)
-                c = c->_parent;
-
-            const QMetaObject *metaObject = c->createMetaObject();
-            Q_ASSERT(metaObject);
-            m = metaObject->method(data.coreIndex);
-        } else {
-            m = object->metaObject()->method(data.coreIndex);
-        }
-
-        type = m.returnType();
-        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(object->metaObject(), propTypeName, type);
-    }
-
-    if (type == QMetaType::UnknownType) {
-        if (unknownTypeError) *unknownTypeError = propTypeName;
-    }
-
-    return type;
-}
-
 int QQmlPropertyCache::originalClone(int index)
 {
     while (signal(index)->isCloned())
@@ -1662,4 +1522,135 @@ QQmlPropertyCache *QQmlMetaObject::propertyCache(QQmlEnginePrivate *e) const
     else return e->cache(_m.asT2());
 }
 
+int QQmlMetaObject::methodReturnType(const QQmlPropertyData &data, QByteArray *unknownTypeError) const
+{
+    Q_ASSERT(!_m.isNull() && data.coreIndex >= 0);
+
+    int type = data.propType;
+
+    const char *propTypeName = 0;
+
+    if (type == QMetaType::UnknownType) {
+        // Find the return type name from the method info
+        QMetaMethod m;
+
+        if (_m.isT1()) {
+            QQmlPropertyCache *c = _m.asT1();
+            Q_ASSERT(data.coreIndex < c->methodIndexCacheStart + c->methodIndexCache.count());
+
+            while (data.coreIndex < c->methodIndexCacheStart)
+                c = c->_parent;
+
+            const QMetaObject *metaObject = c->createMetaObject();
+            Q_ASSERT(metaObject);
+            m = metaObject->method(data.coreIndex);
+        } else {
+            m = _m.asT2()->method(data.coreIndex);
+        }
+
+        type = m.returnType();
+        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;
+    }
+
+    return type;
+}
+
+int *QQmlMetaObject::methodParameterTypes(int index, QVarLengthArray<int, 9> &dummy, QByteArray *unknownTypeError) const
+{
+    Q_ASSERT(!_m.isNull() && index >= 0);
+
+    if (_m.isT1()) {
+        typedef QQmlPropertyCacheMethodArguments A;
+
+        QQmlPropertyCache *c = _m.asT1();
+        Q_ASSERT(index < c->methodIndexCacheStart + c->methodIndexCache.count());
+
+        while (index < c->methodIndexCacheStart)
+            c = c->_parent;
+
+        QQmlPropertyData *rv = const_cast<QQmlPropertyData *>(&c->methodIndexCache.at(index - c->methodIndexCacheStart));
+
+        if (rv->arguments && static_cast<A *>(rv->arguments)->argumentsValid)
+            return static_cast<A *>(rv->arguments)->arguments;
+
+        const QMetaObject *metaObject = c->createMetaObject();
+        Q_ASSERT(metaObject);
+        QMetaMethod m = metaObject->method(index);
+
+        int argc = m.parameterCount();
+        if (!rv->arguments) {
+            A *args = c->createArgumentsObject(argc, m.parameterNames());
+            rv->arguments = args;
+        }
+        A *args = static_cast<A *>(rv->arguments);
+
+        QList<QByteArray> argTypeNames; // Only loaded if needed
+
+        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 (argTypeNames.isEmpty())
+                    argTypeNames = m.parameterTypes();
+                type = EnumType(metaObject, argTypeNames.at(ii), type);
+            }
+            if (type == QMetaType::UnknownType) {
+                if (unknownTypeError) *unknownTypeError = argTypeNames.at(ii);
+                return 0;
+            }
+            args->arguments[ii + 1] = type;
+        }
+        args->argumentsValid = true;
+        return static_cast<A *>(rv->arguments)->arguments;
+
+    } else {
+        QMetaMethod m = _m.asT2()->method(index);
+        int argc = m.parameterCount();
+        dummy.resize(argc + 1);
+        dummy[0] = argc;
+        QList<QByteArray> argTypeNames; // Only loaded if needed
+
+        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 (argTypeNames.isEmpty())
+                    argTypeNames = m.parameterTypes();
+                type = EnumType(_m.asT2(), argTypeNames.at(ii), type);
+            }
+            if (type == QMetaType::UnknownType) {
+                if (unknownTypeError) *unknownTypeError = argTypeNames.at(ii);
+                return 0;
+            }
+            dummy[ii + 1] = type;
+        }
+
+        return dummy.data();
+    }
+}
+
 QT_END_NAMESPACE
index 524546e..82217f3 100644 (file)
@@ -305,10 +305,6 @@ public:
                                               QQmlContextData *, QQmlPropertyData &);
     static QQmlPropertyData *property(QQmlEngine *, QObject *, const QV4::String *,
                                               QQmlContextData *, QQmlPropertyData &);
-    static int *methodParameterTypes(QObject *, int index, QVarLengthArray<int, 9> &dummy,
-                                     QByteArray *unknownTypeError);
-    static int methodReturnType(QObject *, const QQmlPropertyData &data,
-                                QByteArray *unknownTypeError);
 
     //see QMetaObjectPrivate::originalClone
     int originalClone(int index);
@@ -340,6 +336,7 @@ private:
     friend class QQmlCompiler;
     friend class QQmlPropertyCacheCreator;
     friend class QQmlComponentAndAliasResolver;
+    friend class QQmlMetaObject;
 
     inline QQmlPropertyCache *copy(int reserve);
 
@@ -428,6 +425,9 @@ public:
 
     QQmlPropertyCache *propertyCache(QQmlEnginePrivate *) const;
 
+    int methodReturnType(const QQmlPropertyData &data, QByteArray *unknownTypeError) const;
+    int *methodParameterTypes(int index, QVarLengthArray<int, 9> &dummy, QByteArray *unknownTypeError) const;
+
     static bool canConvert(const QQmlMetaObject &from, const QQmlMetaObject &to);
 
 private: