From 9bc3eed5c8e267f11fe63cc3fb5068e9fce2f64d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 6 Jan 2023 17:18:06 +0100 Subject: shiboken6: Add element for opaque containers Add an element enabling adding opaque containers to existing container-type entries (including builtins). Task-number: PYSIDE-1605 Task-number: PYSIDE-2174 Change-Id: I1b4a94331b264dc5e9503ab795edf882dfaa070f Reviewed-by: Shyamnath Premnadh Reviewed-by: Cristian Maureira-Fredes --- .../PySide6/QtCore/typesystem_core_common.xml | 2 +- .../PySide6/QtGui/typesystem_gui_common.xml | 2 ++ sources/shiboken6/ApiExtractor/typedatabase.cpp | 20 ++++++++++++++- sources/shiboken6/ApiExtractor/typedatabase_p.h | 3 +++ .../shiboken6/ApiExtractor/typesystemparser.cpp | 30 +++++++++++++++++++++- .../shiboken6/ApiExtractor/typesystemparser_p.h | 2 ++ sources/shiboken6/doc/typesystem_containers.rst | 3 ++- .../shiboken6/doc/typesystem_specifying_types.rst | 19 ++++++++++++++ .../tests/minimalbinding/typesystem_minimal.xml | 15 +---------- 9 files changed, 78 insertions(+), 18 deletions(-) (limited to 'sources') diff --git a/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml b/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml index 391e10032..91afc3b2a 100644 --- a/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml +++ b/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml @@ -368,7 +368,7 @@ + opaque-containers="int:QIntList;QPoint:QPointList;QPointF:QPointFList"> diff --git a/sources/pyside6/PySide6/QtGui/typesystem_gui_common.xml b/sources/pyside6/PySide6/QtGui/typesystem_gui_common.xml index f6e98b5cf..673a12f32 100644 --- a/sources/pyside6/PySide6/QtGui/typesystem_gui_common.xml +++ b/sources/pyside6/PySide6/QtGui/typesystem_gui_common.xml @@ -3126,4 +3126,6 @@ + + diff --git a/sources/shiboken6/ApiExtractor/typedatabase.cpp b/sources/shiboken6/ApiExtractor/typedatabase.cpp index adb092f19..1b2d7e7b7 100644 --- a/sources/shiboken6/ApiExtractor/typedatabase.cpp +++ b/sources/shiboken6/ApiExtractor/typedatabase.cpp @@ -129,6 +129,7 @@ struct TypeDatabasePrivate const CustomTypeEntryPtr &targetLang); void addBuiltInPrimitiveTypes(); void addBuiltInContainerTypes(const TypeDatabaseParserContextPtr &context); + bool addOpaqueContainers(const TypeDatabaseParserContextPtr &context); TypeEntryMultiMapConstIteratorRange findTypeRange(const QString &name) const; template TypeEntryCList findTypesHelper(const QString &name, Predicate pred) const; @@ -904,6 +905,22 @@ void TypeDatabasePrivate::addBuiltInContainerTypes(const TypeDatabaseParserConte Q_ASSERT(ok); } +bool TypeDatabasePrivate::addOpaqueContainers(const TypeDatabaseParserContextPtr &context) +{ + const auto &och = context->opaqueContainerHash; + for (auto it = och.cbegin(), end = och.cend(); it != end; ++it) { + const QString &name = it.key(); + auto te = findType(name); + if (!te || !te->isContainer()) { + qCWarning(lcShiboken, "No container \"%s\" found.", qPrintable(name)); + return false; + } + auto cte = std::static_pointer_cast(te); + cte->appendOpaqueContainers(it.value()); + } + return true; +} + bool TypeDatabase::parseFile(const QString &filename, bool generate) { QString filepath = modifiedTypesystemFilepath(filename, {}); @@ -975,7 +992,8 @@ bool TypeDatabasePrivate::parseFile(QIODevice *device, TypeDatabase *db, bool ge addBuiltInPrimitiveTypes(); addBuiltInContainerTypes(context); - return resolveSmartPointerInstantiations(context); + return addOpaqueContainers(context) + && resolveSmartPointerInstantiations(context); } bool TypeDatabase::parseFile(const TypeDatabaseParserContextPtr &context, diff --git a/sources/shiboken6/ApiExtractor/typedatabase_p.h b/sources/shiboken6/ApiExtractor/typedatabase_p.h index 04c1df145..fc56c7961 100644 --- a/sources/shiboken6/ApiExtractor/typedatabase_p.h +++ b/sources/shiboken6/ApiExtractor/typedatabase_p.h @@ -5,6 +5,7 @@ #define TYPEDATABASE_P_H #include "typesystem_typedefs.h" +#include "containertypeentry.h" #include #include @@ -14,9 +15,11 @@ class TypeDatabase; struct TypeDatabaseParserContext { using SmartPointerInstantiations = QHash; + using OpaqueContainerHash = QHash; TypeDatabase *db; SmartPointerInstantiations smartPointerInstantiations; + OpaqueContainerHash opaqueContainerHash; }; #endif // TYPEDATABASE_P_H diff --git a/sources/shiboken6/ApiExtractor/typesystemparser.cpp b/sources/shiboken6/ApiExtractor/typesystemparser.cpp index f7168adfb..8898c8715 100644 --- a/sources/shiboken6/ApiExtractor/typesystemparser.cpp +++ b/sources/shiboken6/ApiExtractor/typesystemparser.cpp @@ -465,6 +465,7 @@ static const StackElementHash &stackElementHash() {u"native-to-target", StackElement::NativeToTarget}, {u"no-null-pointer", StackElement::NoNullPointers}, {u"object-type", StackElement::ObjectTypeEntry}, + {u"opaque-container", StackElement::OpaqueContainer}, {u"parent", StackElement::ParentOwner}, {u"primitive-type", StackElement::PrimitiveTypeEntry}, {u"property", StackElement::Property}, @@ -1544,6 +1545,28 @@ ContainerTypeEntryPtr return type; } +bool TypeSystemParser::parseOpaqueContainerElement(QXmlStreamAttributes *attributes) +{ + QString containerName; + OpaqueContainers oc; + for (auto i = attributes->size() - 1; i >= 0; --i) { + const auto name = attributes->at(i).qualifiedName(); + if (name == nameAttribute()) { + containerName = attributes->takeAt(i).value().toString(); + } else if (name == opaqueContainerAttribute()) { + const auto attribute = attributes->takeAt(i); + if (!parseOpaqueContainers(attribute.value(), &oc)) + return false; + } + } + if (containerName.isEmpty()) { + m_error = msgMissingAttribute(nameAttribute()); + return false; + } + m_context->opaqueContainerHash[containerName].append(oc); + return true; +} + EnumTypeEntryPtr TypeSystemParser::parseEnumTypeEntry(const ConditionalStreamReader &reader, const QString &name, const QVersionNumber &since, @@ -3333,7 +3356,8 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack || element == StackElement::ConversionRule || element == StackElement::AddFunction || element == StackElement::DeclareFunction - || element == StackElement::Template; + || element == StackElement::Template + || element == StackElement::OpaqueContainer; if (!topLevel && m_stack.at(m_stack.size() - 2) == StackElement::Root) { m_error = u"Tag requires parent: '"_s + tagName.toString() + u'\''; @@ -3503,6 +3527,10 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack if (!parseReplace(reader, topElement, &attributes)) return false; break; + case StackElement::OpaqueContainer: + if (!parseOpaqueContainerElement(&attributes)) + return false; + break; default: break; // nada } diff --git a/sources/shiboken6/ApiExtractor/typesystemparser_p.h b/sources/shiboken6/ApiExtractor/typesystemparser_p.h index 68faab34b..01463f056 100644 --- a/sources/shiboken6/ApiExtractor/typesystemparser_p.h +++ b/sources/shiboken6/ApiExtractor/typesystemparser_p.h @@ -103,6 +103,7 @@ enum class StackElement { ArgumentModifiers, ImportFile, + OpaqueContainer, Unimplemented }; @@ -172,6 +173,7 @@ private: ContainerTypeEntryPtr parseContainerTypeEntry(const ConditionalStreamReader &, const QString &name, const QVersionNumber &since, QXmlStreamAttributes *); + bool parseOpaqueContainerElement(QXmlStreamAttributes *attributes); EnumTypeEntryPtr parseEnumTypeEntry(const ConditionalStreamReader &, const QString &name, const QVersionNumber &since, QXmlStreamAttributes *); diff --git a/sources/shiboken6/doc/typesystem_containers.rst b/sources/shiboken6/doc/typesystem_containers.rst index 5c4abee44..ffcae88a1 100644 --- a/sources/shiboken6/doc/typesystem_containers.rst +++ b/sources/shiboken6/doc/typesystem_containers.rst @@ -19,7 +19,8 @@ instead of a Python list. Manipulations like adding or removing elements can applied directly to them using the C++ container functions. This is achieved by specifying the name and the instantiated type -in the ``opaque-containers`` attribute of :ref:`container-type`. +in the ``opaque-containers`` attribute of :ref:`container-type` +or using the :ref:`opaque-container` element for existing container types. A second use case are public fields of container types. In the normal case, they are converted to Python containers on read access. By a field modification, diff --git a/sources/shiboken6/doc/typesystem_specifying_types.rst b/sources/shiboken6/doc/typesystem_specifying_types.rst index 6b58faa36..52b0ee4df 100644 --- a/sources/shiboken6/doc/typesystem_specifying_types.rst +++ b/sources/shiboken6/doc/typesystem_specifying_types.rst @@ -34,6 +34,7 @@ typesystem It may contain :ref:`add-function`, :ref:`container-type`, :ref:`custom-type`, :ref:`enum-type`, :ref:`extra-includes`, :ref:`function`, :ref:`load-typesystem`, :ref:`namespace`, :ref:`object-type`, + :ref:`opaque-container`, :ref:`primitive-type`, :ref:`rejection`, :ref:`smart-pointer-type`, :ref:`suppress-warning`, :ref:`template`, :ref:`system_include`, :ref:`typedef-type` or :ref:`value-type` child nodes. @@ -549,6 +550,24 @@ container-type and there are also a number of useful :ref:`predefined conversion templates `. +.. _opaque-container: + +opaque-container +^^^^^^^^^^^^^^^^ + + The ``opaque-container`` element can be used to add further instantiations + of :ref:`opaque containers ` to existing container types + (built-in or specified by :ref:`container-type` in included modules). + It is a child of the :ref:`typesystem` node. + + .. code-block:: xml + + + + + + For the **name** and **opaque-containers** attributes, + see :ref:`container-type`. .. _typedef-type: diff --git a/sources/shiboken6/tests/minimalbinding/typesystem_minimal.xml b/sources/shiboken6/tests/minimalbinding/typesystem_minimal.xml index 3fac1b2b3..b5e0d0532 100644 --- a/sources/shiboken6/tests/minimalbinding/typesystem_minimal.xml +++ b/sources/shiboken6/tests/minimalbinding/typesystem_minimal.xml @@ -15,20 +15,7 @@ - - - - - - - - - - - - - + -- cgit v1.2.3