diff options
author | Marcelo Lira <marcelo.lira@openbossa.org> | 2009-11-09 19:08:52 -0300 |
---|---|---|
committer | Hugo Lima <hugo.lima@openbossa.org> | 2009-11-10 11:00:43 -0200 |
commit | 14b0bdd84be9a23419fea6b6e70370d4a1cb6501 (patch) | |
tree | 046e089d4e4a9cdde15257a12c22777d2de6d0aa | |
parent | 3abff670957e68c6e6bc2da2aa51acc1b5d4508f (diff) |
moved HeaderGenerator::writeConverterImpl to CppGenerator, i.e.
the converter implementations now are written in the proper wrapper
class .cpp files instead of in the global module header
Reviewed by Hugo Parente <hugo.lima@openbossa.org>
-rw-r--r-- | cppgenerator.cpp | 129 | ||||
-rw-r--r-- | cppgenerator.h | 2 | ||||
-rw-r--r-- | headergenerator.cpp | 111 | ||||
-rw-r--r-- | headergenerator.h | 1 |
4 files changed, 130 insertions, 113 deletions
diff --git a/cppgenerator.cpp b/cppgenerator.cpp index 9be169bd5..58f9daf07 100644 --- a/cppgenerator.cpp +++ b/cppgenerator.cpp @@ -117,6 +117,13 @@ void CppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *metaCl s << "#include <shiboken.h>" << endl; s << "#include \"" << moduleName().toLower() << "_python.h\"" << endl << endl; + QString converterImpl; + QTextStream convImpl(&converterImpl); + if (!metaClass->isNamespace()) { + Indentation indentation(INDENT); + writeTypeConverterImpl(convImpl, metaClass->typeEntry()); + } + QString headerfile = fileNameForClass(metaClass); headerfile.replace("cpp", "h"); s << "#include \"" << headerfile << '"' << endl; @@ -256,12 +263,14 @@ void CppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *metaCl foreach (AbstractMetaEnum* cppEnum, metaClass->enums()) { bool hasFlags = cppEnum->typeEntry()->flags(); if (hasFlags) { + writeTypeConverterImpl(convImpl, cppEnum->typeEntry()->flags()); writeFlagsMethods(s, cppEnum); writeFlagsNumberMethodsDefinition(s, cppEnum); s << endl; } writeEnumDefinition(s, cppEnum); + writeTypeConverterImpl(convImpl, cppEnum->typeEntry()); if (hasFlags) { // Write Enum as Flags definition (at the moment used only by QFlags<enum>) @@ -272,7 +281,12 @@ void CppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *metaCl s << endl; writeClassRegister(s, metaClass); - s << endl << "} // extern \"C\"" << endl; + s << endl << "} // extern \"C\"" << endl << endl; + + s << "namespace Shiboken" << endl << '{' << endl; + s << "// Converter implementations" << endl; + s << converterImpl; + s << "} // namespace Shiboken" << endl << endl; } void CppGenerator::writeConstructorNative(QTextStream& s, const AbstractMetaFunction* func) @@ -1809,6 +1823,107 @@ void CppGenerator::writeClassRegister(QTextStream& s, const AbstractMetaClass* m s << '}' << endl << endl; } +void CppGenerator::writeTypeConverterImpl(QTextStream& s, const TypeEntry* type) +{ + if (type->hasConversionRule()) + return; + + QString pyTypeName = cpythonTypeName(type); + + const AbstractMetaClass* metaClass = classes().findClass(type->name()); + bool isAbstractOrObjectType = (metaClass && metaClass->isAbstract()) || type->isObject(); + + // Write Converter<T>::createWrapper function + s << "PyObject* Converter<" << type->name() << (isAbstractOrObjectType ? "*" : ""); + s << " >::createWrapper("; + QString convArg = type->name(); + if (!type->isEnum() && !type->isFlags()) { + convArg.prepend("const "); + convArg.append('*'); + } + s << convArg << " cppobj)" << endl; + + s << '{' << endl; + s << INDENT << "return " << "Shiboken::"; + if (type->isObject() || type->isValue()) { + s << "PyBaseWrapper_New(&" << pyTypeName << ", &" << pyTypeName << ','; + } else { + // Type is enum or flag + s << "PyEnumObject_New(&" << pyTypeName << ", (long)"; + } + s << " cppobj);" << endl; + s << '}' << endl << endl; + + AbstractMetaFunctionList implicitConvs = implicitConversions(type); + bool hasImplicitConversions = !implicitConvs.isEmpty(); + + if (hasImplicitConversions) { + // Write Converter<T>::isConvertible + s << "bool Converter<" << type->name() << " >::isConvertible(PyObject* pyobj)" << endl; + s << '{' << endl; + s << INDENT << "return "; + bool isFirst = true; + foreach (const AbstractMetaFunction* ctor, implicitConvs) { + Indentation indent(INDENT); + if (isFirst) + isFirst = false; + else + s << endl << INDENT << " || "; + s << cpythonCheckFunction(ctor->arguments().first()->type()); + s << "(pyobj)"; + } + s << ';' << endl; + s << '}' << endl << endl; + } + + if (!type->isValue()) + return; + + // Write Converter<T>::toPython function + s << "PyObject* Converter<" << type->name() << " >::toPython(const "; + s << type->name() << "& cppobj)" << endl; + s << '{' << endl; + s << INDENT << "return Converter<" << type->name() << " >::createWrapper(new "; + s << type->name() << "(cppobj));" << endl; + s << '}' << endl << endl; + + if (!hasImplicitConversions) + return; + + // Write Converter<T>::toCpp function + s << type->name() << " Converter<" << type->name() << " >::toCpp(PyObject* pyobj)" << endl; + s << '{' << endl << INDENT; + + bool firstImplicitIf = true; + foreach (const AbstractMetaFunction* ctor, implicitConvs) { + if (ctor->isModifiedRemoved()) + continue; + + const AbstractMetaType* argType = ctor->arguments().first()->type(); + if (firstImplicitIf) + firstImplicitIf = false; + else + s << INDENT << "else "; + s << "if (" << cpythonCheckFunction(argType) << "(pyobj))" << endl; + { + Indentation indent(INDENT); + s << INDENT << "return " << type->name() << '('; + writeBaseConversion(s, argType, 0); + s << "toCpp(pyobj));" << endl; + } + } + + s << INDENT << "return *Converter<" << type->name() << "* >::toCpp(pyobj);" << endl; + s << '}' << endl << endl; + + // Write Converter<T>::copyCppObject function + s << type->name() << "* Converter<" << type->name(); + s << " >::copyCppObject(const " << type->name() << "& cppobj)" << endl; + s << '{' << endl; + s << INDENT << "return new " << type->name() << "(cppobj);" << endl; + s << '}' << endl << endl; +} + void CppGenerator::finishGeneration() { //Generate CPython wrapper file @@ -1903,12 +2018,24 @@ void CppGenerator::finishGeneration() s << classInitDecl << endl; if (!globalEnums().isEmpty()) { + QString converterImpl; + QTextStream convImpl(&converterImpl); + s << "// Enum definitions "; s << "------------------------------------------------------------" << endl; foreach (const AbstractMetaEnum* cppEnum, globalEnums()) { + writeTypeConverterImpl(convImpl, cppEnum->typeEntry()); writeEnumDefinition(s, cppEnum); s << endl; } + + if (!converterImpl.isEmpty()) { + s << "// Enum converters "; + s << "------------------------------------------------------------" << endl; + s << "namespace Shiboken" << endl << '{' << endl; + s << converterImpl << endl; + s << "} // namespace Shiboken" << endl << endl; + } } s << "// Module initialization "; diff --git a/cppgenerator.h b/cppgenerator.h index 91517c6d0..257169063 100644 --- a/cppgenerator.h +++ b/cppgenerator.h @@ -58,6 +58,8 @@ private: void writeErrorSection(QTextStream& s, OverloadData& overloadData); void writeTypeCheck(QTextStream& s, const OverloadData* overloadData, QString argumentName); + void writeTypeConverterImpl(QTextStream& s, const TypeEntry* type); + /** * Writes Python to C++ conversions for arguments on Python wrappers. * If implicit conversions, and thus new object allocation, are needed, diff --git a/headergenerator.cpp b/headergenerator.cpp index 75d7333ae..cba8ffb75 100644 --- a/headergenerator.cpp +++ b/headergenerator.cpp @@ -220,107 +220,6 @@ void HeaderGenerator::writeTypeConverterDecl(QTextStream& s, const TypeEntry* ty s << "};" << endl; } -void HeaderGenerator::writeTypeConverterImpl(QTextStream& s, const TypeEntry* type) -{ - if (type->hasConversionRule()) - return; - - QString pyTypeName = cpythonTypeName(type); - - const AbstractMetaClass* metaClass = classes().findClass(type->name()); - bool isAbstractOrObjectType = (metaClass && metaClass->isAbstract()) || type->isObject(); - - // Write Converter<T>::createWrapper function - s << "inline PyObject* Converter<" << type->name() << (isAbstractOrObjectType ? "*" : ""); - s << " >::createWrapper("; - QString convArg = type->name(); - if (!type->isEnum() && !type->isFlags()) { - convArg.prepend("const "); - convArg.append('*'); - } - s << convArg << " cppobj)" << endl; - - s << '{' << endl; - s << INDENT << "return " << "Shiboken::"; - if (type->isObject() || type->isValue()) { - s << "PyBaseWrapper_New(&" << pyTypeName << ", &" << pyTypeName << ','; - } else { - // Type is enum or flag - s << "PyEnumObject_New(&" << pyTypeName << ", (long)"; - } - s << " cppobj);" << endl; - s << '}' << endl << endl; - - AbstractMetaFunctionList implicitConvs = implicitConversions(type); - bool hasImplicitConversions = !implicitConvs.isEmpty(); - - if (hasImplicitConversions) { - // Write Converter<T>::isConvertible - s << "inline bool Converter<" << type->name() << " >::isConvertible(PyObject* pyobj)" << endl; - s << '{' << endl; - s << INDENT << "return "; - bool isFirst = true; - foreach (const AbstractMetaFunction* ctor, implicitConvs) { - Indentation indent(INDENT); - if (isFirst) - isFirst = false; - else - s << endl << INDENT << " || "; - s << cpythonCheckFunction(ctor->arguments().first()->type()); - s << "(pyobj)"; - } - s << ';' << endl; - s << '}' << endl << endl; - } - - if (!type->isValue()) - return; - - // Write Converter<T>::toPython function - s << "inline PyObject* Converter<" << type->name() << " >::toPython(const "; - s << type->name() << "& cppobj)" << endl; - s << '{' << endl; - s << INDENT << "return Converter<" << type->name() << " >::createWrapper(new "; - s << type->name() << "(cppobj));" << endl; - s << '}' << endl << endl; - - if (!hasImplicitConversions) - return; - - // Write Converter<T>::toCpp function - s << "inline " << type->name() << " Converter<" << type->name() << " >::toCpp(PyObject* pyobj)" << endl; - s << '{' << endl << INDENT; - - bool firstImplicitIf = true; - foreach (const AbstractMetaFunction* ctor, implicitConvs) { - if (ctor->isModifiedRemoved()) - continue; - - const AbstractMetaType* argType = ctor->arguments().first()->type(); - if (firstImplicitIf) - firstImplicitIf = false; - else - s << INDENT << "else "; - s << "if (" << cpythonCheckFunction(argType) << "(pyobj))" << endl; - { - Indentation indent(INDENT); - s << INDENT << "return " << type->name() << '('; - writeBaseConversion(s, argType, 0); - s << "toCpp(pyobj));" << endl; - } - } - - s << INDENT << "return *Converter<" << type->name() << "* >::toCpp(pyobj);" << endl; - s << '}' << endl << endl; - - // Write Converter<T>::copyCppObject function - s << "inline " << type->name() << "* Converter<" << type->name(); - s << " >::copyCppObject(const " << type->name() << "& cppobj)" << endl; - s << '{' << endl; - s << INDENT << "return new " << type->name() << "(cppobj);" << endl; - s << '}' << endl << endl; -} - void HeaderGenerator::finishGeneration() { // Generate the main header for this module. @@ -332,9 +231,7 @@ void HeaderGenerator::finishGeneration() QString pythonTypeStuff; QTextStream s_pts(&pythonTypeStuff); QString convertersDecl; - QString convertersImpl; QTextStream convDecl(&convertersDecl); - QTextStream convImpl(&convertersImpl); Indentation indent(INDENT); @@ -349,7 +246,6 @@ void HeaderGenerator::finishGeneration() writeTypeCheckMacro(s_pts, flags); s_pts << endl; writeTypeConverterDecl(convDecl, cppEnum->typeEntry()); - writeTypeConverterImpl(convImpl, cppEnum->typeEntry()); convDecl << endl; } @@ -369,12 +265,10 @@ void HeaderGenerator::finishGeneration() foreach (const AbstractMetaEnum* cppEnum, metaClass->enums()) { writeTypeCheckMacro(s_pts, cppEnum->typeEntry()); writeTypeConverterDecl(convDecl, cppEnum->typeEntry()); - writeTypeConverterImpl(convImpl, cppEnum->typeEntry()); FlagsTypeEntry* flagsEntry = cppEnum->typeEntry()->flags(); if (flagsEntry) { writeTypeCheckMacro(s_pts, flagsEntry); writeTypeConverterDecl(convDecl, flagsEntry); - writeTypeConverterImpl(convImpl, flagsEntry); } s_pts << endl; convDecl << endl; @@ -388,7 +282,6 @@ void HeaderGenerator::finishGeneration() s_pts << "_New(PyTypeObject* type, PyObject* args, PyObject* kwds);" << endl; writeTypeCheckMacro(s_pts, innerClass->typeEntry()); writeTypeConverterDecl(convDecl, innerClass->typeEntry()); - writeTypeConverterImpl(convImpl, innerClass->typeEntry()); convDecl << endl; } } @@ -398,7 +291,6 @@ void HeaderGenerator::finishGeneration() s_pts << "#define Py" << metaClass->name() << "_cptr(pyobj) (("; s_pts << metaClass->name() << "*)PyBaseWrapper_cptr(pyobj))" << endl << endl; writeTypeConverterDecl(convDecl, classType); - writeTypeConverterImpl(convImpl, classType); convDecl << endl; } } @@ -472,9 +364,6 @@ void HeaderGenerator::finishGeneration() } } - s << "// Generated converters implementations -------------------------------" << endl << endl; - s << convertersImpl << endl; - s << "} // namespace Shiboken" << endl << endl; s << "#endif // " << includeShield << endl << endl; diff --git a/headergenerator.h b/headergenerator.h index 2fdd779f2..431130844 100644 --- a/headergenerator.h +++ b/headergenerator.h @@ -44,7 +44,6 @@ private: void writeVirtualDispatcher(QTextStream &s, const AbstractMetaFunction *func) const; void writeTypeCheckMacro(QTextStream& s, const TypeEntry* type); void writeTypeConverterDecl(QTextStream& s, const TypeEntry* type); - void writeTypeConverterImpl(QTextStream& s, const TypeEntry* type); }; #endif // HEADERGENERATOR_H |