aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2024-03-13 09:56:38 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2024-03-18 11:43:07 +0100
commit02838733a868e8898cc8218a6a877ed52fe5a3e9 (patch)
treed6f38f134404268740f91b25d0a67c17aa974067
parent9141f75965d3a7b03f831193ed1f4094aff28574 (diff)
shiboken6: Register typedefs of container types
For signals like QRemoteObjectRegistry.remoteObjectAdded(QRemoteObjectSourceLocation) where using QRemoteObjectSourceLocation = std::pair<QString,QRemoteObjectSourceLocationInfo> one needed to specify the fully qualified C++ name in @Slot() for the metaobject system to work and the shiboken converter to be found. Record the typedefs and register the container converters under the typedef name, too. Fixes: PYSIDE-2633 Change-Id: Ifc62f096277949a507957a0466adb47d082695c7 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
-rw-r--r--sources/pyside6/tests/pysidetest/testobject.cpp5
-rw-r--r--sources/pyside6/tests/pysidetest/testobject.h5
-rw-r--r--sources/pyside6/tests/pysidetest/typedef_signal_test.py15
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp33
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder.h1
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h5
-rw-r--r--sources/shiboken6/ApiExtractor/apiextractor.cpp1
-rw-r--r--sources/shiboken6/ApiExtractor/apiextractorresult.cpp5
-rw-r--r--sources/shiboken6/ApiExtractor/apiextractorresult.h4
-rw-r--r--sources/shiboken6/ApiExtractor/parser/typeinfo.cpp6
-rw-r--r--sources/shiboken6/ApiExtractor/parser/typeinfo.h2
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.cpp16
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.h3
13 files changed, 94 insertions, 7 deletions
diff --git a/sources/pyside6/tests/pysidetest/testobject.cpp b/sources/pyside6/tests/pysidetest/testobject.cpp
index 295945a86..fe4ec98f7 100644
--- a/sources/pyside6/tests/pysidetest/testobject.cpp
+++ b/sources/pyside6/tests/pysidetest/testobject.cpp
@@ -30,6 +30,11 @@ void TestObject::emitSignalWithTypedefValue(int value)
emit signalWithTypedefValue(TypedefValue(value));
}
+void TestObject::emitSignalWithContainerTypedefValue(const IntList &il)
+{
+ emit signalWithContainerTypedefValue(il);
+}
+
void TestObject::emitFlagsSignal(Qt::Alignment alignment)
{
emit flagsSignal(alignment);
diff --git a/sources/pyside6/tests/pysidetest/testobject.h b/sources/pyside6/tests/pysidetest/testobject.h
index 0d6aa9d14..a095a382e 100644
--- a/sources/pyside6/tests/pysidetest/testobject.h
+++ b/sources/pyside6/tests/pysidetest/testobject.h
@@ -8,12 +8,15 @@
#include <QtWidgets/QApplication>
+#include <QtCore/QList>
#include <QtCore/QObject>
#include <QtCore/QMetaType>
#include <QtCore/QVariant>
QT_FORWARD_DECLARE_CLASS(QDebug)
+using IntList = QList<int>;
+
class IntValue
{
public:
@@ -44,6 +47,7 @@ public:
void emitSignalWithDefaultValue_bool();
void emitSignalWithTypedefValue(int value);
+ void emitSignalWithContainerTypedefValue(const IntList &il);
void emitFlagsSignal(Qt::Alignment alignment);
@@ -59,6 +63,7 @@ signals:
void childrenChanged(const QList<QObject*>&);
void signalWithDefaultValue(bool value = false);
void signalWithTypedefValue(TypedefValue value);
+ void signalWithContainerTypedefValue(const IntList &il);
void flagsSignal(Qt::Alignment alignment);
private:
diff --git a/sources/pyside6/tests/pysidetest/typedef_signal_test.py b/sources/pyside6/tests/pysidetest/typedef_signal_test.py
index dfe5311e8..d0bdc880b 100644
--- a/sources/pyside6/tests/pysidetest/typedef_signal_test.py
+++ b/sources/pyside6/tests/pysidetest/typedef_signal_test.py
@@ -10,7 +10,7 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(True)
-from PySide6.QtCore import QObject
+from PySide6.QtCore import QObject, Slot
from testbinding import TestObject
@@ -23,6 +23,10 @@ class Receiver(QObject):
def slot(self, value):
self.received = value
+ @Slot("IntList")
+ def containerSlot(self, value):
+ self.received = value
+
class TypedefSignal(unittest.TestCase):
@@ -34,6 +38,15 @@ class TypedefSignal(unittest.TestCase):
obj.emitSignalWithTypedefValue(2)
self.assertEqual(receiver.received.value, 2)
+ def testContainerTypedef(self):
+ obj = TestObject(0)
+ receiver = Receiver()
+
+ test_list = [1, 2]
+ obj.signalWithContainerTypedefValue.connect(receiver.containerSlot)
+ obj.emitSignalWithContainerTypedefValue(test_list)
+ self.assertEqual(receiver.received, test_list)
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
index 63e94cb51..58a8901cb 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
@@ -161,6 +161,11 @@ const QHash<TypeEntryCPtr, AbstractMetaEnum> &AbstractMetaBuilder::typeEntryToEn
return d->m_enums;
}
+const QMultiHash<QString, QString> &AbstractMetaBuilder::typedefTargetToName() const
+{
+ return d->m_typedefTargetToName;
+}
+
void AbstractMetaBuilderPrivate::checkFunctionModifications() const
{
const auto &entries = TypeDatabase::instance()->entries();
@@ -963,9 +968,31 @@ std::optional<AbstractMetaEnum>
return metaEnum;
}
-AbstractMetaClassPtr AbstractMetaBuilderPrivate::traverseTypeDef(const FileModelItem &,
- const TypeDefModelItem &typeDef,
- const AbstractMetaClassPtr &currentClass)
+AbstractMetaClassPtr
+ AbstractMetaBuilderPrivate::traverseTypeDef(const FileModelItem &dom,
+ const TypeDefModelItem &typeDef,
+ const AbstractMetaClassPtr &currentClass)
+{
+ auto result = traverseTypeDefHelper(dom, typeDef, currentClass);
+ if (!result && typeDef->type().isPlain()) {
+ const auto &type = typeDef->type();
+ QString fullName;
+ if (currentClass)
+ fullName += currentClass->qualifiedCppName() + "::"_L1;
+ fullName += typeDef->name();
+ QString targetName = typeDef->type().toString();
+ m_typedefTargetToName.insert(targetName, fullName);
+ const QByteArray normalized = QMetaObject::normalizedType(targetName.toUtf8().constData());
+ if (targetName != QLatin1StringView(normalized))
+ m_typedefTargetToName.insert(QString::fromUtf8(normalized), fullName);
+ }
+ return result;
+}
+
+AbstractMetaClassPtr
+ AbstractMetaBuilderPrivate::traverseTypeDefHelper(const FileModelItem &,
+ const TypeDefModelItem &typeDef,
+ const AbstractMetaClassPtr &currentClass)
{
TypeDatabase *types = TypeDatabase::instance();
QString className = stripTemplateArgs(typeDef->name());
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder.h b/sources/shiboken6/ApiExtractor/abstractmetabuilder.h
index b00a69363..cbd8c7034 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetabuilder.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder.h
@@ -54,6 +54,7 @@ public:
const AbstractMetaFunctionCList &globalFunctions() const;
const AbstractMetaEnumList &globalEnums() const;
const QHash<TypeEntryCPtr, AbstractMetaEnum> &typeEntryToEnumsHash() const;
+ const QMultiHash<QString, QString> &typedefTargetToName() const;
bool build(const QByteArrayList &arguments,
ApiExtractorFlags apiExtractorFlags = {},
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h
index 39ade6438..d7aaba5b0 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h
@@ -17,6 +17,7 @@
#include <QtCore/QFileInfo>
#include <QtCore/QList>
#include <QtCore/QMap>
+#include <QtCore/QMultiHash>
#include <QtCore/QSet>
#include <optional>
@@ -77,6 +78,9 @@ public:
AbstractMetaClassPtr traverseTypeDef(const FileModelItem &dom,
const TypeDefModelItem &typeDef,
const AbstractMetaClassPtr &currentClass);
+ AbstractMetaClassPtr traverseTypeDefHelper(const FileModelItem &dom,
+ const TypeDefModelItem &typeDef,
+ const AbstractMetaClassPtr &currentClass);
void traverseTypesystemTypedefs();
AbstractMetaClassPtr traverseClass(const FileModelItem &dom,
const ClassModelItem &item,
@@ -240,6 +244,7 @@ public:
QFileInfoList m_globalHeaders;
QStringList m_headerPaths;
mutable QHash<QString, Include> m_resolveIncludeHash;
+ QMultiHash<QString, QString> m_typedefTargetToName;
QList<TypeClassEntry> m_typeSystemTypeDefs; // look up metatype->class for type system typedefs
ApiExtractorFlags m_apiExtractorFlags;
bool m_skipDeprecated = false;
diff --git a/sources/shiboken6/ApiExtractor/apiextractor.cpp b/sources/shiboken6/ApiExtractor/apiextractor.cpp
index 7778e97de..ea45f22ba 100644
--- a/sources/shiboken6/ApiExtractor/apiextractor.cpp
+++ b/sources/shiboken6/ApiExtractor/apiextractor.cpp
@@ -421,6 +421,7 @@ std::optional<ApiExtractorResult> ApiExtractor::run(ApiExtractorFlags flags)
result.m_globalEnums = d->m_builder->globalEnums();
result.m_enums = d->m_builder->typeEntryToEnumsHash();
result.m_flags = flags;
+ result.m_typedefTargetToName = d->m_builder->typedefTargetToName();
qSwap(result.m_instantiatedContainers, collectContext.instantiatedContainers);
qSwap(result.m_instantiatedSmartPointers, collectContext.instantiatedSmartPointers);
return result;
diff --git a/sources/shiboken6/ApiExtractor/apiextractorresult.cpp b/sources/shiboken6/ApiExtractor/apiextractorresult.cpp
index eb9ac2d4a..2a48a30d1 100644
--- a/sources/shiboken6/ApiExtractor/apiextractorresult.cpp
+++ b/sources/shiboken6/ApiExtractor/apiextractorresult.cpp
@@ -50,6 +50,11 @@ const InstantiatedSmartPointers &ApiExtractorResult::instantiatedSmartPointers()
return m_instantiatedSmartPointers;
}
+const QMultiHash<QString, QString> &ApiExtractorResult::typedefTargetToName() const
+{
+ return m_typedefTargetToName;
+}
+
ApiExtractorFlags ApiExtractorResult::flags() const
{
return m_flags;
diff --git a/sources/shiboken6/ApiExtractor/apiextractorresult.h b/sources/shiboken6/ApiExtractor/apiextractorresult.h
index c1bb1a0a0..88a2093f1 100644
--- a/sources/shiboken6/ApiExtractor/apiextractorresult.h
+++ b/sources/shiboken6/ApiExtractor/apiextractorresult.h
@@ -10,6 +10,7 @@
#include "typesystem_typedefs.h"
#include <QtCore/QHash>
+#include <QtCore/QMultiHash>
#include <optional>
@@ -43,6 +44,8 @@ public:
const AbstractMetaTypeList &instantiatedContainers() const;
const InstantiatedSmartPointers &instantiatedSmartPointers() const;
+ const QMultiHash<QString, QString> &typedefTargetToName() const;
+
// Query functions for the generators
std::optional<AbstractMetaEnum>
findAbstractMetaEnum(TypeEntryCPtr typeEntry) const;
@@ -66,6 +69,7 @@ private:
AbstractMetaTypeList m_instantiatedContainers;
InstantiatedSmartPointers m_instantiatedSmartPointers;
QHash<TypeEntryCPtr, AbstractMetaEnum> m_enums;
+ QMultiHash<QString, QString> m_typedefTargetToName;
ApiExtractorFlags m_flags;
friend class ApiExtractor;
diff --git a/sources/shiboken6/ApiExtractor/parser/typeinfo.cpp b/sources/shiboken6/ApiExtractor/parser/typeinfo.cpp
index 50d6a535c..f8c5c31d8 100644
--- a/sources/shiboken6/ApiExtractor/parser/typeinfo.cpp
+++ b/sources/shiboken6/ApiExtractor/parser/typeinfo.cpp
@@ -266,6 +266,12 @@ void TypeInfo::clearInstantiations()
d->m_instantiations.clear();
}
+bool TypeInfo::isPlain() const
+{
+ return d->m_constant == 0 && d->m_volatile == 0 && d->m_referenceType == NoReference
+ && d->m_indirections.isEmpty() && d->m_arrayElements.isEmpty();
+}
+
TypeInfo TypeInfo::resolveType(TypeInfo const &__type, const ScopeModelItem &__scope)
{
CodeModel *__model = __scope->model();
diff --git a/sources/shiboken6/ApiExtractor/parser/typeinfo.h b/sources/shiboken6/ApiExtractor/parser/typeinfo.h
index d51e290c7..e4f363b67 100644
--- a/sources/shiboken6/ApiExtractor/parser/typeinfo.h
+++ b/sources/shiboken6/ApiExtractor/parser/typeinfo.h
@@ -80,6 +80,8 @@ public:
void addInstantiation(const TypeInfo &i);
void clearInstantiations();
+ bool isPlain() const; // neither const,volatile, no indirections/references, array
+
bool isStdType() const;
std::pair<qsizetype, qsizetype>
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
index 726365234..40c0e09da 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
@@ -4145,7 +4145,8 @@ void CppGenerator::writeEnumConverterInitialization(TextStream &s, const Abstrac
}
QString CppGenerator::writeContainerConverterInitialization(TextStream &s,
- const AbstractMetaType &type)
+ const AbstractMetaType &type,
+ const ApiExtractorResult &api)
{
const auto cppSignature =
QString::fromUtf8(QMetaObject::normalizedSignature(type.cppSignature().toUtf8()));
@@ -4179,6 +4180,17 @@ QString CppGenerator::writeContainerConverterInitialization(TextStream &s,
QString isConv = convertibleToCppFunctionName(sourceTypeName, typeName);
writeAddPythonToCppConversion(s, converter, toCpp, isConv);
}
+
+ auto typedefItPair = api.typedefTargetToName().equal_range(type.cppSignature());
+ if (typedefItPair.first != typedefItPair.second) {
+ auto *typeDb = TypeDatabase::instance();
+ s << "// Register converters for type aliases of " << cppSignature << "'.\n";
+ for (auto it = typedefItPair.first; it != typedefItPair.second; ++it) {
+ if (!typeDb->findType(it.value()))
+ s << registerConverterName(it.value(), converter);
+ }
+ }
+
return converter;
}
@@ -6300,7 +6312,7 @@ bool CppGenerator::finishGeneration()
if (!containers.isEmpty()) {
s << '\n';
for (const AbstractMetaType &container : containers) {
- const QString converterObj = writeContainerConverterInitialization(s, container);
+ const QString converterObj = writeContainerConverterInitialization(s, container, api());
const auto it = opaqueContainers.constFind(container);
if (it != opaqueContainers.constEnd()) {
writeSetPythonToCppPointerConversion(s, converterObj,
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.h b/sources/shiboken6/generator/shiboken/cppgenerator.h
index b7b1590ae..2c35b6f1d 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.h
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.h
@@ -460,7 +460,8 @@ private:
const CustomConversionPtr &customConversion);
static void writeEnumConverterInitialization(TextStream &s, const AbstractMetaEnum &metaEnum);
static QString writeContainerConverterInitialization(TextStream &s,
- const AbstractMetaType &type);
+ const AbstractMetaType &type,
+ const ApiExtractorResult &api);
void writeSmartPointerConverterInitialization(TextStream &s, const AbstractMetaType &ype) const;
static void writeExtendedConverterInitialization(TextStream &s,
const TypeEntryCPtr &externalType,