diff options
author | Hugo Lima <hugo.lima@openbossa.org> | 2010-01-28 22:15:41 -0200 |
---|---|---|
committer | Hugo Lima <hugo.lima@openbossa.org> | 2010-01-28 22:22:27 -0200 |
commit | 6a3cf558071a156a9bed24af89a4cfb056ce106b (patch) | |
tree | a86c5c727e67e38ef265802d87e791e86ee86dd7 /cppgenerator.cpp | |
parent | af98f2bd0db84f5698e9fd5896262b61e17d03bc (diff) |
Do not throw a Python exception when the user calls a pure virtual method of an object
wihtout C++ Wrapper (Shell) class.
Reviewed by Marcelo Lira <marcelo.lira@openbossa.org>
Diffstat (limited to 'cppgenerator.cpp')
-rw-r--r-- | cppgenerator.cpp | 144 |
1 files changed, 74 insertions, 70 deletions
diff --git a/cppgenerator.cpp b/cppgenerator.cpp index f9430c3bc..d574c53e5 100644 --- a/cppgenerator.cpp +++ b/cppgenerator.cpp @@ -665,83 +665,77 @@ void CppGenerator::writeMethodWrapper(QTextStream& s, const AbstractMetaFunction } s << ')' << endl << '{' << endl; - if (overloads.count() == 1 && rfunc->isAbstract()) { - s << INDENT << "PyErr_SetString(PyExc_NotImplementedError, \"pure virtual method '"; - s << rfunc->ownerClass()->name() << '.' << rfunc->name(); - s << "()' not implemented.\");" << endl; - s << INDENT << "return " << m_currentErrorCode << ';' << endl; - } else { - if (rfunc->implementingClass() && - (!rfunc->implementingClass()->isNamespace() && !rfunc->isStatic())) { - - if (rfunc->isOperatorOverload() && rfunc->isBinaryOperator()) { - QString checkFunc = cpythonCheckFunction(rfunc->ownerClass()->typeEntry()); - s << INDENT << "// FIXME: Optimize this: Only do this when there is a reverse operator in this function group\n"; - s << INDENT << "bool isReverse = " << checkFunc << "(arg) && !" << checkFunc << "(self);\n" - << INDENT << "if (isReverse)\n" - << INDENT << INDENT << "std::swap(self, arg);\n\n"; - } + if (rfunc->implementingClass() && + (!rfunc->implementingClass()->isNamespace() && !rfunc->isStatic())) { + + if (rfunc->isOperatorOverload() && rfunc->isBinaryOperator()) { + QString checkFunc = cpythonCheckFunction(rfunc->ownerClass()->typeEntry()); + s << INDENT << "// FIXME: Optimize this: Only do this when there is a reverse operator in this function group\n"; + s << INDENT << "bool isReverse = " << checkFunc << "(arg) && !" << checkFunc << "(self);\n" + << INDENT << "if (isReverse)\n" + << INDENT << INDENT << "std::swap(self, arg);\n\n"; + } - // Checks if the underlying C++ object is valid. - if (OverloadData::hasStaticAndInstanceFunctions(overloads)) { - s << INDENT << "if (self) {" << endl; - { - Indentation indent(INDENT); - writeInvalidCppObjectCheck(s); - } - s << INDENT << '}' << endl; - } else { + // Checks if the underlying C++ object is valid. + if (OverloadData::hasStaticAndInstanceFunctions(overloads)) { + s << INDENT << "if (self) {" << endl; + { + Indentation indent(INDENT); writeInvalidCppObjectCheck(s); } - s << endl; + s << INDENT << '}' << endl; + } else { + writeInvalidCppObjectCheck(s); } + s << endl; + } - bool hasReturnValue = overloadData.hasNonVoidReturnType(); + bool hasReturnValue = overloadData.hasNonVoidReturnType(); - if (hasReturnValue && !rfunc->isInplaceOperator()) - s << INDENT << "PyObject* " << PYTHON_RETURN_VAR << " = 0;" << endl; - if (overloadData.hasAllowThread()) - s << INDENT << "Shiboken::ThreadStateSaver " << THREAD_STATE_SAVER_VAR << ';' << endl; - s << endl; + if (hasReturnValue && !rfunc->isInplaceOperator()) + s << INDENT << "PyObject* " << PYTHON_RETURN_VAR << " = 0;" << endl; + if (overloadData.hasAllowThread()) + s << INDENT << "Shiboken::ThreadStateSaver " << THREAD_STATE_SAVER_VAR << ';' << endl; + s << endl; - if (minArgs != maxArgs || maxArgs > 1) { - s << INDENT << "int numArgs = "; - if (minArgs == 0 && maxArgs == 1) - s << "(arg == 0 ? 0 : 1);" << endl; - else - writeArgumentsInitializer(s, overloadData); - } + if (minArgs != maxArgs || maxArgs > 1) { + s << INDENT << "int numArgs = "; + if (minArgs == 0 && maxArgs == 1) + s << "(arg == 0 ? 0 : 1);" << endl; + else + writeArgumentsInitializer(s, overloadData); + } - writeOverloadedMethodDecisor(s, &overloadData); + writeOverloadedMethodDecisor(s, &overloadData); - s << endl << INDENT << "if (PyErr_Occurred()"; - if (hasReturnValue && !rfunc->isInplaceOperator()) - s << " || !" << PYTHON_RETURN_VAR; - s << ") {" << endl; - { - Indentation indent(INDENT); - if (hasReturnValue && !rfunc->isInplaceOperator()) - s << INDENT << "Py_XDECREF(" << PYTHON_RETURN_VAR << ");" << endl; - s << INDENT << "return " << m_currentErrorCode << ';' << endl; - } - s << INDENT << '}' << endl; + s << endl << INDENT << "if (PyErr_Occurred()"; + if (hasReturnValue && !rfunc->isInplaceOperator()) + s << " || !" << PYTHON_RETURN_VAR; + s << ") {" << endl; + { + Indentation indent(INDENT); + if (hasReturnValue && !rfunc->isInplaceOperator()) + s << INDENT << "Py_XDECREF(" << PYTHON_RETURN_VAR << ");" << endl; + s << INDENT << "return " << m_currentErrorCode << ';' << endl; + } + s << INDENT << '}' << endl; - s << INDENT; - if (hasReturnValue) { - if (rfunc->isInplaceOperator()) { - s << INDENT << "Py_INCREF(self);\n"; - s << INDENT << "return self;\n"; - } else { - s << INDENT << "return " << PYTHON_RETURN_VAR << ";\n"; - } + s << INDENT; + if (hasReturnValue) { + if (rfunc->isInplaceOperator()) { + s << INDENT << "Py_INCREF(self);\n"; + s << INDENT << "return self;\n"; } else { - s << "Py_RETURN_NONE"; + s << INDENT << "return " << PYTHON_RETURN_VAR << ";\n"; } - s << ';' << endl; - - if (maxArgs > 0) - writeErrorSection(s, overloadData); + } else { + s << "Py_RETURN_NONE"; } + s << ';' << endl; + + if (maxArgs > 0) + writeErrorSection(s, overloadData); + s << '}' << endl << endl; } @@ -1111,11 +1105,18 @@ void CppGenerator::writeMethodCall(QTextStream& s, const AbstractMetaFunction* f { s << INDENT << "// " << func->minimalSignature() << (func->isReverseOperator() ? " [reverse operator]": "") << endl; + if (func->isAbstract()) { - s << INDENT << "PyErr_SetString(PyExc_NotImplementedError, \"pure virtual method '" - << func->ownerClass()->name() << '.' << func->name() << "()' not implemented.\");" << endl; - return; + s << INDENT << "if (SbkBaseWrapper_containsCppWrapper(self)) {\n"; + { + Indentation indent(INDENT); + s << INDENT << "PyErr_SetString(PyExc_NotImplementedError, \"pure virtual method '"; + s << func->ownerClass()->name() << '.' << func->name() << "()' not implemented.\");" << endl; + s << INDENT << "return " << m_currentErrorCode << ';' << endl; + } + s << INDENT << "}\n"; } + writeCppSelfDefinition(s, func); // Used to provide contextual information to custom code writer function. @@ -1243,15 +1244,18 @@ void CppGenerator::writeMethodCall(QTextStream& s, const AbstractMetaFunction* f #ifndef AVOID_PROTECTED_HACK if (!func->isStatic()) mc << CPP_SELF_VAR << "->"; - mc << func->ownerClass()->name() << "::" << func->originalName(); + if (!func->isAbstract()) + mc << func->ownerClass()->name() << "::"; + mc << func->originalName(); #else if (!func->isStatic()) { if (func->isProtected()) mc << "((" << wrapperName(func->ownerClass()) << "*) "; mc << CPP_SELF_VAR << (func->isProtected() ? ")" : "") << "->"; } - mc << (func->isProtected() ? wrapperName(func->ownerClass()) : func->ownerClass()->name()); - mc << "::" << func->originalName() << (func->isProtected() ? "_protected" : ""); + if (!func->isAbstract()) + mc << (func->isProtected() ? wrapperName(func->ownerClass()) : func->ownerClass()->name()) << "::"; + mc << func->originalName() << (func->isProtected() ? "_protected" : ""); #endif } else { mc << func->originalName(); |