diff options
-rw-r--r-- | src/qml/jsruntime/qv4qobjectwrapper.cpp | 13 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetaobject.cpp | 14 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetaobject_p.h | 5 | ||||
-rw-r--r-- | tests/auto/qml/qqmlecmascript/data/scriptConnect.7.qml | 11 | ||||
-rw-r--r-- | tests/auto/qml/qqmlecmascript/testtypes.cpp | 3 | ||||
-rw-r--r-- | tests/auto/qml/qqmlecmascript/testtypes.h | 14 | ||||
-rw-r--r-- | tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 8 |
7 files changed, 57 insertions, 11 deletions
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 98d69b2f80..1d3b12f083 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -939,15 +939,15 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase { QV4::PersistentValue function; QV4::PersistentValue thisObject; - int signalIndex; + QMetaMethod signal; QObjectSlotDispatcher() : QtPrivate::QSlotObjectBase(&impl) - , signalIndex(-1) {} - static void impl(int which, QSlotObjectBase *this_, QObject *r, void **metaArgs, bool *ret) + static void impl(int which, QSlotObjectBase *this_, QObject *receiver, void **metaArgs, bool *ret) { + Q_UNUSED(receiver); switch (which) { case Destroy: { delete static_cast<QObjectSlotDispatcher*>(this_); @@ -963,7 +963,7 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase break; QQmlMetaObject::ArgTypeStorage storage; - int *argsTypes = QQmlMetaObject(r).methodParameterTypes(This->signalIndex, &storage, nullptr); + int *argsTypes = QQmlMetaObject::methodParameterTypes(This->signal, &storage, nullptr); int argCount = argsTypes ? argsTypes[0]:0; @@ -1071,7 +1071,8 @@ ReturnedValue QObjectWrapper::method_connect(const FunctionObject *b, const Valu if (!signalObject) THROW_GENERIC_ERROR("Function.prototype.connect: cannot connect to deleted QObject"); - if (signalObject->metaObject()->method(signalIndex).methodType() != QMetaMethod::Signal) + auto signalMetaMethod = signalObject->metaObject()->method(signalIndex); + if (signalMetaMethod.methodType() != QMetaMethod::Signal) THROW_GENERIC_ERROR("Function.prototype.connect: this object is not a signal"); QV4::ScopedFunctionObject f(scope); @@ -1091,7 +1092,7 @@ ReturnedValue QObjectWrapper::method_connect(const FunctionObject *b, const Valu THROW_GENERIC_ERROR("Function.prototype.connect: target this is not an object"); QV4::QObjectSlotDispatcher *slot = new QV4::QObjectSlotDispatcher; - slot->signalIndex = signalIndex; + slot->signal = signalMetaMethod; slot->thisObject.set(scope.engine, object); slot->function.set(scope.engine, f); diff --git a/src/qml/qml/qqmlmetaobject.cpp b/src/qml/qml/qqmlmetaobject.cpp index 89c08f3841..b6454e083d 100644 --- a/src/qml/qml/qqmlmetaobject.cpp +++ b/src/qml/qml/qqmlmetaobject.cpp @@ -184,7 +184,7 @@ int *QQmlMetaObject::constructorParameterTypes(int index, ArgTypeStorage *dummy, } int *QQmlMetaObject::methodParameterTypes(const QMetaMethod &m, ArgTypeStorage *argStorage, - QByteArray *unknownTypeError) const + QByteArray *unknownTypeError) { Q_ASSERT(argStorage); @@ -203,7 +203,17 @@ int *QQmlMetaObject::methodParameterTypes(const QMetaMethod &m, ArgTypeStorage * } else { if (argTypeNames.isEmpty()) argTypeNames = m.parameterTypes(); - if (isNamedEnumerator(_m, argTypeNames.at(ii))) { + // hack only needed in Qt 6.1 to access the metaobject of the metamethod + // In 6.2 this method has been refactored and does not need acccess to the metaobject + union HackyAccessor { + HackyAccessor(QMetaMethod method) : m(method) {} + QMetaMethod m; + struct { + const QMetaObject *mobj = nullptr; + } accessor; + }; + HackyAccessor hack { m }; + if (isNamedEnumerator(hack.accessor.mobj, argTypeNames.at(ii))) { type = QMetaType::Int; } else if (type == QMetaType::UnknownType) { if (unknownTypeError) diff --git a/src/qml/qml/qqmlmetaobject_p.h b/src/qml/qml/qqmlmetaobject_p.h index a5b9b758a8..299218c10a 100644 --- a/src/qml/qml/qqmlmetaobject_p.h +++ b/src/qml/qml/qqmlmetaobject_p.h @@ -101,11 +101,10 @@ public: // we need a helper to find the correct meta object and property/method index. static void resolveGadgetMethodOrPropertyIndex(QMetaObject::Call type, const QMetaObject **metaObject, int *index); + static int *methodParameterTypes(const QMetaMethod &method, ArgTypeStorage *argStorage, + QByteArray *unknownTypeError); protected: const QMetaObject *_m = nullptr; - int *methodParameterTypes(const QMetaMethod &method, ArgTypeStorage *argStorage, - QByteArray *unknownTypeError) const; - }; QQmlMetaObject::QQmlMetaObject(const QObject *o) diff --git a/tests/auto/qml/qqmlecmascript/data/scriptConnect.7.qml b/tests/auto/qml/qqmlecmascript/data/scriptConnect.7.qml new file mode 100644 index 0000000000..9dab8d7815 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/scriptConnect.7.qml @@ -0,0 +1,11 @@ +import Qt.test +import QtQml + +QtObject { + readonly property Sender s: Sender {id: sender} + readonly property Receiver r: Receiver {id: receiver} + Component.onCompleted: () => { + sender.sig1.connect(receiver.slot1) + sender.sig1() + } +} diff --git a/tests/auto/qml/qqmlecmascript/testtypes.cpp b/tests/auto/qml/qqmlecmascript/testtypes.cpp index 688ed2c946..9b699f485b 100644 --- a/tests/auto/qml/qqmlecmascript/testtypes.cpp +++ b/tests/auto/qml/qqmlecmascript/testtypes.cpp @@ -556,6 +556,9 @@ void registerTypes() qmlRegisterType<ClassWithQProperty>("Qt.test", 1, 0, "ClassWithQProperty"); qmlRegisterType<ClassWithQProperty2>("Qt.test", 1, 0, "ClassWithQProperty2"); + + qmlRegisterType<Receiver>("Qt.test", 1,0, "Receiver"); + qmlRegisterType<Sender>("Qt.test", 1,0, "Sender"); } #include "testtypes.moc" diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h index 7074ffaa10..09c3fcaf40 100644 --- a/tests/auto/qml/qqmlecmascript/testtypes.h +++ b/tests/auto/qml/qqmlecmascript/testtypes.h @@ -1781,6 +1781,20 @@ public: // QNotifiedProperty<float, &ClassWithQProperty2::callback> value; }; +struct Sender : QObject +{ + Q_OBJECT +signals: + void sig1(); +}; + +struct Receiver : QObject +{ + Q_OBJECT +public slots: + int slot1(int i, int j, int k) {return i+j+k;} +}; + void registerTypes(); #endif // TESTTYPES_H diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 1ac1c04fd4..59f2b1ab88 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -3617,6 +3617,14 @@ void tst_qqmlecmascript::scriptConnect() delete object; } + + { + QRegularExpression msg {".*scriptConnect.7.qml:9: Error: Insufficient arguments"}; + QTest::ignoreMessage(QtMsgType::QtWarningMsg, msg); + QQmlComponent component(&engine, testFileUrl("scriptConnect.7.qml")); + QScopedPointer<QObject> root { component.create() }; + QVERIFY2(root, qPrintable(component.errorString())); + } } void tst_qqmlecmascript::scriptDisconnect() |