aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2011-08-06 17:28:00 -0300
committerHugo Parente Lima <hugo.pl@gmail.com>2012-03-08 16:17:09 -0300
commit714ddb6c74b4db4853ca2e34bb50f2888e75ec8d (patch)
tree7d04cd087ad99fef6442f6be4fbe0342eb722682
parent8794f303c16f67812093d0311530b4447ff5c94c (diff)
The type checking now pays attention to the <no-null-pointer/> tag.
An unit test was also added for it.
-rw-r--r--generator/cppgenerator.cpp16
-rw-r--r--generator/cppgenerator.h2
-rw-r--r--generator/shibokengenerator.cpp19
-rw-r--r--generator/shibokengenerator.h3
-rw-r--r--tests/libsample/modifications.cpp6
-rw-r--r--tests/libsample/modifications.h4
-rw-r--r--tests/samplebinding/modifications_test.py5
-rw-r--r--tests/samplebinding/typesystem_sample.xml5
8 files changed, 54 insertions, 6 deletions
diff --git a/generator/cppgenerator.cpp b/generator/cppgenerator.cpp
index 44d62f4f6..70290253d 100644
--- a/generator/cppgenerator.cpp
+++ b/generator/cppgenerator.cpp
@@ -1469,7 +1469,7 @@ void CppGenerator::writeInvalidPyObjectCheck(QTextStream& s, const QString& pyOb
s << INDENT << "return " << m_currentErrorCode << ';' << endl;
}
-void CppGenerator::writeTypeCheck(QTextStream& s, const AbstractMetaType* argType, QString argumentName, bool isNumber, QString customType)
+void CppGenerator::writeTypeCheck(QTextStream& s, const AbstractMetaType* argType, QString argumentName, bool isNumber, QString customType, bool rejectNull)
{
AbstractMetaType* metaType;
std::auto_ptr<AbstractMetaType> metaType_autoptr;
@@ -1482,12 +1482,17 @@ void CppGenerator::writeTypeCheck(QTextStream& s, const AbstractMetaType* argTyp
}
}
+ QString typeCheck;
if (customCheck.isEmpty())
- s << cpythonIsConvertibleFunction(argType, argType->isEnum() ? false : isNumber);
+ typeCheck = cpythonIsConvertibleFunction(argType, argType->isEnum() ? false : isNumber);
else
- s << customCheck;
+ typeCheck = customCheck;
+ typeCheck.append(QString("(%1)").arg(argumentName));
- s << '(' << argumentName << ')';
+ if (rejectNull)
+ typeCheck = QString("(%1 != Py_None && %2)").arg(argumentName).arg(typeCheck);
+
+ s << typeCheck;
}
void CppGenerator::writeTypeCheck(QTextStream& s, const OverloadData* overloadData, QString argumentName)
@@ -1510,7 +1515,8 @@ void CppGenerator::writeTypeCheck(QTextStream& s, const OverloadData* overloadDa
const AbstractMetaType* argType = overloadData->argType();
bool numberType = numericTypes.count() == 1 || ShibokenGenerator::isPyInt(argType);
QString customType = (overloadData->hasArgumentTypeReplace() ? overloadData->argumentTypeReplaced() : "");
- writeTypeCheck(s, argType, argumentName, numberType, customType);
+ bool rejectNull = shouldRejectNullPointerArgument(overloadData->referenceFunction(), overloadData->argPos());
+ writeTypeCheck(s, argType, argumentName, numberType, customType, rejectNull);
}
void CppGenerator::writeArgumentConversion(QTextStream& s,
diff --git a/generator/cppgenerator.h b/generator/cppgenerator.h
index 4dea57bd2..f0548931e 100644
--- a/generator/cppgenerator.h
+++ b/generator/cppgenerator.h
@@ -65,7 +65,7 @@ private:
/// Writes the check section for the validity of wrapped C++ objects.
void writeInvalidPyObjectCheck(QTextStream& s, const QString& pyObj);
- void writeTypeCheck(QTextStream& s, const AbstractMetaType* argType, QString argumentName, bool isNumber = false, QString customType = "");
+ void writeTypeCheck(QTextStream& s, const AbstractMetaType* argType, QString argumentName, bool isNumber = false, QString customType = "", bool rejectNull = false);
void writeTypeCheck(QTextStream& s, const OverloadData* overloadData, QString argumentName);
void writeTypeDiscoveryFunction(QTextStream& s, const AbstractMetaClass* metaClass);
diff --git a/generator/shibokengenerator.cpp b/generator/shibokengenerator.cpp
index 17cd31a91..54e5b2a2e 100644
--- a/generator/shibokengenerator.cpp
+++ b/generator/shibokengenerator.cpp
@@ -595,6 +595,25 @@ void ShibokenGenerator::writeToCppConversion(QTextStream& s, const AbstractMetaT
s << "toCpp(" << argumentName << ')';
}
+bool ShibokenGenerator::shouldRejectNullPointerArgument(const AbstractMetaFunction* func, int argIndex)
+{
+ if (argIndex < 0 || argIndex >= func->arguments().count())
+ return false;
+ // Argument type is not a pointer, a None rejection should not be
+ // necessary because the type checking would handle that already.
+ if (!isPointer(func->arguments().at(argIndex)->type()))
+ return false;
+ if (func->argumentRemoved(argIndex + 1))
+ return false;
+ foreach (FunctionModification funcMod, func->modifications()) {
+ foreach (ArgumentModification argMod, funcMod.argument_mods) {
+ if (argMod.index == argIndex + 1 && argMod.noNullPointers)
+ return true;
+ }
+ }
+ return false;
+}
+
QString ShibokenGenerator::getFormatUnitString(const AbstractMetaFunction* func, bool incRef) const
{
QString result;
diff --git a/generator/shibokengenerator.h b/generator/shibokengenerator.h
index 729dc0bc0..3139399e3 100644
--- a/generator/shibokengenerator.h
+++ b/generator/shibokengenerator.h
@@ -234,6 +234,9 @@ public:
const AbstractMetaClass* context, const QString& argumentName, Options options = NoOption);
void writeToCppConversion(QTextStream& s, const AbstractMetaClass* metaClass, const QString& argumentName);
+ /// Returns true if the argument is a pointer that rejects NULL values.
+ static bool shouldRejectNullPointerArgument(const AbstractMetaFunction* func, int argIndex);
+
/// Verifies if the class should have a C++ wrapper generated for it, instead of only a Python wrapper.
bool shouldGenerateCppWrapper(const AbstractMetaClass* metaClass) const;
diff --git a/tests/libsample/modifications.cpp b/tests/libsample/modifications.cpp
index 72c3f40ed..739ca5c74 100644
--- a/tests/libsample/modifications.cpp
+++ b/tests/libsample/modifications.cpp
@@ -103,3 +103,9 @@ Modifications::getSize(const void* data, int size)
(void)data;
return size;
}
+
+int
+Modifications::sumPointCoordinates(const Point* point)
+{
+ return point->x() + point->y();
+}
diff --git a/tests/libsample/modifications.h b/tests/libsample/modifications.h
index 1b6fb8240..c7a7748c6 100644
--- a/tests/libsample/modifications.h
+++ b/tests/libsample/modifications.h
@@ -98,6 +98,10 @@ public:
// Replace 'const void*' by 'ByteArray&'.
int getSize(const void* data, int size);
+
+ // Mark the argument with a <no-null-pointer/> tag;
+ // the test implementation must expect point never to be null.
+ int sumPointCoordinates(const Point* point);
};
class LIBSAMPLE_API AbstractModifications : public Modifications
diff --git a/tests/samplebinding/modifications_test.py b/tests/samplebinding/modifications_test.py
index b37d74635..344801015 100644
--- a/tests/samplebinding/modifications_test.py
+++ b/tests/samplebinding/modifications_test.py
@@ -143,5 +143,10 @@ class ModificationsTest(unittest.TestCase):
self.assertEqual(self.mods.getSize(ba), len(ba))
self.assertEqual(self.mods.getSize(ba, 20), 20)
+ def testNoNulPointerTag(self):
+ point = Point(12, 34)
+ self.assertEqual(self.mods.sumPointCoordinates(point), 12 + 34)
+ self.assertRaises(TypeError, self.mods.sumPointCoordinates, None)
+
if __name__ == '__main__':
unittest.main()
diff --git a/tests/samplebinding/typesystem_sample.xml b/tests/samplebinding/typesystem_sample.xml
index add18c289..3e910ccc6 100644
--- a/tests/samplebinding/typesystem_sample.xml
+++ b/tests/samplebinding/typesystem_sample.xml
@@ -714,6 +714,11 @@
%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
</inject-code>
</modify-function>
+ <modify-function signature="sumPointCoordinates(const Point*)">
+ <modify-argument index="1">
+ <no-null-pointer/>
+ </modify-argument>
+ </modify-function>
</object-type>
<object-type name="AbstractModifications">