aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2009-11-09 19:08:52 -0300
committerHugo Lima <hugo.lima@openbossa.org>2009-11-10 11:00:43 -0200
commit14b0bdd84be9a23419fea6b6e70370d4a1cb6501 (patch)
tree046e089d4e4a9cdde15257a12c22777d2de6d0aa
parent3abff670957e68c6e6bc2da2aa51acc1b5d4508f (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.cpp129
-rw-r--r--cppgenerator.h2
-rw-r--r--headergenerator.cpp111
-rw-r--r--headergenerator.h1
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