summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qmetaobject.cpp18
-rw-r--r--src/corelib/kernel/qmetaobject_p.h1
-rw-r--r--tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp39
3 files changed, 58 insertions, 0 deletions
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index fe6b4075ef..bdd2af1a2e 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -590,6 +590,24 @@ bool QMetaObjectPrivate::methodMatch(const QMetaObject *m, const QMetaMethod &me
return true;
}
+/*!
+ \internal
+ Returns the first method with name \a name found in \a baseObject
+ */
+QMetaMethod QMetaObjectPrivate::firstMethod(const QMetaObject *baseObject, QByteArrayView name)
+{
+ for (const QMetaObject *currentObject = baseObject; currentObject; currentObject = currentObject->superClass()) {
+ const int start = priv(currentObject->d.data)->methodCount - 1;
+ const int end = 0;
+ for (int i = start; i >= end; --i) {
+ auto candidate = QMetaMethod::fromRelativeMethodIndex(currentObject, i);
+ if (name == candidate.name())
+ return candidate;
+ }
+ }
+ return QMetaMethod{};
+}
+
/**
* \internal
* helper function for indexOf{Method,Slot,Signal}, returns the relative index of the method within
diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h
index efc1eafc8f..dbd82ba27b 100644
--- a/src/corelib/kernel/qmetaobject_p.h
+++ b/src/corelib/kernel/qmetaobject_p.h
@@ -253,6 +253,7 @@ struct QMetaObjectPrivate
static bool methodMatch(const QMetaObject *m, const QMetaMethod &method,
const QByteArray &name, int argc,
const QArgumentType *types);
+ Q_CORE_EXPORT static QMetaMethod firstMethod(const QMetaObject *baseObject, QByteArrayView name);
};
diff --git a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp
index dca4f0fea5..82d39cbbb3 100644
--- a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp
+++ b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp
@@ -321,6 +321,9 @@ private slots:
void indexOfMethod_data();
void indexOfMethod();
+ void firstMethod_data();
+ void firstMethod();
+
void indexOfMethodPMF();
void signalOffset_data();
@@ -1700,6 +1703,42 @@ void tst_QMetaObject::indexOfMethod()
QCOMPARE(object->metaObject()->indexOfSignal(name), !isSignal ? -1 : idx);
}
+class Base : public QObject {
+ Q_OBJECT
+public slots:
+ int test() {return 0;}
+ int baseOnly() {return 0;}
+};
+
+class Derived : public Base {
+ Q_OBJECT
+
+public slots:
+ int test() {return 1;}
+};
+
+void tst_QMetaObject::firstMethod_data()
+{
+ QTest::addColumn<QByteArray>("name");
+ QTest::addColumn<QMetaMethod>("method");
+
+ const QMetaObject &derived = Derived::staticMetaObject;
+ const QMetaObject &base = Base::staticMetaObject;
+
+ QTest::newRow("own method") << QByteArray("test") << derived.method(derived.indexOfMethod("test()"));
+ QTest::newRow("parent method") << QByteArray("baseOnly") << derived.method(base.indexOfMethod("baseOnly()"));
+ QTest::newRow("invalid") << QByteArray("invalid") << QMetaMethod();
+}
+
+void tst_QMetaObject::firstMethod()
+{
+ QFETCH(QByteArray, name);
+ QFETCH(QMetaMethod, method);
+
+ QMetaMethod firstMethod = QMetaObjectPrivate::firstMethod(&Derived::staticMetaObject, name);
+ QCOMPARE(firstMethod, method);
+}
+
void tst_QMetaObject::indexOfMethodPMF()
{
#define INDEXOFMETHODPMF_HELPER(ObjectType, Name, Arguments) { \