aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp13
-rw-r--r--src/qml/qml/qqmlmetaobject.cpp14
-rw-r--r--src/qml/qml/qqmlmetaobject_p.h5
-rw-r--r--tests/auto/qml/qqmlecmascript/data/scriptConnect.7.qml11
-rw-r--r--tests/auto/qml/qqmlecmascript/testtypes.cpp3
-rw-r--r--tests/auto/qml/qqmlecmascript/testtypes.h14
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp8
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()