aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2011-08-18 17:00:32 -0300
committerHugo Parente Lima <hugo.pl@gmail.com>2012-03-08 16:17:12 -0300
commite5fb8ee50dbcb0eab68260efe95c985ddc979e00 (patch)
tree73d8cb3b7b5a7e6a048dfbd9c058249bad19e860
parentb7169ca7fe92c5874076ff47f9b4ec7954acc480 (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.cpp14
-rw-r--r--generator/cppgenerator.h4
-rw-r--r--tests/libsample/modifications.cpp14
-rw-r--r--tests/libsample/modifications.h4
-rw-r--r--tests/samplebinding/modifications_test.py57
-rw-r--r--tests/samplebinding/typesystem_sample.xml43
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 = &amp;_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/>