aboutsummaryrefslogtreecommitdiffstats
path: root/cppgenerator.cpp
diff options
context:
space:
mode:
authorHugo Lima <hugo.lima@openbossa.org>2010-01-28 22:15:41 -0200
committerHugo Lima <hugo.lima@openbossa.org>2010-01-28 22:22:27 -0200
commit6a3cf558071a156a9bed24af89a4cfb056ce106b (patch)
treea86c5c727e67e38ef265802d87e791e86ee86dd7 /cppgenerator.cpp
parentaf98f2bd0db84f5698e9fd5896262b61e17d03bc (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.cpp144
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();