aboutsummaryrefslogtreecommitdiffstats
path: root/generator
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2011-07-16 17:15:09 -0300
committerHugo Parente Lima <hugo.pl@gmail.com>2012-03-08 16:17:05 -0300
commit849c246c1e459ddeb545b5a4520365fbb803bf55 (patch)
tree96d061b6f20170085b3553f74254afb84a0cf837 /generator
parent5d61dc4c2d080c1e843d8958169c924c8b31f4de (diff)
Added a function to initialize a new wrapper type and add it to a module or enclosing class.
The class register writer was updated to use the new ObjectType::introduceWrapperType(). Types are now created and registered via the introduceWrapperType() function. I also did a little refactoring on CppGenerator::writeClassRegister.
Diffstat (limited to 'generator')
-rw-r--r--generator/cppgenerator.cpp149
1 files changed, 77 insertions, 72 deletions
diff --git a/generator/cppgenerator.cpp b/generator/cppgenerator.cpp
index b8204ac5d..8848e34a2 100644
--- a/generator/cppgenerator.cpp
+++ b/generator/cppgenerator.cpp
@@ -3421,8 +3421,15 @@ void CppGenerator::writeFlagsUnaryOperator(QTextStream& s, const AbstractMetaEnu
void CppGenerator::writeClassRegister(QTextStream& s, const AbstractMetaClass* metaClass)
{
+ const ComplexTypeEntry* classTypeEntry = metaClass->typeEntry();
+
+ const AbstractMetaClass* enc = metaClass->enclosingClass();
+ bool hasEnclosingClass = enc && enc->typeEntry()->codeGeneration() != TypeEntry::GenerateForSubclass;
+ QString enclosingObjectVariable = hasEnclosingClass ? "enclosingClass" : "module";
+
QString pyTypeName = cpythonTypeName(metaClass);
- s << "void init_" << metaClass->qualifiedCppName().replace("::", "_") << "(PyObject* module)" << endl;
+ s << "void init_" << metaClass->qualifiedCppName().replace("::", "_");
+ s << "(PyObject* " << enclosingObjectVariable << ")" << endl;
s << '{' << endl;
if (supportsNumberProtocol(metaClass)) {
@@ -3446,91 +3453,89 @@ void CppGenerator::writeClassRegister(QTextStream& s, const AbstractMetaClass* m
s << endl;
}
- s << INDENT << cpythonTypeNameExt(metaClass->typeEntry());
+ s << INDENT << cpythonTypeNameExt(classTypeEntry);
s << " = reinterpret_cast<PyTypeObject*>(&" << pyTypeName << ");" << endl;
s << endl;
- // alloc private data
- s << INDENT << "Shiboken::ObjectType::initPrivateData(&" << pyTypeName << ");" << endl;
-
- // class inject-code target/beginning
- if (!metaClass->typeEntry()->codeSnips().isEmpty()) {
- writeCodeSnips(s, metaClass->typeEntry()->codeSnips(), CodeSnip::Beginning, TypeSystem::TargetLangCode, 0, 0, metaClass);
- s << endl;
- }
-
- if (metaClass->baseClass())
- s << INDENT << pyTypeName << ".super.ht_type.tp_base = " << cpythonTypeNameExt(metaClass->baseClass()->typeEntry()) << ';' << endl;
-
// Multiple inheritance
+ QString pyTypeBasesVariable = QString("%1_bases").arg(pyTypeName);
const AbstractMetaClassList baseClasses = getBaseClasses(metaClass);
if (metaClass->baseClassNames().size() > 1) {
- s << INDENT << pyTypeName << ".super.ht_type.tp_bases = PyTuple_Pack(";
- s << baseClasses.size();
- s << ',' << endl;
+ s << INDENT << "PyObject* " << pyTypeBasesVariable << " = PyTuple_Pack(" << baseClasses.size() << ',' << endl;
QStringList bases;
foreach (const AbstractMetaClass* base, baseClasses)
- bases << "(PyTypeObject*)"+cpythonTypeNameExt(base->typeEntry());
+ bases << "(PyObject*)" + cpythonTypeNameExt(base->typeEntry());
Indentation indent(INDENT);
- s << INDENT << bases.join(", ") << ");" << endl << endl;
- }
-
- // Fill multiple inheritance data, if needed.
- const AbstractMetaClass* miClass = getMultipleInheritingClass(metaClass);
- if (miClass) {
- s << INDENT << "MultipleInheritanceInitFunction func;" << endl;
-
- if (miClass == metaClass)
- s << INDENT << "func = " << multipleInheritanceInitializerFunctionName(miClass) << ";" << endl;
- else
- s << INDENT << "func = Shiboken::ObjectType::getMultipleIheritanceFunction(reinterpret_cast<SbkObjectType*>(" << cpythonTypeNameExt(miClass->typeEntry()) << "));" << endl;
+ QString separator;
+ QTextStream sep(&separator);
+ sep << "," << endl << INDENT;
+ s << INDENT << bases.join(separator) << ");" << endl << endl;
+ }
+
+ // Create type and insert it in the module or enclosing class.
+ s << INDENT << "if (!Shiboken::ObjectType::introduceWrapperType(" << enclosingObjectVariable;
+ s << ", \"" << metaClass->name() << "\", \"";
+ // Original name
+ s << metaClass->qualifiedCppName() << (ShibokenGenerator::isObjectType(classTypeEntry) ? "*" : "");
+ s << "\"," << endl;
+ {
+ Indentation indent(INDENT);
+ s << INDENT << "&" << pyTypeName;
+
+ // Set destructor function
+ if (!metaClass->isNamespace() && !metaClass->hasPrivateDestructor()) {
+ QString dtorClassName = metaClass->qualifiedCppName();
+ if ((avoidProtectedHack() && metaClass->hasProtectedDestructor()) || classTypeEntry->isValue())
+ dtorClassName = wrapperName(metaClass);
+ s << ", &Shiboken::callCppDestructor< ::" << dtorClassName << " >";
+ } else if (metaClass->baseClass() || hasEnclosingClass) {
+ s << ", 0";
+ }
- s << INDENT << "Shiboken::ObjectType::setMultipleIheritanceFunction(&" << cpythonTypeName(metaClass) << ", func);" << endl;
- s << INDENT << "Shiboken::ObjectType::setCastFunction(&" << cpythonTypeName(metaClass) << ", &" << cpythonSpecialCastFunctionName(metaClass) << ");" << endl;
+ // Base type
+ if (metaClass->baseClass()) {
+ s << ", (SbkObjectType*)" << cpythonTypeNameExt(metaClass->baseClass()->typeEntry());
+ // The other base types
+ if (metaClass->baseClassNames().size() > 1)
+ s << ", " << pyTypeBasesVariable;
+ else if (hasEnclosingClass)
+ s << ", 0";
+ } else if (hasEnclosingClass) {
+ s << ", 0, 0";
+ }
+ if (hasEnclosingClass)
+ s << ", true";
+ s << ")) {" << endl;
+ s << INDENT << "return;" << endl;
}
+ s << INDENT << '}' << endl << endl;
- // Fill destrutor
- QString dtorClassName = metaClass->qualifiedCppName();
- if (!metaClass->isNamespace() && !metaClass->hasPrivateDestructor()) {
- if (avoidProtectedHack() && metaClass->hasProtectedDestructor())
- dtorClassName = wrapperName(metaClass);
- // call the real destructor
- if (metaClass->typeEntry()->isValue())
- dtorClassName = wrapperName(metaClass);
-
- s << INDENT << "Shiboken::ObjectType::setDestructorFunction(&" << cpythonTypeName(metaClass) << ", &Shiboken::callCppDestructor< ::" << dtorClassName << " >);" << endl;
+ // class inject-code target/beginning
+ if (!classTypeEntry->codeSnips().isEmpty()) {
+ writeCodeSnips(s, classTypeEntry->codeSnips(), CodeSnip::Beginning, TypeSystem::TargetLangCode, 0, 0, metaClass);
+ s << endl;
}
- s << INDENT << "Py_INCREF((PyObject*)&" << pyTypeName << "); //Incref due the 'PyModule_AddObject' steals the reference." << endl;
- s << INDENT << "if (PyType_Ready((PyTypeObject*)&" << pyTypeName << ") < 0)" << endl;
- s << INDENT << INDENT << "return;" << endl << endl;
-
- // Set typediscovery struct or fill the struct of another one
- if (metaClass->isPolymorphic()) {
- s << INDENT << "// Fill type discovery information" << endl;
- if (metaClass->baseClass()) {
- s << INDENT << "Shiboken::ObjectType::setTypeDiscoveryFunction(&" << cpythonTypeName(metaClass) << ", &" << cpythonBaseName(metaClass) << "_typeDiscovery);" << endl;
- s << INDENT << "Shiboken::BindingManager& bm = Shiboken::BindingManager::instance();" << endl;
- foreach (const AbstractMetaClass* base, baseClasses) {
- s << INDENT << "bm.addClassInheritance(reinterpret_cast<SbkObjectType*>(" << cpythonTypeNameExt(base->typeEntry()) << "), &" << cpythonTypeName(metaClass) << ");" << endl;
- }
+ // Fill multiple inheritance data, if needed.
+ const AbstractMetaClass* miClass = getMultipleInheritingClass(metaClass);
+ if (miClass) {
+ s << INDENT << "MultipleInheritanceInitFunction func = ";
+ if (miClass == metaClass) {
+ s << multipleInheritanceInitializerFunctionName(miClass) << ";" << endl;
+ } else {
+ s << "Shiboken::ObjectType::getMultipleIheritanceFunction(reinterpret_cast<SbkObjectType*>(";
+ s << cpythonTypeNameExt(miClass->typeEntry()) << "));" << endl;
}
- s << endl;
+ s << INDENT << "Shiboken::ObjectType::setMultipleIheritanceFunction(&";
+ s << cpythonTypeName(metaClass) << ", func);" << endl;
+ s << INDENT << "Shiboken::ObjectType::setCastFunction(&" << cpythonTypeName(metaClass);
+ s << ", &" << cpythonSpecialCastFunctionName(metaClass) << ");" << endl;
}
- // Set OriginalName
- QByteArray suffix;
- if (isObjectType(metaClass))
- suffix = "*";
- s << INDENT << "Shiboken::ObjectType::setOriginalName(&" << pyTypeName << ", \"" << metaClass->qualifiedCppName() << suffix << "\");" << endl;
-
- if (metaClass->enclosingClass() && (metaClass->enclosingClass()->typeEntry()->codeGeneration() != TypeEntry::GenerateForSubclass) ) {
- s << INDENT << "PyDict_SetItemString(module,"
- << "\"" << metaClass->name() << "\", (PyObject*)&" << pyTypeName << ");" << endl;
- } else {
- s << INDENT << "PyModule_AddObject(module, \"" << metaClass->name() << "\"," << endl;
- Indentation indent(INDENT);
- s << INDENT << "((PyObject*)&" << pyTypeName << "));" << endl << endl;
+ // Set typediscovery struct or fill the struct of another one
+ if (metaClass->isPolymorphic() && metaClass->baseClass()) {
+ s << INDENT << "Shiboken::ObjectType::setTypeDiscoveryFunction(&" << cpythonTypeName(metaClass);
+ s << ", &" << cpythonBaseName(metaClass) << "_typeDiscovery);" << endl << endl;
}
AbstractMetaEnumList classEnums = metaClass->enums();
@@ -3563,9 +3568,9 @@ void CppGenerator::writeClassRegister(QTextStream& s, const AbstractMetaClass* m
s << endl;
// class inject-code target/end
- if (!metaClass->typeEntry()->codeSnips().isEmpty()) {
+ if (!classTypeEntry->codeSnips().isEmpty()) {
s << endl;
- writeCodeSnips(s, metaClass->typeEntry()->codeSnips(), CodeSnip::End, TypeSystem::TargetLangCode, 0, 0, metaClass);
+ writeCodeSnips(s, classTypeEntry->codeSnips(), CodeSnip::End, TypeSystem::TargetLangCode, 0, 0, metaClass);
}
if (!metaClass->isNamespace())
@@ -3584,7 +3589,7 @@ void CppGenerator::writeClassRegister(QTextStream& s, const AbstractMetaClass* m
<< "::staticMetaObject, sizeof(::" << metaClass->qualifiedCppName() << "));" << endl;
}
- s << '}' << endl << endl;
+ s << '}' << endl;
}
void CppGenerator::writeInitQtMetaTypeFunctionBody(QTextStream& s, const AbstractMetaClass* metaClass) const