diff options
author | Marcelo Lira <marcelo.lira@openbossa.org> | 2011-08-05 13:55:56 -0300 |
---|---|---|
committer | Hugo Parente Lima <hugo.pl@gmail.com> | 2012-03-08 16:17:08 -0300 |
commit | 50aef1dd4836b5019c60d31c54501ebcd37f72cd (patch) | |
tree | 3e9f41435c3ee0da5fdb5ee32b5b9900ad5a5259 | |
parent | 08f29f0d8f456eb1f994b05c21fd04468c95329c (diff) |
Improved guessCPythonCheckFunction method to produce an AbstractMetaType for known types.
This is in opposition of simply returning a string with a custom type
check. The details are in the docstring in ShibokenGenerator header.
Also added a new modification test and refactored here and there in the
sample binding type system.
-rw-r--r-- | generator/cppgenerator.cpp | 19 | ||||
-rw-r--r-- | generator/shibokengenerator.cpp | 51 | ||||
-rw-r--r-- | generator/shibokengenerator.h | 12 | ||||
-rw-r--r-- | tests/libsample/modifications.cpp | 7 | ||||
-rw-r--r-- | tests/libsample/modifications.h | 3 | ||||
-rw-r--r-- | tests/samplebinding/modifications_test.py | 7 | ||||
-rw-r--r-- | tests/samplebinding/typesystem_sample.xml | 27 |
7 files changed, 102 insertions, 24 deletions
diff --git a/generator/cppgenerator.cpp b/generator/cppgenerator.cpp index 9e8007f6d..687a24499 100644 --- a/generator/cppgenerator.cpp +++ b/generator/cppgenerator.cpp @@ -1471,12 +1471,21 @@ void CppGenerator::writeInvalidPyObjectCheck(QTextStream& s, const QString& pyOb void CppGenerator::writeTypeCheck(QTextStream& s, const AbstractMetaType* argType, QString argumentName, bool isNumber, QString customType) { - if (!customType.isEmpty()) - s << guessCPythonCheckFunction(customType); - else if (argType->isEnum()) - s << cpythonIsConvertibleFunction(argType, false); + AbstractMetaType* metaType; + std::auto_ptr<AbstractMetaType> metaType_autoptr; + QString customCheck; + if (!customType.isEmpty()) { + customCheck = guessCPythonCheckFunction(customType, &metaType); + if (metaType) { + metaType_autoptr = std::auto_ptr<AbstractMetaType>(metaType); + argType = metaType; + } + } + + if (customCheck.isEmpty()) + s << cpythonIsConvertibleFunction(argType, argType->isEnum() ? false : isNumber); else - s << cpythonIsConvertibleFunction(argType, isNumber); + s << customCheck; s << '(' << argumentName << ')'; } diff --git a/generator/shibokengenerator.cpp b/generator/shibokengenerator.cpp index 3e5b8eabb..17cd31a91 100644 --- a/generator/shibokengenerator.cpp +++ b/generator/shibokengenerator.cpp @@ -860,8 +860,18 @@ bool ShibokenGenerator::visibilityModifiedToPrivate(const AbstractMetaFunction* QString ShibokenGenerator::cpythonCheckFunction(const AbstractMetaType* metaType, bool genericNumberType) { - if (metaType->typeEntry()->isCustom()) - return guessCPythonCheckFunction(metaType->typeEntry()->name()); + AbstractMetaType* type; + std::auto_ptr<AbstractMetaType> type_autoptr; + QString customCheck; + if (metaType->typeEntry()->isCustom()) { + customCheck = guessCPythonCheckFunction(metaType->typeEntry()->name(), &type); + if (type) { + type_autoptr = std::auto_ptr<AbstractMetaType>(type); + metaType = type; + } + if (!customCheck.isEmpty()) + return customCheck; + } QString baseName = cpythonBaseName(metaType); if (isNumber(baseName)) @@ -878,8 +888,17 @@ QString ShibokenGenerator::cpythonCheckFunction(const AbstractMetaType* metaType QString ShibokenGenerator::cpythonCheckFunction(const TypeEntry* type, bool genericNumberType) { - if (type->isCustom()) - return guessCPythonCheckFunction(type->name()); + AbstractMetaType* metaType; + std::auto_ptr<AbstractMetaType> metaType_autoptr; + QString customCheck; + if (type->isCustom()) { + customCheck = guessCPythonCheckFunction(type->name(), &metaType); + if (metaType) { + metaType_autoptr = std::auto_ptr<AbstractMetaType>(metaType); + return cpythonCheckFunction(metaType, genericNumberType); + } + return customCheck; + } QString baseName = cpythonBaseName(type); if (isNumber(baseName)) @@ -892,18 +911,18 @@ QString ShibokenGenerator::cpythonCheckFunction(const TypeEntry* type, bool gene return QString("%1checkType").arg(baseName); } -QString ShibokenGenerator::guessCPythonCheckFunction(const QString& type) +QString ShibokenGenerator::guessCPythonCheckFunction(const QString& type, AbstractMetaType** metaType) { + *metaType = 0; if (type == "PyTypeObject") return "PyType_Check"; if (type == "PyBuffer") return "Shiboken::Buffer::checkType"; - AbstractMetaType* metaType = buildAbstractMetaTypeFromString(type); - std::auto_ptr<const AbstractMetaType> metaType_autoptr(metaType); - if (metaType && !metaType->typeEntry()->isCustom()) - return cpythonCheckFunction(metaType); + *metaType = buildAbstractMetaTypeFromString(type); + if (*metaType && !(*metaType)->typeEntry()->isCustom()) + return QString(); return QString("%1_Check").arg(type); } @@ -939,8 +958,18 @@ QString ShibokenGenerator::cpythonIsConvertibleFunction(const TypeEntry* type, b QString ShibokenGenerator::cpythonIsConvertibleFunction(const AbstractMetaType* metaType, bool genericNumberType) { - if (metaType->typeEntry()->isCustom()) - return guessCPythonCheckFunction(metaType->typeEntry()->name()); + AbstractMetaType* type; + std::auto_ptr<AbstractMetaType> type_autoptr; + QString customCheck; + if (metaType->typeEntry()->isCustom()) { + customCheck = guessCPythonCheckFunction(metaType->typeEntry()->name(), &type); + if (type) { + type_autoptr = std::auto_ptr<AbstractMetaType>(type); + metaType = type; + } + if (!customCheck.isEmpty()) + return customCheck; + } QString baseName = cpythonBaseName(metaType); if (isNumber(baseName)) diff --git a/generator/shibokengenerator.h b/generator/shibokengenerator.h index 674bbeab2..729dc0bc0 100644 --- a/generator/shibokengenerator.h +++ b/generator/shibokengenerator.h @@ -296,7 +296,17 @@ public: QString cpythonTypeNameExt(const TypeEntry* type); QString cpythonCheckFunction(const TypeEntry* type, bool genericNumberType = false); QString cpythonCheckFunction(const AbstractMetaType* metaType, bool genericNumberType = false); - QString guessCPythonCheckFunction(const QString& type); + /** + * Receives the argument \p type and tries to find the appropriate AbstractMetaType for it + * or a custom type check. + * \param type A string representing the type to be discovered. + * \param metaType A pointer to an AbstractMetaType pointer, to where write a new meta type object + * if one is produced from the \p type string. This object must be deallocated by + * the caller. It will set the target variable to NULL, is \p type is a Python type. + * \return A custom check if \p type is a custom type, or an empty string if \p metaType + * receives an existing type object. + */ + QString guessCPythonCheckFunction(const QString& type, AbstractMetaType** metaType); QString cpythonIsConvertibleFunction(const TypeEntry* type, bool genericNumberType = false, bool checkExact = false); QString cpythonIsConvertibleFunction(const AbstractMetaType* metaType, bool genericNumberType = false); QString cpythonIsConvertibleFunction(const AbstractMetaArgument* metaArg, bool genericNumberType = false) diff --git a/tests/libsample/modifications.cpp b/tests/libsample/modifications.cpp index 00a0cdf0c..72c3f40ed 100644 --- a/tests/libsample/modifications.cpp +++ b/tests/libsample/modifications.cpp @@ -96,3 +96,10 @@ Modifications::sumPointArray(int arraySize, const Point pointArray[]) point = point + pointArray[i]; return point; } + +int +Modifications::getSize(const void* data, int size) +{ + (void)data; + return size; +} diff --git a/tests/libsample/modifications.h b/tests/libsample/modifications.h index 5f7b58995..1b6fb8240 100644 --- a/tests/libsample/modifications.h +++ b/tests/libsample/modifications.h @@ -95,6 +95,9 @@ public: virtual const char* className(); Point sumPointArray(int arraySize, const Point pointArray[]); + + // Replace 'const void*' by 'ByteArray&'. + int getSize(const void* data, int size); }; class LIBSAMPLE_API AbstractModifications : public Modifications diff --git a/tests/samplebinding/modifications_test.py b/tests/samplebinding/modifications_test.py index b23165ff6..b37d74635 100644 --- a/tests/samplebinding/modifications_test.py +++ b/tests/samplebinding/modifications_test.py @@ -28,7 +28,7 @@ import unittest -from sample import Modifications, Point +from sample import Modifications, Point, ByteArray class ExtModifications(Modifications): def __init__(self): @@ -138,5 +138,10 @@ class ModificationsTest(unittest.TestCase): summedPoint = Point(1, 1) + Point(2, 2) self.assertEqual(self.mods.sumPointArray(points), summedPoint) + def testTypeSystemVariableReplacementInFunctionModification(self): + ba = ByteArray('12345') + self.assertEqual(self.mods.getSize(ba), len(ba)) + self.assertEqual(self.mods.getSize(ba, 20), 20) + if __name__ == '__main__': unittest.main() diff --git a/tests/samplebinding/typesystem_sample.xml b/tests/samplebinding/typesystem_sample.xml index be0f8fe88..27c265f3f 100644 --- a/tests/samplebinding/typesystem_sample.xml +++ b/tests/samplebinding/typesystem_sample.xml @@ -697,6 +697,21 @@ </conversion-rule> </modify-argument> </modify-function> + <modify-function signature="getSize(const void*,int)"> + <modify-argument index="1"> + <replace-type modified-type="ByteArray&"/> + </modify-argument> + <modify-argument index="2"> + <replace-default-expression with="-1"/> + </modify-argument> + <inject-code class="target" position="beginning"> + int size = (%2 < 0) ? %1.size() : %2; + %BEGIN_ALLOW_THREADS + %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME((const void*) %1.data(), size); + %END_ALLOW_THREADS + %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); + </inject-code> + </modify-function> </object-type> <object-type name="AbstractModifications"> @@ -833,9 +848,9 @@ </modify-function> <template name="fix_int*,int*,int*,int*"> int a0, a1, a2, a3; - PyThreadState* _save = PyEval_SaveThread(); // Py_BEGIN_ALLOW_THREADS + %BEGIN_ALLOW_THREADS %CPPSELF->::%TYPE::%FUNCTION_NAME(&a0, &a1, &a2, &a3); - PyEval_RestoreThread(_save); // Py_END_ALLOW_THREADS + %END_ALLOW_THREADS %PYARG_0 = Shiboken::makeTuple(a0, a1, a2, a3); </template> <template name="fix_native_return_int*,int*,int*,int*"> @@ -1373,10 +1388,10 @@ <insert-template name="buffer_argument"> <replace from="%out" to="argOut" /> </insert-template> - PyThreadState* _save = PyEval_SaveThread(); - %RETURN_TYPE cppResult = %CPPSELF.%FUNCTION_NAME(argOut, %2); - PyEval_RestoreThread(_save); - %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](cppResult); + %BEGIN_ALLOW_THREADS + %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(argOut, %2); + %END_ALLOW_THREADS + %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); </inject-code> </add-function> </object-type> |