diff options
author | Marcelo Lira <marcelo.lira@openbossa.org> | 2011-08-04 17:31:48 -0300 |
---|---|---|
committer | Hugo Parente Lima <hugo.pl@gmail.com> | 2012-03-08 16:17:08 -0300 |
commit | 08f29f0d8f456eb1f994b05c21fd04468c95329c (patch) | |
tree | 857a3dee162eec94d3ffd624ec4fba3f7c5e21d8 | |
parent | eda3572089e71e0c5065831438c4999486838547 (diff) |
Included tests for added function signatures very similar to already existing ones.
Specifically this causes the situation when there is in C++ a function
with an argument that is a reference to a Value Type, and the user adds
a very similar function with the same type, but passed as value.
Example:
C++ : function(const TYPE& a, int b)
Added: function(TYPE)
The return type of ShibokenGenerator::getArgumentReplacement() method
was modified, because the argument object is more useful than its index.
-rw-r--r-- | generator/shibokengenerator.cpp | 32 | ||||
-rw-r--r-- | generator/shibokengenerator.h | 8 | ||||
-rw-r--r-- | tests/libsample/samplenamespace.cpp | 13 | ||||
-rw-r--r-- | tests/libsample/samplenamespace.h | 8 | ||||
-rw-r--r-- | tests/samplebinding/addedfunction_test.py | 57 | ||||
-rw-r--r-- | tests/samplebinding/typesystem_sample.xml | 20 |
6 files changed, 121 insertions, 17 deletions
diff --git a/generator/shibokengenerator.cpp b/generator/shibokengenerator.cpp index eacc5e54d..3e5b8eabb 100644 --- a/generator/shibokengenerator.cpp +++ b/generator/shibokengenerator.cpp @@ -1201,11 +1201,11 @@ void ShibokenGenerator::processCodeSnip(QString& code, const AbstractMetaClass* replaceTypeCheckTypeSystemVariable(code); } -QMap<int, QString> ShibokenGenerator::getArgumentReplacement(const AbstractMetaFunction* func, - bool usePyArgs, TypeSystem::Language language, - const AbstractMetaArgument* lastArg) +ShibokenGenerator::ArgumentVarReplacementList ShibokenGenerator::getArgumentReplacement(const AbstractMetaFunction* func, + bool usePyArgs, TypeSystem::Language language, + const AbstractMetaArgument* lastArg) { - QMap<int, QString> argReplacement; + ArgumentVarReplacementList argReplacements; TypeSystem::Language convLang = (language == TypeSystem::TargetLangCode) ? TypeSystem::NativeCode : TypeSystem::TargetLangCode; int removed = 0; @@ -1236,9 +1236,10 @@ QMap<int, QString> ShibokenGenerator::getArgumentReplacement(const AbstractMetaF argValue = arg->name(); } if (!argValue.isEmpty()) - argReplacement[i+1] = argValue; + argReplacements << ArgumentVarReplacementPair(arg, argValue); + } - return argReplacement; + return argReplacements; } void ShibokenGenerator::writeCodeSnips(QTextStream& s, @@ -1387,10 +1388,21 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s, // Replaces template %ARGUMENT_NAMES and %# variables by argument variables and values. // Replaces template variables %# for individual arguments. - QMap<int, QString> argReplacements = getArgumentReplacement(func, usePyArgs, language, lastArg); - code.replace("%ARGUMENT_NAMES", QStringList(argReplacements.values()).join(", ")); - foreach (int i, argReplacements.keys()) - code.replace(QString("%%1").arg(i), argReplacements[i]); + ArgumentVarReplacementList argReplacements = getArgumentReplacement(func, usePyArgs, language, lastArg); + + QStringList args; + foreach (ArgumentVarReplacementPair pair, argReplacements) + args << pair.second; + code.replace("%ARGUMENT_NAMES", args.join(", ")); + + foreach (ArgumentVarReplacementPair pair, argReplacements) { + const AbstractMetaArgument* arg = pair.first; + int idx = arg->argumentIndex() + 1; + QString replacement = pair.second; + if (isWrapperType(arg->type()) && isPointer(arg->type())) + code.replace(QString("%%1.").arg(idx), QString("%1->").arg(replacement)); + code.replace(QString("%%1").arg(idx), replacement); + } if (language == TypeSystem::NativeCode) { // Replaces template %PYTHON_ARGUMENTS variable with a pointer to the Python tuple diff --git a/generator/shibokengenerator.h b/generator/shibokengenerator.h index 2c4dc888a..674bbeab2 100644 --- a/generator/shibokengenerator.h +++ b/generator/shibokengenerator.h @@ -114,9 +114,11 @@ public: QString functionReturnType(const AbstractMetaFunction* func, Options options = NoOption) const; /// Utility function for writeCodeSnips. - static QMap<int, QString> getArgumentReplacement(const AbstractMetaFunction* func, - bool usePyArgs, TypeSystem::Language language, - const AbstractMetaArgument* lastArg); + typedef QPair<const AbstractMetaArgument*, QString> ArgumentVarReplacementPair; + typedef QList<ArgumentVarReplacementPair> ArgumentVarReplacementList; + ArgumentVarReplacementList getArgumentReplacement(const AbstractMetaFunction* func, + bool usePyArgs, TypeSystem::Language language, + const AbstractMetaArgument* lastArg); /// Write user's custom code snippets at class or module level. void writeCodeSnips(QTextStream& s, diff --git a/tests/libsample/samplenamespace.cpp b/tests/libsample/samplenamespace.cpp index 0bcc5c2b2..922f26fa3 100644 --- a/tests/libsample/samplenamespace.cpp +++ b/tests/libsample/samplenamespace.cpp @@ -101,5 +101,16 @@ forceDecisorSideB(int a, const Point& pt, const Str& text, ObjectType* object) { } -} // namespace SampleNamespace +double +passReferenceToValueType(const Point& point, double multiplier) +{ + return (point.x() + point.y()) * multiplier; +} + +int +passReferenceToObjectType(const ObjectType& obj, int multiplier) +{ + return obj.objectName().size() * multiplier; +} +} // namespace SampleNamespace diff --git a/tests/libsample/samplenamespace.h b/tests/libsample/samplenamespace.h index 3ac5b2601..e1578dc88 100644 --- a/tests/libsample/samplenamespace.h +++ b/tests/libsample/samplenamespace.h @@ -26,8 +26,7 @@ #include "libsamplemacros.h" #include "str.h" #include "point.h" - -class ObjectType; +#include "objecttype.h" // Anonymous global enum enum { @@ -130,6 +129,11 @@ LIBSAMPLE_API void forceDecisorSideA(const Point& pt, const Str& text, ObjectTyp LIBSAMPLE_API void forceDecisorSideB(int a, ObjectType* object = 0); LIBSAMPLE_API void forceDecisorSideB(int a, const Point& pt, const Str& text, ObjectType* object = 0); +// Add a new signature on type system with only a Point value as parameter. +LIBSAMPLE_API double passReferenceToValueType(const Point& point, double multiplier); +// Add a new signature on type system with only a ObjectType pointer as parameter. +LIBSAMPLE_API int passReferenceToObjectType(const ObjectType& obj, int multiplier); + } // namespace SampleNamespace #endif // SAMPLENAMESPACE_H diff --git a/tests/samplebinding/addedfunction_test.py b/tests/samplebinding/addedfunction_test.py new file mode 100644 index 000000000..7e8db06af --- /dev/null +++ b/tests/samplebinding/addedfunction_test.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# This file is part of the Shiboken Python Bindings Generator project. +# +# Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +# +# Contact: PySide team <contact@pyside.org> +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public License +# version 2.1 as published by the Free Software Foundation. Please +# review the following information to ensure the GNU Lesser General +# Public License version 2.1 requirements will be met: +# http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +# # +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +'''Test cases for added functions.''' + +import unittest +from sample import SampleNamespace, ObjectType, Point + +class TestAddedFunctionsWithSimilarTypes(unittest.TestCase): + '''Adds new signatures very similar to already existing ones.''' + + def testValueTypeReferenceAndValue(self): + '''In C++ we have "function(const ValueType&, double)", + in Python we add "function(ValueType)".''' + point = Point(10, 20) + multiplier = 4.0 + control = (point.x() + point.y()) * multiplier + self.assertEqual(SampleNamespace.passReferenceToValueType(point, multiplier), control) + control = point.x() + point.y() + self.assertEqual(SampleNamespace.passReferenceToValueType(point), control) + + def testObjectTypeReferenceAndPointer(self): + '''In C++ we have "function(const ObjectType&, int)", + in Python we add "function(ValueType)".''' + obj = ObjectType() + obj.setObjectName('sbrubbles') + multiplier = 3.0 + control = len(obj.objectName()) * multiplier + self.assertEqual(SampleNamespace.passReferenceToObjectType(obj, multiplier), control) + control = len(obj.objectName()) + self.assertEqual(SampleNamespace.passReferenceToObjectType(obj), control) + +if __name__ == '__main__': + unittest.main() diff --git a/tests/samplebinding/typesystem_sample.xml b/tests/samplebinding/typesystem_sample.xml index 547710a52..be0f8fe88 100644 --- a/tests/samplebinding/typesystem_sample.xml +++ b/tests/samplebinding/typesystem_sample.xml @@ -137,6 +137,22 @@ %PYARG_0 = %CONVERTTOPYTHON[int](%1 + %2); </inject-code> </add-function> + <add-function signature="passReferenceToValueType(Point&)" return-type="double"> + <inject-code> + double %0 = %1.x() + %1.y(); + %PYARG_0 = %CONVERTTOPYTHON[double](%0); + </inject-code> + </add-function> + + <!-- Do change the argument from pointer to reference to comply with the C++ overload + of this function. The generator must be able to deal with this for Object Types. --> + <add-function signature="passReferenceToObjectType(ObjectType*)" return-type="int"> + <inject-code> + // The dot in "%1." must be replaced by a "->". + double %0 = %1.objectName().size(); + %PYARG_0 = %CONVERTTOPYTHON[int](%0); + </inject-code> + </add-function> </namespace-type> <namespace-type name="RemovedNamespace1" generate='no'> @@ -1711,5 +1727,7 @@ <suppress-warning text="template baseclass 'std::list<T>' of 'QList' is not known" /> <suppress-warning text="template baseclass 'std::list<Str>' of 'StrList' is not known" /> -</typesystem> + <!-- Do not fix this warning, the generator should be able to handle this situation for Object Types. --> + <suppress-warning text="Argument in position 1 of added function 'SampleNamespace::passReferenceToObjectType(ObjectType * arg__1)', has a type that is not a reference, while the argument in the corresponding position in C++ function 'SampleNamespace::passReferenceToObjectType(const ObjectType & obj, int multiplier)' is a reference." /> +</typesystem> |