diff options
author | Hugo Parente Lima <hugo.pl@gmail.com> | 2010-12-29 18:26:44 -0200 |
---|---|---|
committer | Hugo Parente Lima <hugo.pl@gmail.com> | 2010-12-29 19:13:39 -0200 |
commit | a24e6bcd2251b6cbd78ec4e69a2b6b591738e697 (patch) | |
tree | 54776f0352b3e84d4208bdecbaa5c36a1a2b90f0 | |
parent | 304a8d46c162a3289da16ebcef839ff5c1b8697c (diff) | |
download | shiboken-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.cpp | 40 | ||||
-rw-r--r-- | generator/shibokengenerator.cpp | 5 | ||||
-rw-r--r-- | tests/samplebinding/objecttypeoperators_test.py | 3 | ||||
-rw-r--r-- | tests/samplebinding/typesystem_sample.xml | 8 |
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" /> |