aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2009-09-02 01:19:58 -0300
committerMarcelo Lira <marcelo.lira@openbossa.org>2009-09-02 01:19:58 -0300
commit9e00e39dca65935df280b35ccffce84287e1f4c4 (patch)
treeed25ef1b4ae606e5419894277ac61a721fc3ae84
parentfd761144e6ae4c24b3f77fae7047eaa26dbb8764 (diff)
- CppGenerator and HeaderGenerator modified to take classes with
private destructors into account - Removed ShibokenGenerator::canCreateWrapperFor(...) method - Minor improvements to ShibokenGenerator documentation - Expanded PrivateDtor case and added related unit test
-rw-r--r--cppgenerator.cpp9
-rw-r--r--headergenerator.cpp19
-rw-r--r--shibokengenerator.cpp5
-rw-r--r--shibokengenerator.h11
-rw-r--r--tests/libsample/privatedtor.h14
-rwxr-xr-xtests/samplebinding/privatedtor_test.py55
6 files changed, 85 insertions, 28 deletions
diff --git a/cppgenerator.cpp b/cppgenerator.cpp
index 874c72afa..4ffc72935 100644
--- a/cppgenerator.cpp
+++ b/cppgenerator.cpp
@@ -103,7 +103,7 @@ void CppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *metaCl
// write license comment
s << licenseComment() << endl;
- if (!metaClass->isNamespace()) {
+ if (!metaClass->isNamespace() && !metaClass->hasPrivateDestructor()) {
//workaround to access protected functions
s << "//workaround to access protected functions" << endl;
s << "#define protected public" << endl << endl;
@@ -136,12 +136,9 @@ void CppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *metaCl
if (metaClass->typeEntry()->typeFlags() & ComplexTypeEntry::Deprecated)
s << "#Deprecated" << endl;
- if (!canCreateWrapperFor(metaClass))
- return;
-
s << "using namespace Shiboken;" << endl << endl;
- if (!metaClass->isNamespace()) {
+ if (!metaClass->isNamespace() && !metaClass->hasPrivateDestructor()) {
s << "// Native ---------------------------------------------------------" << endl << endl;
//inject code native beginner
@@ -943,7 +940,7 @@ void CppGenerator::writeClassDefinition(QTextStream& s, const AbstractMetaClass*
else
baseClassName = QString("0");
- if (metaClass->isNamespace()) {
+ if (metaClass->isNamespace() || metaClass->hasPrivateDestructor()) {
tp_flags = QString("Py_TPFLAGS_HAVE_CLASS");
tp_new = QString("0");
tp_dealloc = QString("0");
diff --git a/headergenerator.cpp b/headergenerator.cpp
index 61358d16c..5c74a7a1e 100644
--- a/headergenerator.cpp
+++ b/headergenerator.cpp
@@ -59,7 +59,7 @@ void HeaderGenerator::generateClass(QTextStream& s, const AbstractMetaClass* met
s << "#ifndef " << wrapperName.toUpper() << "_H" << endl;
s << "#define " << wrapperName.toUpper() << "_H" << endl<< endl;
- if (!metaClass->isNamespace()) {
+ if (!metaClass->isNamespace() && !metaClass->hasPrivateDestructor()) {
s << "// The mother of all C++ binding hacks!" << endl;
s << "#define protected public" << endl << endl;
}
@@ -73,9 +73,7 @@ void HeaderGenerator::generateClass(QTextStream& s, const AbstractMetaClass* met
writeCodeSnips(s, metaClass->typeEntry()->codeSnips(),
CodeSnip::Declaration, TypeSystem::NativeCode);
- if (!metaClass->isNamespace()) {
- bool createWrapper = canCreateWrapperFor(metaClass);
-
+ if (!metaClass->isNamespace() && !metaClass->hasPrivateDestructor()) {
/*
* BOTOWTI (Beast of The Old World to be Investigated)
// detect the held type
@@ -92,8 +90,7 @@ void HeaderGenerator::generateClass(QTextStream& s, const AbstractMetaClass* met
// Class
s << "class SHIBOKEN_LOCAL " << wrapperName;
- if (createWrapper)
- s << " : public " << metaClass->qualifiedCppName();
+ s << " : public " << metaClass->qualifiedCppName();
s << endl << '{' << endl << "public:" << endl;
@@ -103,13 +100,11 @@ void HeaderGenerator::generateClass(QTextStream& s, const AbstractMetaClass* met
foreach (AbstractMetaFunction *func, filterFunctions(metaClass))
writeFunction(s, func);
- if (createWrapper) {
- //destructor
- s << INDENT << "~" << wrapperName << "();" << endl;
+ //destructor
+ s << INDENT << "~" << wrapperName << "();" << endl;
- if (metaClass->isQObject() && (metaClass->name() != "QObject"))
- s << INDENT << "using QObject::parent;" << endl;
- }
+ if (metaClass->isQObject() && (metaClass->name() != "QObject"))
+ s << INDENT << "using QObject::parent;" << endl;
writeCodeSnips(s, metaClass->typeEntry()->codeSnips(),
CodeSnip::PrototypeInitialization, TypeSystem::NativeCode);
diff --git a/shibokengenerator.cpp b/shibokengenerator.cpp
index d45308d01..50d233f8a 100644
--- a/shibokengenerator.cpp
+++ b/shibokengenerator.cpp
@@ -774,11 +774,6 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s,
}
}
-bool ShibokenGenerator::canCreateWrapperFor(const AbstractMetaClass* metaClass)
-{
- return !metaClass->hasPrivateDestructor();
-}
-
QStringList ShibokenGenerator::getBaseClasses(const AbstractMetaClass* metaClass)
{
QStringList baseClass;
diff --git a/shibokengenerator.h b/shibokengenerator.h
index a2aa2440f..02966d88b 100644
--- a/shibokengenerator.h
+++ b/shibokengenerator.h
@@ -91,11 +91,16 @@ public:
CodeSnip::Position position,
TypeSystem::Language language,
const AbstractMetaFunction* func = 0);
- /// returns the code snips of a function
+
+ /**
+ * Returns a function's code snippets.
+ * \param func the function from which retrieve the code snippets
+ * \return a list containing the function code snippets
+ */
CodeSnipList getCodeSnips(const AbstractMetaFunction* func);
- static bool canCreateWrapperFor(const AbstractMetaClass* metaClass);
+
/**
- * Function witch parse the metafunction information
+ * Function which parse the metafunction information
* \param func the function witch will be parserd
* \param option some extra options
* \param arg_count the number of function arguments
diff --git a/tests/libsample/privatedtor.h b/tests/libsample/privatedtor.h
index 9cc78ae8b..8e428292a 100644
--- a/tests/libsample/privatedtor.h
+++ b/tests/libsample/privatedtor.h
@@ -37,13 +37,23 @@
class PrivateDtor
{
- PrivateDtor* instance()
+public:
+ static PrivateDtor* instance()
{
static PrivateDtor self;
+ self.m_instanciations++;
return &self;
}
+
+ int instanceCalls()
+ {
+ return m_instanciations;
+ }
+
private:
- PrivateDtor() {}
+ int m_instanciations;
+
+ PrivateDtor() : m_instanciations(0) {}
PrivateDtor(const PrivateDtor&) {}
~PrivateDtor() {}
};
diff --git a/tests/samplebinding/privatedtor_test.py b/tests/samplebinding/privatedtor_test.py
new file mode 100755
index 000000000..7acabf039
--- /dev/null
+++ b/tests/samplebinding/privatedtor_test.py
@@ -0,0 +1,55 @@
+#!/usr/bin/python
+
+'''Test cases for a class with a private destructor.'''
+
+import gc
+import sys
+import unittest
+
+from sample import PrivateDtor
+
+
+class PrivateDtorTest(unittest.TestCase):
+ '''Test case for PrivateDtor class'''
+
+ def testPrivateDtorInstanciation(self):
+ '''Test if instanciation of class with a private destructor raises an exception.'''
+ self.assertRaises(TypeError, PrivateDtor)
+
+ def testPrivateDtorInheritance(self):
+ '''Test if inheriting from PrivateDtor raises an exception.'''
+ def inherit():
+ class Foo(PrivateDtor):
+ pass
+ self.assertRaises(TypeError, inherit)
+
+ def testPrivateDtorInstanceMethod(self):
+ '''Test if PrivateDtor.instance() method return the proper singleton.'''
+ pd1 = PrivateDtor.instance()
+ calls = pd1.instanceCalls()
+ self.assertEqual(type(pd1), PrivateDtor)
+ pd2 = PrivateDtor.instance()
+ self.assertEqual(pd2, pd1)
+ self.assertEqual(pd2.instanceCalls(), calls + 1)
+
+ def testPrivateDtorRefCounting(self):
+ '''Test refcounting of the singleton returned by PrivateDtor.instance().'''
+ pd1 = PrivateDtor.instance()
+ calls = pd1.instanceCalls()
+ refcnt = sys.getrefcount(pd1)
+ pd2 = PrivateDtor.instance()
+ self.assertEqual(pd2.instanceCalls(), calls + 1)
+ self.assertEqual(sys.getrefcount(pd2), sys.getrefcount(pd1))
+ self.assertEqual(sys.getrefcount(pd2), refcnt + 1)
+ del pd1
+ self.assertEqual(sys.getrefcount(pd2), refcnt)
+ del pd2
+ gc.collect()
+ pd3 = PrivateDtor.instance()
+ self.assertEqual(type(pd3), PrivateDtor)
+ self.assertEqual(pd3.instanceCalls(), calls + 2)
+ self.assertEqual(sys.getrefcount(pd3), refcnt)
+
+if __name__ == '__main__':
+ unittest.main()
+