aboutsummaryrefslogtreecommitdiffstats
path: root/headergenerator.cpp
diff options
context:
space:
mode:
authorHugo Lima <hugo.lima@openbossa.org>2010-02-18 17:17:27 -0200
committerHugo Lima <hugo.lima@openbossa.org>2010-02-18 18:01:47 -0200
commit589c2f447187e5071094648d5fe4046784ca28fd (patch)
tree004f87d35ac0704377ce13d895520f55fcbc7f8f /headergenerator.cpp
parent985d583110b9175d8b98fcdeaa2e0d83f3cc566f (diff)
Write all converters on global header to avoid the module from exporting any symbols.
Diffstat (limited to 'headergenerator.cpp')
-rw-r--r--headergenerator.cpp88
1 files changed, 82 insertions, 6 deletions
diff --git a/headergenerator.cpp b/headergenerator.cpp
index 9d483bedc..ea590a1e6 100644
--- a/headergenerator.cpp
+++ b/headergenerator.cpp
@@ -165,10 +165,7 @@ void HeaderGenerator::writeTypeConverterDecl(QTextStream& s, const TypeEntry* ty
}
bool isValueTypeWithImplConversions = type->isValue() && !implicitConvs.isEmpty();
- s << "struct ";
- if (isValueTypeWithImplConversions)
- s << getApiExportMacro() << ' ';
- s << "Converter<" << type->name() << (isAbstractOrObjectType ? "*" : "") << " > : ";
+ s << "struct Converter<" << type->name() << (isAbstractOrObjectType ? "*" : "") << " > : ";
if (type->isEnum() || type->isFlags())
s << "Converter_CppEnum";
else
@@ -226,6 +223,8 @@ void HeaderGenerator::finishGeneration()
QTextStream convDecl(&convertersDecl);
QString sbkTypeFunctions;
QTextStream typeFunctions(&sbkTypeFunctions);
+ QString converterImpl;
+ QTextStream convImpl(&converterImpl);
Indentation indent(INDENT);
@@ -282,16 +281,17 @@ void HeaderGenerator::finishGeneration()
if (!metaClass->isNamespace()) {
writeSbkTypeFunction(typeFunctions, metaClass);
- writeSbkCopyCppObjectFunction(typeFunctions, metaClass);
+ writeSbkCopyCppObjectFunction(convDecl, metaClass);
foreach (AbstractMetaClass* innerClass, metaClass->innerClasses()) {
if (shouldGenerate(innerClass)) {
- writeSbkCopyCppObjectFunction(typeFunctions, innerClass);
+ writeSbkCopyCppObjectFunction(convDecl, innerClass);
s_cin << innerClass->typeEntry()->include().toString() << endl;
writeTypeCheckMacro(s_pts, innerClass->typeEntry());
s_pts << "#define " << cpythonWrapperCPtr(innerClass, "pyobj") << " ((";
s_pts << innerClass->qualifiedCppName() << "*)SbkBaseWrapper_cptr(pyobj))" << endl << endl;
writeTypeConverterDecl(convDecl, innerClass->typeEntry());
+ writeTypeConverterImpl(convImpl, innerClass->typeEntry());
convDecl << endl;
writeSbkTypeFunction(typeFunctions, innerClass);
}
@@ -300,6 +300,7 @@ void HeaderGenerator::finishGeneration()
s_pts << "#define " << cpythonWrapperCPtr(metaClass, "pyobj") << " ((";
s_pts << metaClass->qualifiedCppName() << "*)SbkBaseWrapper_cptr(pyobj))" << endl << endl;
writeTypeConverterDecl(convDecl, classType);
+ writeTypeConverterImpl(convImpl, classType);
convDecl << endl;
}
}
@@ -389,6 +390,8 @@ void HeaderGenerator::finishGeneration()
}
s << "} // namespace Shiboken" << endl << endl;
+ s << "// Generated converters implemantations -------------------------------" << endl << endl;
+ s << converterImpl << endl;
s << "#endif // " << includeShield << endl << endl;
}
@@ -445,3 +448,76 @@ void HeaderGenerator::writeSbkCopyCppObjectFunction(QTextStream& s, const Abstra
s << "};" << endl;
}
+void HeaderGenerator::writeTypeConverterImpl(QTextStream& s, const TypeEntry* type)
+{
+ if (type->hasConversionRule())
+ return;
+
+ QString pyTypeName = cpythonTypeName(type);
+
+ AbstractMetaFunctionList implicitConvs;
+ foreach (AbstractMetaFunction* func, implicitConversions(type)) {
+ if (!func->isUserAdded())
+ implicitConvs << func;
+ }
+
+ bool hasImplicitConversions = !implicitConvs.isEmpty();
+
+ if (hasImplicitConversions) {
+ // Write Converter<T>::isConvertible
+ s << "inline bool Shiboken::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;
+ }
+
+ // A specialized Converter<T>::toCpp method is only need for
+ // value-types with implicit conversions.
+ if (!type->isValue() || !hasImplicitConversions)
+ return;
+
+ // Write Converter<T>::toCpp function
+ s << "inline " << type->name() << " Shiboken::Converter<" << type->name() << " >::toCpp(PyObject* pyobj)" << endl;
+ s << '{' << endl;
+
+ if (!implicitConvs.isEmpty()) {
+ s << INDENT << "if (!Shiboken_TypeCheck(pyobj, " << type->name() << ")) {" << endl;
+ bool firstImplicitIf = true;
+ foreach (const AbstractMetaFunction* ctor, implicitConvs) {
+ if (ctor->isModifiedRemoved())
+ continue;
+
+ Indentation indent(INDENT);
+ s << INDENT;
+
+ const AbstractMetaType* argType = ctor->arguments().first()->type();
+ if (firstImplicitIf)
+ firstImplicitIf = false;
+ else
+ s << "else ";
+ s << "if (" << cpythonCheckFunction(argType) << "(pyobj))" << endl;
+ {
+ Indentation indent(INDENT);
+ s << INDENT << "return " << type->name() << '(';
+ writeToCppConversion(s, argType, 0, "pyobj");
+ s << ");" << endl;
+ }
+ }
+ s << INDENT << '}' << endl;
+ }
+
+ s << INDENT << "return *" << cpythonWrapperCPtr(type, "pyobj") << ';' << endl;
+ s << '}' << endl << endl;
+}
+