moc: Fix related objects containing itself

This may happen when we have namespaces and the qualified name is used
to scope an enum.

Task-number: QTBUG-32933
Change-Id: Ic4923bbfb138387bae1e3694172661ace8342089
Reviewed-by: Alan Alpert <aalpert@blackberry.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Olivier Goffart 2013-08-21 11:29:14 +02:00 committed by The Qt Project
parent c20b358703
commit 2bd40c53ef
2 changed files with 40 additions and 2 deletions

View File

@ -184,6 +184,18 @@ bool Generator::registerableMetaType(const QByteArray &propertyType)
return false;
}
/* returns true if name and qualifiedName refers to the same name.
* If qualified name is "A::B::C", it returns true for "C", "B::C" or "A::B::C" */
static bool qualifiedNameEquals(const QByteArray &qualifiedName, const QByteArray &name)
{
if (qualifiedName == name)
return true;
int index = qualifiedName.indexOf("::");
if (index == -1)
return false;
return qualifiedNameEquals(qualifiedName.mid(index+2), name);
}
void Generator::generateCode()
{
bool isQt = (cdef->classname == "Qt");
@ -431,7 +443,7 @@ void Generator::generateCode()
int s = p.type.lastIndexOf("::");
if (s > 0) {
QByteArray scope = p.type.left(s);
if (scope != "Qt" && scope != cdef->classname && !extraList.contains(scope))
if (scope != "Qt" && !qualifiedNameEquals(cdef->qualified, scope) && !extraList.contains(scope))
extraList += scope;
}
}
@ -446,7 +458,7 @@ void Generator::generateCode()
int s = enumKey.lastIndexOf("::");
if (s > 0) {
QByteArray scope = enumKey.left(s);
if (scope != "Qt" && scope != cdef->classname && !extraList.contains(scope))
if (scope != "Qt" && !qualifiedNameEquals(cdef->qualified, scope) && !extraList.contains(scope))
extraList += scope;
}
}

View File

@ -565,6 +565,7 @@ private slots:
void parseDefines();
void preprocessorOnly();
void unterminatedFunctionMacro();
void QTBUG32933_relatedObjectsDontIncludeItself();
signals:
void sigWithUnsignedArg(unsigned foo);
@ -3005,6 +3006,31 @@ void tst_Moc::unterminatedFunctionMacro()
#endif
}
namespace QTBUG32933_relatedObjectsDontIncludeItself {
namespace NS {
class Obj : QObject {
Q_OBJECT
Q_PROPERTY(MyEnum p1 MEMBER member)
Q_PROPERTY(Obj::MyEnum p2 MEMBER member)
Q_PROPERTY(NS::Obj::MyEnum p3 MEMBER member)
Q_PROPERTY(QTBUG32933_relatedObjectsDontIncludeItself::NS::Obj::MyEnum p4 MEMBER member)
Q_ENUMS(MyEnum);
public:
enum MyEnum { Something, SomethingElse };
MyEnum member;
};
}
}
void tst_Moc::QTBUG32933_relatedObjectsDontIncludeItself()
{
const QMetaObject *mo = &QTBUG32933_relatedObjectsDontIncludeItself::NS::Obj::staticMetaObject;
const QMetaObject **objects = mo->d.relatedMetaObjects;
// the related objects should be empty because the enums is in the same object.
QVERIFY(!objects);
}
QTEST_MAIN(tst_Moc)
#include "tst_moc.moc"