summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2010-06-02 07:57:07 -0300
committerMarcelo Lira <marcelo.lira@openbossa.org>2010-06-02 15:41:07 -0300
commit7bc6f1512b1febc026d81917f33b1ea90d23fe24 (patch)
treec0328569c80bcd54022fbe3951802739deb580b0
parent47d4a1f545eb7f348e46d39230a73a1b465e57a4 (diff)
downloadshiboken-7bc6f1512b1febc026d81917f33b1ea90d23fe24.tar.gz
shiboken-7bc6f1512b1febc026d81917f33b1ea90d23fe24.tar.xz
shiboken-7bc6f1512b1febc026d81917f33b1ea90d23fe24.zip
Fixes code generation for classes with private destructors.
This fix is specific for the cases when the "protected hack" is turned off. Also added some tests.
-rw-r--r--cppgenerator.cpp14
-rw-r--r--headergenerator.cpp24
-rw-r--r--shibokengenerator.cpp19
-rw-r--r--tests/libsample/privatedtor.h3
-rwxr-xr-xtests/samplebinding/protected_test.py17
5 files changed, 71 insertions, 6 deletions
diff --git a/cppgenerator.cpp b/cppgenerator.cpp
index e2351094..c2fc670f 100644
--- a/cppgenerator.cpp
+++ b/cppgenerator.cpp
@@ -194,15 +194,27 @@ void CppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *metaCl
continue;
if (func->isConstructor() && !func->isCopyConstructor() && !func->isUserAdded())
writeConstructorNative(s, func);
+#ifdef AVOID_PROTECTED_HACK
+ else if (!metaClass->hasPrivateDestructor() && (func->isVirtual() || func->isAbstract()))
+#else
else if (func->isVirtual() || func->isAbstract())
+#endif
writeVirtualMethodNative(s, func);
}
+#ifdef AVOID_PROTECTED_HACK
+ if (!metaClass->hasPrivateDestructor()) {
+#endif
+
if (usePySideExtensions() && metaClass->isQObject())
writeMetaObjectMethod(s, metaClass);
writeDestructorNative(s, metaClass);
+#ifdef AVOID_PROTECTED_HACK
+ }
+#endif
+
s << endl << "// Target ---------------------------------------------------------" << endl;
s << endl;
}
@@ -390,7 +402,7 @@ void CppGenerator::writeDestructorNative(QTextStream &s, const AbstractMetaClass
void CppGenerator::writeVirtualMethodNative(QTextStream &s, const AbstractMetaFunction* func)
{
- //skip metaObject function, this will be write manually ahead
+ //skip metaObject function, this will be written manually ahead
if (usePySideExtensions() && func->ownerClass() && func->ownerClass()->isQObject() &&
((func->name() == "metaObject") || (func->name() == "qt_metacall")))
return;
diff --git a/headergenerator.cpp b/headergenerator.cpp
index ca6b5daf..f43fc2cd 100644
--- a/headergenerator.cpp
+++ b/headergenerator.cpp
@@ -91,10 +91,17 @@ void HeaderGenerator::generateClass(QTextStream& s, const AbstractMetaClass* met
}
//destructor
- s << INDENT << (metaClass->hasVirtualDestructor() || hasVirtualFunction ? "virtual " : "") << "~" << wrapperName << "();" << endl;
+#ifdef AVOID_PROTECTED_HACK
+ if (!metaClass->hasPrivateDestructor())
+#endif
+ s << INDENT << (metaClass->hasVirtualDestructor() || hasVirtualFunction ? "virtual " : "") << "~" << wrapperName << "();" << endl;
writeCodeSnips(s, metaClass->typeEntry()->codeSnips(), CodeSnip::Declaration, TypeSystem::NativeCode);
+#ifdef AVOID_PROTECTED_HACK
+ if (!metaClass->hasPrivateDestructor()) {
+#endif
+
if (usePySideExtensions() && metaClass->isQObject()) {
s << "public:\n";
s << INDENT << "virtual int qt_metacall(QMetaObject::Call call, int id, void** args);\n";
@@ -102,6 +109,10 @@ void HeaderGenerator::generateClass(QTextStream& s, const AbstractMetaClass* met
s << INDENT << "mutable PySide::DynamicQMetaObject* m_metaObject;\n";
}
+#ifdef AVOID_PROTECTED_HACK
+ }
+#endif
+
s << "};" << endl << endl;
}
@@ -118,10 +129,12 @@ void HeaderGenerator::writeFunction(QTextStream& s, const AbstractMetaFunction*
return;
#ifdef AVOID_PROTECTED_HACK
- if (func->isProtected() && !func->isConstructor()) {
+ if (func->isProtected() && !func->isConstructor() && !func->isOperatorOverload()) {
s << INDENT << "inline " << (func->isStatic() ? "static " : "");
s << functionSignature(func, "", "_protected", Generator::EnumAsInts|Generator::OriginalTypeDescription) << " { ";
- s << (func->type() ? "return " : "") << func->ownerClass()->qualifiedCppName() << "::";
+ s << (func->type() ? "return " : "");
+ if (!func->isAbstract())
+ s << func->ownerClass()->qualifiedCppName() << "::";
s << func->originalName() << '(';
QStringList args;
foreach (const AbstractMetaArgument* arg, func->arguments()) {
@@ -144,6 +157,11 @@ void HeaderGenerator::writeFunction(QTextStream& s, const AbstractMetaFunction*
if (func->isPrivate() || (func->isModifiedRemoved() && !func->isAbstract()))
return;
+#ifdef AVOID_PROTECTED_HACK
+ if (func->ownerClass()->hasPrivateDestructor() && (func->isAbstract() || func->isVirtual()))
+ return;
+#endif
+
if (func->isConstructor() || func->isAbstract() || func->isVirtual()) {
s << INDENT;
Options virtualOption = Generator::NoOption;
diff --git a/shibokengenerator.cpp b/shibokengenerator.cpp
index 5b85ef43..16a216da 100644
--- a/shibokengenerator.cpp
+++ b/shibokengenerator.cpp
@@ -178,9 +178,24 @@ bool ShibokenGenerator::shouldGenerateCppWrapper(const AbstractMetaClass* metaCl
{
bool result = metaClass->isPolymorphic() || metaClass->hasVirtualDestructor();
#ifdef AVOID_PROTECTED_HACK
- result = result || metaClass->hasProtectedFunctions() || metaClass->hasProtectedDestructor();
+ result = result || metaClass->hasProtectedFields() || metaClass->hasProtectedDestructor();
+ if (!result && metaClass->hasProtectedFunctions()) {
+ int protectedFunctions = 0;
+ int protectedOperators = 0;
+ foreach (const AbstractMetaFunction* func, metaClass->functions()) {
+ if (!func->isProtected() || func->isSignal() || func->isModifiedRemoved())
+ continue;
+ else if (func->isOperatorOverload())
+ protectedOperators++;
+ else
+ protectedFunctions++;
+ }
+ result = result || (protectedFunctions > protectedOperators);
+ }
+#else
+ result = result && !metaClass->hasPrivateDestructor();
#endif
- return result && !metaClass->isNamespace() && !metaClass->hasPrivateDestructor();
+ return result && !metaClass->isNamespace();
}
QString ShibokenGenerator::wrapperName(const AbstractMetaClass* metaClass)
diff --git a/tests/libsample/privatedtor.h b/tests/libsample/privatedtor.h
index 2c206b26..73f7f4d8 100644
--- a/tests/libsample/privatedtor.h
+++ b/tests/libsample/privatedtor.h
@@ -52,6 +52,9 @@ public:
return m_instanciations;
}
+protected:
+ int protectedInstanceCalls() { return m_instanciations; }
+
private:
int m_instanciations;
diff --git a/tests/samplebinding/protected_test.py b/tests/samplebinding/protected_test.py
index efb0bedb..fa477c42 100755
--- a/tests/samplebinding/protected_test.py
+++ b/tests/samplebinding/protected_test.py
@@ -31,6 +31,7 @@ import unittest
from sample import ProtectedNonPolymorphic, ProtectedVirtualDestructor
from sample import ProtectedPolymorphic, ProtectedPolymorphicDaughter, ProtectedPolymorphicGrandDaughter
from sample import ProtectedEnumClass
+from sample import PrivateDtor
from sample import Point
class ExtendedProtectedPolymorphic(ProtectedPolymorphic):
@@ -242,6 +243,22 @@ class ProtectedEnumTest(unittest.TestCase):
self.assertEqual(obj.callPublicEnumMethod(ProtectedEnumClass.PublicItem1), ProtectedEnumClass.PublicItem0)
+class PrivateDtorProtectedMethodTest(unittest.TestCase):
+ '''Test cases for classes with private destructors and protected methods.'''
+
+ def testProtectedMethod(self):
+ '''Calls protected method of a class with a private destructor.'''
+ obj = PrivateDtor.instance()
+
+ self.assertEqual(type(obj), PrivateDtor)
+ self.assertEqual(obj.instanceCalls(), 1)
+ self.assertEqual(obj.instanceCalls(), obj.protectedInstanceCalls())
+
+ obj = PrivateDtor.instance()
+ self.assertEqual(obj.instanceCalls(), 2)
+ self.assertEqual(obj.instanceCalls(), obj.protectedInstanceCalls())
+
+
if __name__ == '__main__':
unittest.main()