diff options
author | Marcelo Lira <marcelo.lira@openbossa.org> | 2011-08-18 17:00:32 -0300 |
---|---|---|
committer | Hugo Parente Lima <hugo.pl@gmail.com> | 2012-03-08 16:17:12 -0300 |
commit | e5fb8ee50dbcb0eab68260efe95c985ddc979e00 (patch) | |
tree | 73d8cb3b7b5a7e6a048dfbd9c058249bad19e860 | |
parent | b7169ca7fe92c5874076ff47f9b4ec7954acc480 (diff) |
Fixed generator to consider conversion rules for the return type of wrapper methods.
Tests were added.
Reviewed by Hugo Parente <hugo.lima@openbossa.org>
Reviewed by Lauro Moura <lauro.neto@openbossa.org>
-rw-r--r-- | generator/cppgenerator.cpp | 14 | ||||
-rw-r--r-- | generator/cppgenerator.h | 4 | ||||
-rw-r--r-- | tests/libsample/modifications.cpp | 14 | ||||
-rw-r--r-- | tests/libsample/modifications.h | 4 | ||||
-rw-r--r-- | tests/samplebinding/modifications_test.py | 57 | ||||
-rw-r--r-- | tests/samplebinding/typesystem_sample.xml | 43 |
6 files changed, 128 insertions, 8 deletions
diff --git a/generator/cppgenerator.cpp b/generator/cppgenerator.cpp index 8dd54cc79..6ca6c4775 100644 --- a/generator/cppgenerator.cpp +++ b/generator/cppgenerator.cpp @@ -814,7 +814,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun if (!func->conversionRule(TypeSystem::NativeCode, 0).isEmpty()) { // Has conversion rule. - writeConversionRule(s, func, CPP_RETURN_VAR); + writeConversionRule(s, func, TypeSystem::NativeCode, CPP_RETURN_VAR); } else if (!injectedCodeHasReturnValueAttribution(func, TypeSystem::NativeCode)) { writePythonToCppTypeConversion(s, func->type(), PYTHON_RETURN_VAR, CPP_RETURN_VAR, func->implementingClass()); } @@ -1617,12 +1617,12 @@ void CppGenerator::writeConversionRule(QTextStream& s, const AbstractMetaFunctio writeCodeSnips(s, snippets, CodeSnip::Beginning, TypeSystem::TargetLangCode, func); } -void CppGenerator::writeConversionRule(QTextStream& s, const AbstractMetaFunction* func, const QString& outputVar) +void CppGenerator::writeConversionRule(QTextStream& s, const AbstractMetaFunction* func, TypeSystem::Language language, const QString& outputVar) { CodeSnipList snippets; - QString rule = func->conversionRule(TypeSystem::NativeCode, 0); - addConversionRuleCodeSnippet(snippets, rule, TypeSystem::NativeCode, TypeSystem::NativeCode, outputVar); - writeCodeSnips(s, snippets, CodeSnip::Any, TypeSystem::NativeCode, func); + QString rule = func->conversionRule(language, 0); + addConversionRuleCodeSnippet(snippets, rule, language, language, outputVar); + writeCodeSnips(s, snippets, CodeSnip::Any, language, func); } void CppGenerator::writeNoneReturn(QTextStream& s, const AbstractMetaFunction* func, bool thereIsReturnValue) @@ -2217,7 +2217,9 @@ void CppGenerator::writeMethodCall(QTextStream& s, const AbstractMetaFunction* f s << methodCall << ';' << endl; s << INDENT << END_ALLOW_THREADS << endl; - if (!isCtor && !func->isInplaceOperator() && func->type() + if (!func->conversionRule(TypeSystem::TargetLangCode, 0).isEmpty()) { + writeConversionRule(s, func, TypeSystem::TargetLangCode, PYTHON_RETURN_VAR); + } else if (!isCtor && !func->isInplaceOperator() && func->type() && !injectedCodeHasReturnValueAttribution(func, TypeSystem::TargetLangCode)) { s << INDENT << PYTHON_RETURN_VAR " = "; writeToPythonConversion(s, func->type(), func->ownerClass(), CPP_RETURN_VAR); diff --git a/generator/cppgenerator.h b/generator/cppgenerator.h index 18eb01be0..82e89dece 100644 --- a/generator/cppgenerator.h +++ b/generator/cppgenerator.h @@ -113,8 +113,8 @@ private: /// Writes the conversion rule for arguments of regular and virtual methods. void writeConversionRule(QTextStream& s, const AbstractMetaFunction* func, TypeSystem::Language language); - /// Writes the conversion rule for the return value of a virtual method. - void writeConversionRule(QTextStream& s, const AbstractMetaFunction* func, const QString& outputVar); + /// Writes the conversion rule for the return value of a method. + void writeConversionRule(QTextStream& s, const AbstractMetaFunction* func, TypeSystem::Language language, const QString& outputVar); /** * Set the Python method wrapper return value variable to Py_None if diff --git a/tests/libsample/modifications.cpp b/tests/libsample/modifications.cpp index d809e823e..95880d229 100644 --- a/tests/libsample/modifications.cpp +++ b/tests/libsample/modifications.cpp @@ -122,6 +122,20 @@ Modifications::sumPointCoordinates(const Point* point) return point->x() + point->y(); } +double +Modifications::differenceOfPointCoordinates(const Point* pt, bool* ok) +{ + if (!pt) { + *ok = false; + return 0.0; + } + *ok = true; + double result = pt->x() - pt->y(); + if (result < 0) + result = result * -1.0; + return result; +} + bool Modifications::nonConversionRuleForArgumentWithDefaultValue(ObjectType** object) { diff --git a/tests/libsample/modifications.h b/tests/libsample/modifications.h index f17261473..7d5c9123f 100644 --- a/tests/libsample/modifications.h +++ b/tests/libsample/modifications.h @@ -106,6 +106,10 @@ public: // the test implementation must expect point never to be null. int sumPointCoordinates(const Point* point); + // Modify the return value of a virtual method. + virtual double differenceOfPointCoordinates(const Point* pt, bool* ok); + double callDifferenceOfPointCoordinates(const Point* pt, bool* ok) { return differenceOfPointCoordinates(pt, ok); } + // Sets an ObjectType in the argument and returns true. bool nonConversionRuleForArgumentWithDefaultValue(ObjectType** object = 0); ObjectType* getObject() const { return m_object; } diff --git a/tests/samplebinding/modifications_test.py b/tests/samplebinding/modifications_test.py index bc7b38dfa..a18bd7a18 100644 --- a/tests/samplebinding/modifications_test.py +++ b/tests/samplebinding/modifications_test.py @@ -33,10 +33,16 @@ from sample import Modifications, Point, ByteArray class ExtModifications(Modifications): def __init__(self): Modifications.__init__(self) + self.multiplier = 3.0 + self.increment = 10.0 def name(self): return 'ExtModifications' + def differenceOfPointCoordinates(self, point): + ok, res = Modifications.differenceOfPointCoordinates(self, point) + return ok, res * self.multiplier + self.increment + class ModificationsTest(unittest.TestCase): '''Test cases for method modifications performed as described on type system. ''' @@ -158,5 +164,56 @@ class ModificationsTest(unittest.TestCase): self.assertTrue(Modifications.invertBoolean(False)) self.assertFalse(Modifications.invertBoolean(True)) + def testConversionRuleForReturnType(self): + x, y = 11, 2 + diff = float(abs(x - y)) + point = Point(x, y) + + ok, res = self.mods.differenceOfPointCoordinates(point) + self.assertTrue(isinstance(ok, bool)) + self.assertTrue(isinstance(res, float)) + self.assertEqual(res, diff) + + ok, res = self.mods.callDifferenceOfPointCoordinates(point) + self.assertTrue(isinstance(ok, bool)) + self.assertTrue(isinstance(res, float)) + self.assertEqual(res, diff) + + ok, res = self.mods.differenceOfPointCoordinates(None) + self.assertTrue(isinstance(ok, bool)) + self.assertTrue(isinstance(res, float)) + self.assertEqual(res, 0.0) + + ok, res = self.mods.callDifferenceOfPointCoordinates(None) + self.assertTrue(isinstance(ok, bool)) + self.assertTrue(isinstance(res, float)) + self.assertEqual(res, 0.0) + + def testConversionRuleForReturnTypeOnExtendedClass(self): + x, y = 11, 2 + diff = float(abs(x - y)) + point = Point(x, y) + em = ExtModifications() + + ok, res = em.differenceOfPointCoordinates(point) + self.assertTrue(isinstance(ok, bool)) + self.assertTrue(isinstance(res, float)) + self.assertEqual(res, diff * em.multiplier + em.increment) + + ok, res = em.callDifferenceOfPointCoordinates(point) + self.assertTrue(isinstance(ok, bool)) + self.assertTrue(isinstance(res, float)) + self.assertEqual(res, diff * em.multiplier + em.increment) + + ok, res = em.differenceOfPointCoordinates(None) + self.assertTrue(isinstance(ok, bool)) + self.assertTrue(isinstance(res, float)) + self.assertEqual(res, em.increment) + + ok, res = em.callDifferenceOfPointCoordinates(None) + self.assertTrue(isinstance(ok, bool)) + self.assertTrue(isinstance(res, float)) + self.assertEqual(res, em.increment) + if __name__ == '__main__': unittest.main() diff --git a/tests/samplebinding/typesystem_sample.xml b/tests/samplebinding/typesystem_sample.xml index 75d222b7b..2fef355fc 100644 --- a/tests/samplebinding/typesystem_sample.xml +++ b/tests/samplebinding/typesystem_sample.xml @@ -731,6 +731,49 @@ <no-null-pointer/> </modify-argument> </modify-function> + <template name="differenceOfPointCoordinates_arg2"> + bool _status; + bool* %2 = &_status; + </template> + <template name="differenceOfPointCoordinates_returnTarget"> + %PYARG_0 = PyTuple_New(2); + PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[bool](*%2)); + PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%RETURN_TYPE](%0)); + </template> + <modify-function signature="differenceOfPointCoordinates(const Point*, bool*)"> + <modify-argument index="2"> + <remove-argument/> + <conversion-rule class="native"> + <insert-template name="differenceOfPointCoordinates_arg2"/> + </conversion-rule> + </modify-argument> + <modify-argument index="return"> + <replace-type modified-type="PySequence"/> + <conversion-rule class="native"> + Shiboken::AutoDecRef _py_ok_(PySequence_GetItem(%PYARG_0, 0)); + Shiboken::AutoDecRef _py_ret_(PySequence_GetItem(%PYARG_0, 1)); + *%2 = %CONVERTTOCPP[bool](_py_ok_); + %RETURN_TYPE %out = %CONVERTTOCPP[%RETURN_TYPE](_py_ret_); + </conversion-rule> + <conversion-rule class="target"> + <insert-template name="differenceOfPointCoordinates_returnTarget"/> + </conversion-rule> + </modify-argument> + </modify-function> + <modify-function signature="callDifferenceOfPointCoordinates(const Point*, bool*)"> + <modify-argument index="2"> + <remove-argument/> + <conversion-rule class="native"> + <insert-template name="differenceOfPointCoordinates_arg2"/> + </conversion-rule> + </modify-argument> + <modify-argument index="return"> + <replace-type modified-type="PySequence"/> + <conversion-rule class="target"> + <insert-template name="differenceOfPointCoordinates_returnTarget"/> + </conversion-rule> + </modify-argument> + </modify-function> <modify-function signature="nonConversionRuleForArgumentWithDefaultValue(ObjectType**)"> <modify-argument index="1"> <remove-argument/> |