aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2024-06-25 10:25:09 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2024-06-26 14:35:37 +0200
commit16098891ad21c2ba984582a1de770e49f961f22b (patch)
tree731ad7fe95611e904706631f0193ae90f208791c
parent5bf6334c1b5e821598ddf3964010a07c520a5b1f (diff)
shiboken6: Refactor registerConverterName() streamable helper
Move the functionality to register partially qualified names (previously in helper registerConverterInScopes() and elsewhere), to register names with indirections, and to use typeid() into the streamable class controlled by flags. Simplify the code accordingly. This requires adding indexOf() to the helpers for QAnyStringView. Task-number: PYSIDE-2792 Change-Id: I7af0d8333e3c417e03f6615b471dc7220c95d388 Reviewed-by: Christian Tismer <tismer@stackless.com>
-rw-r--r--sources/shiboken6/ApiExtractor/anystringview_helpers.cpp22
-rw-r--r--sources/shiboken6/ApiExtractor/anystringview_helpers.h1
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.cpp146
3 files changed, 111 insertions, 58 deletions
diff --git a/sources/shiboken6/ApiExtractor/anystringview_helpers.cpp b/sources/shiboken6/ApiExtractor/anystringview_helpers.cpp
index 35d2d535a..c7a224533 100644
--- a/sources/shiboken6/ApiExtractor/anystringview_helpers.cpp
+++ b/sources/shiboken6/ApiExtractor/anystringview_helpers.cpp
@@ -54,3 +54,25 @@ bool asv_contains(QAnyStringView asv, const char *needle)
{
return asv.visit([needle](auto s) { return asv_containsImpl(s, needle); });
}
+
+static qsizetype asv_indexOfImpl(QLatin1StringView v, const char *needle)
+{
+ return v.indexOf(QLatin1StringView(needle));
+}
+
+static qsizetype asv_indexOfImpl(QUtf8StringView v, const char *needle)
+{
+ const char *data = v.data();
+ const char *match = std::strstr(data, needle);
+ return match != nullptr ? qsizetype(match - data) : qsizetype(-1);
+}
+
+static qsizetype asv_indexOfImpl(QStringView v, const char *needle)
+{
+ return v.indexOf(QLatin1StringView(needle));
+}
+
+qsizetype asv_indexOf(QAnyStringView asv, const char *needle)
+{
+ return asv.visit([needle](auto s) { return asv_indexOfImpl(s, needle); });
+}
diff --git a/sources/shiboken6/ApiExtractor/anystringview_helpers.h b/sources/shiboken6/ApiExtractor/anystringview_helpers.h
index e1e6ab7f0..8c25cffb4 100644
--- a/sources/shiboken6/ApiExtractor/anystringview_helpers.h
+++ b/sources/shiboken6/ApiExtractor/anystringview_helpers.h
@@ -14,5 +14,6 @@ QTextStream &operator<<(QTextStream &str, QAnyStringView asv);
bool asv_contains(QAnyStringView asv, char needle);
bool asv_contains(QAnyStringView asv, const char *needle);
+qsizetype asv_indexOf(QAnyStringView asv, const char *needle);
#endif // ANYSTRINGVIEW_STREAM_H
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
index 904fc4445..e83d6d1ed 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "cppgenerator.h"
+#include "anystringview_helpers.h"
#include "configurablescope.h"
#include "generatorargument.h"
#include "generatorstrings.h"
@@ -124,21 +125,76 @@ TextStream &operator<<(TextStream &s, CppGenerator::ErrorReturn r)
static constexpr auto converterVar = "converter"_L1;
-struct registerConverterName
+// Helper streamable class for generating code registering converters
+class registerConverterName
{
+public:
+ enum Flag
+ {
+ Indirections = 0x1, // Also register "Type*", "Type&"
+ PartiallyQualifiedAliases = 0x2, // Also register "B" when passed "A::B"
+ TypeId = 0x4 // Use typeid().name() for the string passed in
+ };
+ Q_DECLARE_FLAGS(Flags, Flag)
+
explicit registerConverterName(QAnyStringView typeName,
- QAnyStringView varName = converterVar) :
- m_typeName(typeName), m_varName(varName) {}
+ QAnyStringView varName = {},
+ Flags flags = {}) noexcept:
+ m_typeName(typeName), m_varName(varName), m_flags(flags) {}
+
+ void format(TextStream &s) const;
+
+ inline friend TextStream &operator<<(TextStream &s, const registerConverterName &r)
+ {
+ r.format(s);
+ return s;
+ }
+
+private:
+ static void formatEntry(TextStream &s, QAnyStringView typeName,
+ QAnyStringView varName, Flags flags,
+ const char *indirection = "");
QAnyStringView m_typeName;
QAnyStringView m_varName;
+ Flags m_flags;
};
-TextStream &operator<<(TextStream &s, const registerConverterName &r)
+Q_DECLARE_OPERATORS_FOR_FLAGS(registerConverterName::Flags)
+
+void registerConverterName::formatEntry(TextStream &s, QAnyStringView typeName,
+ QAnyStringView varName, Flags flags,
+ const char *indirection)
{
- s << "Shiboken::Conversions::registerConverterName(" << r.m_varName
- << ", \"" << r.m_typeName << "\");\n";
- return s;
+ s << "Shiboken::Conversions::registerConverterName("
+ << varName << ", ";
+ if (flags.testFlag(TypeId))
+ s << "typeid(" << typeName << indirection << ").name()";
+ else
+ s << '"' << typeName << indirection << '"';
+ s << ");\n";
+}
+
+void registerConverterName::format(TextStream &s) const
+{
+ QAnyStringView typeName = m_typeName;
+ const QAnyStringView varName = m_varName.isEmpty() ? converterVar : m_varName;
+ auto flags = m_flags;
+
+ while (true) {
+ formatEntry(s, typeName, varName, flags);
+ if (flags.testFlag(Indirections)) {
+ formatEntry(s, typeName, varName, flags, "*");
+ formatEntry(s, typeName, varName, flags, "&");
+ }
+
+ if (!flags.testFlag(PartiallyQualifiedAliases))
+ break;
+ auto pos = asv_indexOf(typeName, "::");
+ if (pos < 0)
+ break;
+ typeName = typeName.sliced(pos + 2);
+ }
}
// Protocol function name / function parameters / return type
@@ -1844,51 +1900,35 @@ void CppGenerator::writeConverterRegister(TextStream &s, const AbstractMetaClass
}
s << outdent << ");\n\n";
- auto writeConversions = [&s](const QString &signature)
- {
- s << registerConverterName(signature) << registerConverterName(signature + u'*')
- << registerConverterName(signature + u'&');
- };
-
- auto writeConversionsForType = [writeConversions](const QString &fullTypeName)
- {
- QStringList lst = fullTypeName.split(u"::"_s,
- Qt::SkipEmptyParts);
- while (!lst.isEmpty()) {
- QString signature = lst.join(u"::"_s);
- writeConversions(signature);
- lst.removeFirst();
- }
- };
-
-
if (!classContext.forSmartPointer()) {
- writeConversionsForType(metaClass->qualifiedCppName());
+ s << registerConverterName(metaClass->qualifiedCppName(), {},
+ registerConverterName::Indirections
+ | registerConverterName::PartiallyQualifiedAliases);
} else {
- const QString &smartPointerType = classContext.preciseType().instantiations().at(0).cppSignature();
+ QString pointeeType = classContext.preciseType().instantiations().at(0).cppSignature();
const QString &smartPointerName = classContext.preciseType().typeEntry()->name();
- QStringList lst = smartPointerType.split(u"::"_s,
- Qt::SkipEmptyParts);
- while (!lst.isEmpty()) {
- QString signature = lst.join(u"::"_s);
- writeConversions(smartPointerName + u'<' + signature + u'>');
- lst.removeFirst();
+ registerConverterName::Flags flags = registerConverterName::Indirections;
+ while (true) {
+ s << registerConverterName(smartPointerName + u'<' + pointeeType + u'>', {}, flags);
+ auto pos = pointeeType.indexOf("::"_L1);
+ if (pos < 0)
+ break;
+ pointeeType.remove(0, pos + 2);
}
}
- s << "Shiboken::Conversions::registerConverterName(converter, typeid(" << m_gsp;
- QString qualifiedCppNameInvocation;
+ QString qualifiedCppNameInvocation = m_gsp;
if (!classContext.forSmartPointer())
- qualifiedCppNameInvocation = metaClass->qualifiedCppName();
+ qualifiedCppNameInvocation += metaClass->qualifiedCppName();
else
- qualifiedCppNameInvocation = classContext.preciseType().cppSignature();
-
- s << qualifiedCppNameInvocation << ").name());\n";
+ qualifiedCppNameInvocation += classContext.preciseType().cppSignature();
+ s << registerConverterName(qualifiedCppNameInvocation, {},
+ registerConverterName::TypeId);
if (classContext.useWrapper()) {
- s << "Shiboken::Conversions::registerConverterName(converter, typeid("
- << classContext.wrapperName() << ").name());\n";
+ s << registerConverterName(classContext.wrapperName(), {},
+ registerConverterName::TypeId);
}
if (!typeEntry->isValue() && !typeEntry->isSmartPointer())
@@ -1900,7 +1940,7 @@ void CppGenerator::writeConverterRegister(TextStream &s, const AbstractMetaClass
targetTypeName = sourceTypeName + u"_COPY"_s;
QString toCpp = pythonToCppFunctionName(sourceTypeName, targetTypeName);
QString isConv = convertibleToCppFunctionName(sourceTypeName, targetTypeName);
- writeAddPythonToCppConversion(s, u"converter"_s, toCpp, isConv);
+ writeAddPythonToCppConversion(s, converterVar, toCpp, isConv);
// User provided implicit conversions.
@@ -1926,7 +1966,7 @@ void CppGenerator::writeConverterRegister(TextStream &s, const AbstractMetaClass
}
QString toCpp = pythonToCppFunctionName(sourceType, targetType);
QString isConv = convertibleToCppFunctionName(sourceType, targetType);
- writeAddPythonToCppConversion(s, u"converter"_s, toCpp, isConv);
+ writeAddPythonToCppConversion(s, converterVar, toCpp, isConv);
}
if (typeEntry->isValue()) {
@@ -4170,18 +4210,6 @@ void CppGenerator::writePrimitiveConverterInitialization(TextStream &s,
writeCustomConverterRegister(s, customConversion, converter);
}
-static void registerConverterInScopes(TextStream &s, QStringView signature,
- QAnyStringView varName = converterVar)
-{
- while (true) {
- s << registerConverterName(signature, varName);
- const auto qualifierPos = signature.indexOf("::"_L1);
- if (qualifierPos == -1)
- break;
- signature = signature.sliced(qualifierPos + 2);
- }
-}
-
void CppGenerator::writeEnumConverterInitialization(TextStream &s, const AbstractMetaEnum &metaEnum)
{
if (metaEnum.isPrivate() || metaEnum.isAnonymous())
@@ -4203,9 +4231,10 @@ void CppGenerator::writeEnumConverterInitialization(TextStream &s, const Abstrac
const QString isConv = convertibleToCppFunctionName(typeName, typeName);
writeAddPythonToCppConversion(s, u"converter"_s, toCpp, isConv);
s << "Shiboken::Enum::setTypeConverter(" << enumPythonVar
- << ", converter);\n";
+ << ", converter);\n"
+ << registerConverterName(enumType->qualifiedCppName(), {},
+ registerConverterName::PartiallyQualifiedAliases);
- registerConverterInScopes(s, enumType->qualifiedCppName());
if (auto flags = enumType->flags())
s << "// Register converter for flag '" << flags->qualifiedCppName() << "'.\n"
<< registerConverterName(flags->name()) // QMetaType
@@ -6490,7 +6519,8 @@ bool CppGenerator::finishGeneration()
if (!pte->referencesType())
continue;
TypeEntryCPtr referencedType = basicReferencedTypeEntry(pte);
- registerConverterInScopes(s, pte->qualifiedCppName(), converterObject(referencedType));
+ s << registerConverterName(pte->qualifiedCppName(), converterObject(referencedType),
+ registerConverterName::PartiallyQualifiedAliases);
}
s << '\n';