diff options
author | Marcelo Lira <marcelo.lira@openbossa.org> | 2011-08-01 19:03:26 -0300 |
---|---|---|
committer | Hugo Parente Lima <hugo.pl@gmail.com> | 2012-03-08 16:17:07 -0300 |
commit | cfcae8d657cb7d13acf2de753bd0e6db117e27f7 (patch) | |
tree | 5c808a8bec68dd12606598a2ad66c3feab11c376 | |
parent | 22c7b2e24212b41fc941121f8df83eb238f8e0d3 (diff) |
Improved and fixed the setter and getter writer functions.
Also added an unit test to a protected container property.
-rw-r--r-- | generator/cppgenerator.cpp | 84 | ||||
-rw-r--r-- | tests/libsample/protected.h | 3 | ||||
-rw-r--r-- | tests/samplebinding/protected_test.py | 6 |
3 files changed, 46 insertions, 47 deletions
diff --git a/generator/cppgenerator.cpp b/generator/cppgenerator.cpp index e3a7cb3d1..5958e1583 100644 --- a/generator/cppgenerator.cpp +++ b/generator/cppgenerator.cpp @@ -2877,42 +2877,37 @@ void CppGenerator::writeGetterFunction(QTextStream& s, const AbstractMetaField* s << "static PyObject* " << cpythonGetterFunctionName(metaField) << "(PyObject* " PYTHON_SELF_VAR ", void*)" << endl; s << '{' << endl; - writeInvalidPyObjectCheck(s, PYTHON_SELF_VAR); - - s << INDENT << "PyObject* val = "; + writeCppSelfDefinition(s, metaField->enclosingClass()); - QString cppField; - AbstractMetaType *metaType = metaField->type(); + AbstractMetaType* fieldType = metaField->type(); // Force use of pointer to return internal variable memory - bool useReference = (!metaType->isConstant() && - !metaType->isEnum() && - !metaType->isFlags() && - !metaType->isPrimitive() && - metaType->indirections() == 0); + bool newWrapperSameObject = !fieldType->isConstant() && isWrapperType(fieldType) && !isPointer(fieldType); + QString cppField; if (avoidProtectedHack() && metaField->isProtected()) { - cppField = QString("((%1*)%2)->%3()") - .arg(wrapperName(metaField->enclosingClass())) - .arg(cpythonWrapperCPtr(metaField->enclosingClass(), PYTHON_SELF_VAR)) - .arg(protectedFieldGetterName(metaField)); + cppField = QString("((%1*)%2)->%3()").arg(wrapperName(metaField->enclosingClass())) + .arg(CPP_SELF_VAR) + .arg(protectedFieldGetterName(metaField)); } else { - cppField = QString("%1%2->%3") - .arg(useReference ? '&' : ' ') - .arg(cpythonWrapperCPtr(metaField->enclosingClass(), PYTHON_SELF_VAR)) - .arg(metaField->name()); + cppField = QString("%2->%3").arg(CPP_SELF_VAR).arg(metaField->name()); + if (newWrapperSameObject) { + cppField.prepend("&("); + cppField.append(')'); + } } - if (useReference) { - s << "Shiboken::createWrapper(" << cppField << ");" << endl; - s << INDENT << "Shiboken::Object::releaseOwnership(val);" << endl; - s << INDENT << "Shiboken::Object::setParent(" PYTHON_SELF_VAR ", val);" << endl; + s << INDENT << "PyObject* value = "; + if (newWrapperSameObject) { + s << "Shiboken::Object::newObject((SbkObjectType*)" << cpythonTypeNameExt(fieldType->typeEntry()); + s << ", " << cppField << ", false, true);" << endl; + s << INDENT << "Shiboken::Object::setParent(" PYTHON_SELF_VAR ", value)"; } else { - writeToPythonConversion(s, metaField->type(), metaField->enclosingClass(), cppField); - s << ';' << endl; + writeToPythonConversion(s, fieldType, metaField->enclosingClass(), cppField); } + s << ';' << endl; - s << INDENT << "return val;" << endl; - s << '}' << endl << endl; + s << INDENT << "return value;" << endl; + s << '}' << endl; } void CppGenerator::writeSetterFunction(QTextStream& s, const AbstractMetaField* metaField) @@ -2921,7 +2916,7 @@ void CppGenerator::writeSetterFunction(QTextStream& s, const AbstractMetaField* s << "static int " << cpythonSetterFunctionName(metaField) << "(PyObject* " PYTHON_SELF_VAR ", PyObject* value, void*)" << endl; s << '{' << endl; - writeInvalidPyObjectCheck(s, PYTHON_SELF_VAR); + writeCppSelfDefinition(s, metaField->enclosingClass()); s << INDENT << "if (value == 0) {" << endl; { @@ -2932,40 +2927,37 @@ void CppGenerator::writeSetterFunction(QTextStream& s, const AbstractMetaField* } s << INDENT << '}' << endl; + AbstractMetaType* fieldType = metaField->type(); + s << INDENT << "if (!"; - writeTypeCheck(s, metaField->type(), "value", isNumber(metaField->type()->typeEntry())); + writeTypeCheck(s, fieldType, "value", isNumber(fieldType->typeEntry())); s << ") {" << endl; { Indentation indent(INDENT); s << INDENT << "PyErr_SetString(PyExc_TypeError, \"wrong type attributed to '"; - s << metaField->name() << "', '" << metaField->type()->name() << "' or convertible type expected\");" << endl; + s << metaField->name() << "', '" << fieldType->name() << "' or convertible type expected\");" << endl; s << INDENT << "return -1;" << endl; } s << INDENT << '}' << endl << endl; - s << INDENT; + QString conversion; + QTextStream c(&conversion); + writeToCppConversion(c, fieldType, metaField->enclosingClass(), "value"); + if (avoidProtectedHack() && metaField->isProtected()) { - QString fieldStr = QString("((%1*)%2)->%3") - .arg(wrapperName(metaField->enclosingClass())) - .arg(cpythonWrapperCPtr(metaField->enclosingClass(), PYTHON_SELF_VAR)) - .arg(protectedFieldSetterName(metaField)); - s << fieldStr << '('; - writeToCppConversion(s, metaField->type(), metaField->enclosingClass(), "value"); - s << ')'; + conversion = QString("((%1*)%2)->%3(%4)").arg(wrapperName(metaField->enclosingClass())) + .arg(CPP_SELF_VAR) + .arg(protectedFieldSetterName(metaField)) + .arg(conversion); } else { - QString fieldStr = QString("%1->%2") - .arg(cpythonWrapperCPtr(metaField->enclosingClass(), PYTHON_SELF_VAR)) - .arg(metaField->name()); - s << fieldStr << " = "; - writeToCppConversion(s, metaField->type(), metaField->enclosingClass(), "value"); + conversion = QString("%1->%2 = %3").arg(CPP_SELF_VAR).arg(metaField->name()).arg(conversion); } - s << ';' << endl << endl; - if (isPointerToWrapperType(metaField->type())) { + s << INDENT << conversion << ';' << endl << endl; + + if (isPointerToWrapperType(fieldType)) { s << INDENT << "Shiboken::Object::keepReference(reinterpret_cast<SbkObject*>(" PYTHON_SELF_VAR "), \""; s << metaField->name() << "\", value);" << endl; - //s << INDENT << "Py_XDECREF(oldvalue);" << endl; - s << endl; } s << INDENT << "return 0;" << endl; diff --git a/tests/libsample/protected.h b/tests/libsample/protected.h index 645dd93e9..1dc628d84 100644 --- a/tests/libsample/protected.h +++ b/tests/libsample/protected.h @@ -27,6 +27,7 @@ #include "objecttype.h" #include "point.h" #include <string> +#include <list> class ProtectedNonPolymorphic { @@ -128,6 +129,7 @@ public: {} protected: int protectedProperty; + std::list<int> protectedContainerProperty; Event::EventType protectedEnumProperty; Point protectedValueTypeProperty; Point* protectedValueTypePointerProperty; @@ -135,4 +137,3 @@ protected: }; #endif // PROTECTED_H - diff --git a/tests/samplebinding/protected_test.py b/tests/samplebinding/protected_test.py index 8ebc99f11..83922d5d1 100644 --- a/tests/samplebinding/protected_test.py +++ b/tests/samplebinding/protected_test.py @@ -277,6 +277,12 @@ class ProtectedPropertyTest(unittest.TestCase): self.obj.protectedProperty = 3 self.assertEqual(self.obj.protectedProperty, 3) + def testProtectedContainerProperty(self): + '''Writes and reads a protected list of integers property.''' + lst = [1, 2, 3, 4] + self.obj.protectedContainerProperty = lst + self.assertEqual(self.obj.protectedContainerProperty, lst) + def testProtectedEnumProperty(self): '''Writes and reads a protected enum property.''' self.obj.protectedEnumProperty = Event.SOME_EVENT |