aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2022-12-22 11:02:18 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2022-12-22 17:43:32 +0100
commit54ed06ab0e9014319ac8053465b97bc2cb226c47 (patch)
treeb28c5a983130a87d63e3451807e1fc8c04d59e9f
parent36f62dd5d45b8b84bd80064ceb43bab74a89321e (diff)
shiboken6: Fix container conversion code
The container conversion code assumed that each container had exactly one target to native conversion and all conversion functions only used the C++ names (std_list_Python_to_Cpp_std_list). Fix the naming by extracting the logic to determine the target name to helper functions. Loop over the target to native conversions to create them all. Task-number: PYSIDE-1790 Change-Id: I63d3f4a91e6ebf451219f0cbb09c55c9ca68944c Reviewed-by: Christian Tismer <tismer@stackless.com> Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io>
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.cpp88
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.h6
-rw-r--r--sources/shiboken6/generator/shiboken/shibokengenerator.cpp36
-rw-r--r--sources/shiboken6/generator/shiboken/shibokengenerator.h1
4 files changed, 79 insertions, 52 deletions
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
index 85ee9968c..63526af0c 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
@@ -3515,6 +3515,18 @@ void CppGenerator::writeCppToPythonFunction(TextStream &s,
replaceCppToPythonVariables(code, getFullTypeName(ownerType), constRef);
writeCppToPythonFunction(s, code, fixedCppTypeName(customConversion->ownerType()));
}
+
+QString CppGenerator::containerNativeToTargetTypeName(const ContainerTypeEntryCPtr &type)
+{
+ QString result = type->targetLangApiName();
+ if (result != cPyObjectT()) {
+ result = containerCpythonBaseName(type);
+ if (result == cPySequenceT())
+ result = cPyListT();
+ }
+ return result;
+}
+
void CppGenerator::writeCppToPythonFunction(TextStream &s, const AbstractMetaType &containerType) const
{
Q_ASSERT(containerType.typeEntry()->isContainer());
@@ -3537,7 +3549,8 @@ void CppGenerator::writeCppToPythonFunction(TextStream &s, const AbstractMetaTyp
}
replaceCppToPythonVariables(code, getFullTypeNameWithoutModifiers(containerType), true);
processCodeSnip(code);
- writeCppToPythonFunction(s, code, fixedCppTypeName(containerType));
+ writeCppToPythonFunction(s, code, fixedCppTypeName(containerType),
+ containerNativeToTargetTypeName(cte));
}
void CppGenerator::writePythonToCppFunction(TextStream &s, const QString &code, const QString &sourceTypeName,
@@ -3657,22 +3670,19 @@ void CppGenerator::writePythonToCppConversionFunctions(TextStream &s,
void CppGenerator::writePythonToCppConversionFunctions(TextStream &s, const AbstractMetaType &containerType) const
{
Q_ASSERT(containerType.typeEntry()->isContainer());
- auto cte = qSharedPointerCast<const ContainerTypeEntry>(containerType.typeEntry());
- if (!cte->hasCustomConversion()) {
- //qFatal
- return;
- }
-
+ const auto cte = qSharedPointerCast<const ContainerTypeEntry>(containerType.typeEntry());
const auto customConversion = cte->customConversion();
- const TargetToNativeConversions &toCppConversions =
- customConversion->targetToNativeConversions();
- if (toCppConversions.isEmpty()) {
- //qFatal
- return;
- }
+ for (const auto &conv : customConversion->targetToNativeConversions())
+ writePythonToCppConversionFunction(s, containerType, conv);
+}
+
+void CppGenerator::writePythonToCppConversionFunction(TextStream &s,
+ const AbstractMetaType &containerType,
+ const TargetToNativeConversion &conv) const
+{
// Python to C++ conversion function.
QString cppTypeName = getFullTypeNameWithoutModifiers(containerType);
- QString code = toCppConversions.constFirst().conversion();
+ QString code = conv.conversion();
const QString line = u"auto &cppOutRef = *reinterpret_cast<"_s
+ cppTypeName + u" *>(cppOut);"_s;
CodeSnipAbstract::prependCode(&code, line);
@@ -3700,7 +3710,8 @@ void CppGenerator::writePythonToCppConversionFunctions(TextStream &s, const Abst
code.replace(u"%in"_s, u"pyIn"_s);
code.replace(u"%out"_s, u"cppOutRef"_s);
QString typeName = fixedCppTypeName(containerType);
- writePythonToCppFunction(s, code, typeName, typeName);
+ const QString &sourceTypeName = conv.sourceTypeName();
+ writePythonToCppFunction(s, code, sourceTypeName, typeName);
// Python to C++ convertible check function.
QString typeCheck = cpythonCheckFunction(containerType);
@@ -3708,7 +3719,7 @@ void CppGenerator::writePythonToCppConversionFunctions(TextStream &s, const Abst
typeCheck = u"false"_s;
else
typeCheck = typeCheck + u"pyIn)"_s;
- writeIsPythonConvertibleToCppFunction(s, typeName, typeName, typeCheck);
+ writeIsPythonConvertibleToCppFunction(s, sourceTypeName, typeName, typeCheck);
s << '\n';
}
@@ -4506,27 +4517,36 @@ QString CppGenerator::writeContainerConverterInitialization(TextStream &s, const
s << "// Register converter for type '" << cppSignature << "'.\n";
QString converter = converterObject(type);
s << converter << " = Shiboken::Conversions::createConverter(";
- if (type.typeEntry()->targetLangApiName() == cPyObjectT()) {
+
+ Q_ASSERT(type.typeEntry()->isContainer());
+ const auto typeEntry = qSharedPointerCast<const ContainerTypeEntry>(type.typeEntry());
+
+ const QString targetTypeName = containerNativeToTargetTypeName(typeEntry);
+ if (targetTypeName == cPyObjectT()) {
s << "&PyBaseObject_Type";
} else {
- QString baseName = cpythonBaseName(type.typeEntry());
- if (baseName == cPySequenceT())
- baseName = cPyListT();
- s << '&' << baseName << "_Type";
+ s << '&' << targetTypeName << "_Type";
+ }
+
+ const QString typeName = fixedCppTypeName(type);
+ s << ", " << cppToPythonFunctionName(typeName, targetTypeName) << ");\n";
+
+ for (const auto &conv : typeEntry->customConversion()->targetToNativeConversions()) {
+ const QString &sourceTypeName = conv.sourceTypeName();
+ QString toCpp = pythonToCppFunctionName(sourceTypeName, typeName);
+ QString isConv = convertibleToCppFunctionName(sourceTypeName, typeName);
+ s << "Shiboken::Conversions::registerConverterName(" << converter
+ << ", \"" << cppSignature << "\");\n";
+ if (usePySideExtensions() && cppSignature.startsWith("const ")
+ && cppSignature.endsWith("&")) {
+ cppSignature.chop(1);
+ cppSignature.remove(0, sizeof("const ") / sizeof(char) - 1);
+ s << "Shiboken::Conversions::registerConverterName(" << converter
+ << ", \"" << cppSignature << "\");\n";
+ }
+ writeAddPythonToCppConversion(s, converter, toCpp, isConv);
}
- QString typeName = fixedCppTypeName(type);
- s << ", " << cppToPythonFunctionName(typeName, typeName) << ");\n";
- QString toCpp = pythonToCppFunctionName(typeName, typeName);
- QString isConv = convertibleToCppFunctionName(typeName, typeName);
- s << "Shiboken::Conversions::registerConverterName(" << converter << ", \"" << cppSignature << "\");\n";
- if (usePySideExtensions() && cppSignature.startsWith("const ") && cppSignature.endsWith("&")) {
- cppSignature.chop(1);
- cppSignature.remove(0, sizeof("const ") / sizeof(char) - 1);
- s << "Shiboken::Conversions::registerConverterName(" << converter << ", \"" << cppSignature << "\");\n";
- }
- const QString converterObj = converterObject(type);
- writeAddPythonToCppConversion(s, converterObj, toCpp, isConv);
- return converterObj;
+ return converter;
}
void CppGenerator::writeSmartPointerConverterInitialization(TextStream &s, const AbstractMetaType &type) const
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.h b/sources/shiboken6/generator/shiboken/cppgenerator.h
index f38c14914..04a92271e 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.h
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.h
@@ -306,6 +306,8 @@ private:
QString targetTypeName = QString()) const;
void writeCppToPythonFunction(TextStream &s, const CustomConversionPtr &customConversion) const;
void writeCppToPythonFunction(TextStream &s, const AbstractMetaType &containerType) const;
+ /// Main target type name of a container (for naming the functions).
+ static QString containerNativeToTargetTypeName(const ContainerTypeEntryCPtr &type);
/// Writes a Python to C++ conversion function.
void writePythonToCppFunction(TextStream &s, const QString &code, const QString &sourceTypeName,
@@ -335,6 +337,10 @@ private:
void writePythonToCppConversionFunctions(TextStream &s,
const AbstractMetaType &containerType) const;
+ void writePythonToCppConversionFunction(TextStream &s,
+ const AbstractMetaType &containerType,
+ const TargetToNativeConversion &conv) const;
+
static void writeAddPythonToCppConversion(TextStream &s, const QString &converterVar,
const QString &pythonToCppFunc,
const QString &isConvertibleFunc);
diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
index 2346ddb5d..7c40b4ed1 100644
--- a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
@@ -566,6 +566,23 @@ QString ShibokenGenerator::cpythonBaseName(const AbstractMetaClassCPtr &metaClas
return cpythonBaseName(metaClass->typeEntry());
}
+QString ShibokenGenerator::containerCpythonBaseName(const ContainerTypeEntryCPtr &ctype)
+{
+ switch (ctype->containerKind()) {
+ case ContainerTypeEntry::SetContainer:
+ return u"PySet"_s;
+ case ContainerTypeEntry::MapContainer:
+ case ContainerTypeEntry::MultiMapContainer:
+ return u"PyDict"_s;
+ case ContainerTypeEntry::ListContainer:
+ case ContainerTypeEntry::PairContainer:
+ break;
+ default:
+ Q_ASSERT(false);
+ }
+ return cPySequenceT();
+}
+
QString ShibokenGenerator::cpythonBaseName(const TypeEntryCPtr &type)
{
QString baseName;
@@ -581,24 +598,7 @@ QString ShibokenGenerator::cpythonBaseName(const TypeEntryCPtr &type)
baseName = cpythonFlagsName(qSharedPointerCast<const FlagsTypeEntry>(type));
} else if (type->isContainer()) {
const auto ctype = qSharedPointerCast<const ContainerTypeEntry>(type);
- switch (ctype->containerKind()) {
- case ContainerTypeEntry::ListContainer:
- //baseName = "PyList";
- //break;
- case ContainerTypeEntry::PairContainer:
- //baseName = "PyTuple";
- baseName = cPySequenceT();
- break;
- case ContainerTypeEntry::SetContainer:
- baseName = u"PySet"_s;
- break;
- case ContainerTypeEntry::MapContainer:
- case ContainerTypeEntry::MultiMapContainer:
- baseName = u"PyDict"_s;
- break;
- default:
- Q_ASSERT(false);
- }
+ baseName = containerCpythonBaseName(ctype);
} else {
baseName = cPyObjectT();
}
diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.h b/sources/shiboken6/generator/shiboken/shibokengenerator.h
index b7caa9b29..4189753cc 100644
--- a/sources/shiboken6/generator/shiboken/shibokengenerator.h
+++ b/sources/shiboken6/generator/shiboken/shibokengenerator.h
@@ -221,6 +221,7 @@ protected:
static QString cpythonBaseName(const AbstractMetaClassCPtr &metaClass);
static QString cpythonBaseName(const TypeEntryCPtr &type);
+ static QString containerCpythonBaseName(const ContainerTypeEntryCPtr &ctype);
static QString cpythonBaseName(const AbstractMetaType &type);
static QString cpythonTypeName(const AbstractMetaClassCPtr &metaClass);
static QString cpythonTypeName(const TypeEntryCPtr &type);