diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2022-12-22 11:02:18 +0100 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2022-12-22 17:43:32 +0100 |
commit | 54ed06ab0e9014319ac8053465b97bc2cb226c47 (patch) | |
tree | b28c5a983130a87d63e3451807e1fc8c04d59e9f /sources | |
parent | 36f62dd5d45b8b84bd80064ceb43bab74a89321e (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>
Diffstat (limited to 'sources')
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); |