summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHugo Parente Lima <hugo.pl@gmail.com>2010-12-29 18:26:44 -0200
committerHugo Parente Lima <hugo.pl@gmail.com>2010-12-29 19:13:39 -0200
commita24e6bcd2251b6cbd78ec4e69a2b6b591738e697 (patch)
tree54776f0352b3e84d4208bdecbaa5c36a1a2b90f0
parent304a8d46c162a3289da16ebcef839ff5c1b8697c (diff)
downloadshiboken-a24e6bcd2251b6cbd78ec4e69a2b6b591738e697.tar.gz
shiboken-a24e6bcd2251b6cbd78ec4e69a2b6b591738e697.tar.xz
shiboken-a24e6bcd2251b6cbd78ec4e69a2b6b591738e697.zip
Add support for operator overload injection.
Reviewer: Marcelo Lira <marcelo.lira@openbossa.org> Lauro Moura <lauro.neto@openbossa.org>
-rw-r--r--generator/cppgenerator.cpp40
-rw-r--r--generator/shibokengenerator.cpp5
-rw-r--r--tests/samplebinding/objecttypeoperators_test.py3
-rw-r--r--tests/samplebinding/typesystem_sample.xml8
4 files changed, 38 insertions, 18 deletions
diff --git a/generator/cppgenerator.cpp b/generator/cppgenerator.cpp
index 5980fdad..41267eff 100644
--- a/generator/cppgenerator.cpp
+++ b/generator/cppgenerator.cpp
@@ -2791,10 +2791,10 @@ void CppGenerator::writeRichCompareFunction(QTextStream& s, const AbstractMetaCl
{
QString baseName = cpythonBaseName(metaClass);
s << "static PyObject* ";
- s << baseName << "_richcompare(PyObject* self, PyObject* other, int op)" << endl;
+ s << baseName << "_richcompare(PyObject* self, PyObject* arg, int op)" << endl;
s << '{' << endl;
QList<AbstractMetaFunctionList> cmpOverloads = filterGroupedOperatorFunctions(metaClass, AbstractMetaClass::ComparisonOp);
- s << INDENT << "PyObject* result = 0;" << endl;
+ s << INDENT << "PyObject* " PYTHON_RETURN_VAR " = 0;" << endl;
s << INDENT << metaClass->qualifiedCppName() << "& " CPP_SELF_VAR " = *" << cpythonWrapperCPtr(metaClass) << ';' << endl;
s << endl;
@@ -2838,7 +2838,7 @@ void CppGenerator::writeRichCompareFunction(QTextStream& s, const AbstractMetaCl
s << INDENT;
}
- s << "if (" << cpythonIsConvertibleFunction(type, numberType) << "(other)) {" << endl;
+ s << "if (" << cpythonIsConvertibleFunction(type, numberType) << "(arg)) {" << endl;
{
Indentation indent(INDENT);
s << INDENT << "// " << func->signature() << endl;
@@ -2846,21 +2846,27 @@ void CppGenerator::writeRichCompareFunction(QTextStream& s, const AbstractMetaCl
s << translateTypeForWrapperMethod(type, 0, ExcludeReference | ExcludeConst);
if (type->isObject() || type->isQObject())
s << '&';
- s << " cppOther = ";
- writeToCppConversion(s, type, 0, "other", ExcludeReference | ExcludeConst);
+ s << " cppArg0 = ";
+ writeToCppConversion(s, type, 0, "arg", ExcludeReference | ExcludeConst);
s << ';' << endl;
- s << INDENT << "result = ";
- if (!func->type()) {
- s << "Py_None;" << endl;
- s << INDENT << "Py_INCREF(Py_None);" << endl;
- s << INDENT << CPP_SELF_VAR " " << op << " cppOther; // this op return void" << endl;
+ // If the function is user added, use the inject code
+ if (func->isUserAdded()) {
+ CodeSnipList snips = func->injectedCodeSnips();
+ writeCodeSnips(s, snips, CodeSnip::Any, TypeSystem::TargetLangCode, func, func->arguments().last());
} else {
- QByteArray self(CPP_SELF_VAR);
- if (func->isPointerOperator())
- self.prepend('&');
- writeToPythonConversion(s, func->type(), metaClass, self + ' ' + op + " cppOther");
- s << ';' << endl;
+ s << INDENT << PYTHON_RETURN_VAR " = ";
+ if (!func->type()) {
+ s << "Py_None;" << endl;
+ s << INDENT << "Py_INCREF(Py_None);" << endl;
+ s << INDENT << CPP_SELF_VAR " " << op << " cppArg0; // this op return void" << endl;
+ } else {
+ QByteArray self(CPP_SELF_VAR);
+ if (func->isPointerOperator())
+ self.prepend('&');
+ writeToPythonConversion(s, func->type(), metaClass, self + ' ' + op + " cppArg0");
+ s << ';' << endl;
+ }
}
}
s << INDENT << '}';
@@ -2879,10 +2885,10 @@ void CppGenerator::writeRichCompareFunction(QTextStream& s, const AbstractMetaCl
}
s << INDENT << '}' << endl << endl;
- s << INDENT << "if (result && !PyErr_Occurred())" << endl;
+ s << INDENT << "if (" PYTHON_RETURN_VAR " && !PyErr_Occurred())" << endl;
{
Indentation indent(INDENT);
- s << INDENT << "return result;" << endl;
+ s << INDENT << "return " PYTHON_RETURN_VAR ";" << endl;
}
s << INDENT << baseName << "_RichComparison_TypeError:" << endl;
s << INDENT << "PyErr_SetString(PyExc_NotImplementedError, \"operator not implemented.\");" << endl;
diff --git a/generator/shibokengenerator.cpp b/generator/shibokengenerator.cpp
index 2647e634..ebf63ab8 100644
--- a/generator/shibokengenerator.cpp
+++ b/generator/shibokengenerator.cpp
@@ -1218,6 +1218,11 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s,
} else {
cppSelf = "cppSelf";
}
+
+ // on comparison operator cppSelf is always a reference.
+ if (func->isComparisonOperator())
+ replacement = "%1.";
+
code.replace("%CPPSELF.", replacement.arg(cppSelf));
code.replace("%CPPSELF", cppSelf);
diff --git a/tests/samplebinding/objecttypeoperators_test.py b/tests/samplebinding/objecttypeoperators_test.py
index 148bc359..71e5a5d4 100644
--- a/tests/samplebinding/objecttypeoperators_test.py
+++ b/tests/samplebinding/objecttypeoperators_test.py
@@ -47,6 +47,9 @@ class ObjectTypeOperatorsTest(unittest.TestCase):
self.assertEqual("a", a)
self.assertEqual(a, "a")
+ def testOperatorInjection(self):
+ a = ObjectTypeOperators("a")
+ self.assertNotEqual(a, "b")
if __name__ == '__main__':
unittest.main()
diff --git a/tests/samplebinding/typesystem_sample.xml b/tests/samplebinding/typesystem_sample.xml
index 576c5465..5a518c34 100644
--- a/tests/samplebinding/typesystem_sample.xml
+++ b/tests/samplebinding/typesystem_sample.xml
@@ -1274,7 +1274,13 @@
<object-type name="HandleHolder" />
- <object-type name="ObjectTypeOperators" />
+ <object-type name="ObjectTypeOperators">
+ <add-function signature="operator!=(std::string)" return-type="bool">
+ <inject-code class="target">
+ %PYARG_0 = %CONVERTTOPYTHON[bool](%CPPSELF.key() != %1);
+ </inject-code>
+ </add-function>
+ </object-type>
<!-- type used in abstract method -->
<object-type name="HideType" generate="no" />