diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2022-04-01 17:29:04 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2022-05-13 14:54:16 +0200 |
commit | b2dd6f135cd8bb2e113e0ec1ab37f350e3a240b2 (patch) | |
tree | 5450c594c85280736ad830c858f12c5a1a3a4795 /sources | |
parent | b6aaca48de358b4cfb3c841f05cc82267a6b47dc (diff) |
shiboken6: Add type "handle", "value-handle", to smart pointers
"handle" as opposed to the existing "shared" is a generalized class
that has a getter and operator->, which is modelled by getattro.
"value-handle" indicates that the getter returns a T instead of T*.
Task-number: PYSIDE-454
Change-Id: I1650627ff3df53d61e09d9d6e192fdb9974c830f
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'sources')
-rw-r--r-- | sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp | 5 | ||||
-rw-r--r-- | sources/shiboken6/ApiExtractor/typesystem.cpp | 16 | ||||
-rw-r--r-- | sources/shiboken6/ApiExtractor/typesystem.h | 4 | ||||
-rw-r--r-- | sources/shiboken6/ApiExtractor/typesystem_enums.h | 6 | ||||
-rw-r--r-- | sources/shiboken6/ApiExtractor/typesystemparser.cpp | 28 | ||||
-rw-r--r-- | sources/shiboken6/doc/typesystem_specifying_types.rst | 17 | ||||
-rw-r--r-- | sources/shiboken6/generator/shiboken/cppgenerator.cpp | 18 |
7 files changed, 67 insertions, 27 deletions
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp index 18fb749ef..936f1683e 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp @@ -2301,10 +2301,11 @@ static AbstractMetaFunctionPtr // Create the instantiation type of a smart pointer static AbstractMetaType instantiationType(const AbstractMetaClass *s, - const SmartPointerTypeEntry *) + const SmartPointerTypeEntry *ste) { AbstractMetaType type(s->templateArguments().constFirst()); - type.addIndirection(); + if (ste->smartPointerType() != TypeSystem::SmartPointerType::ValueHandle) + type.addIndirection(); type.decideUsagePattern(); return type; } diff --git a/sources/shiboken6/ApiExtractor/typesystem.cpp b/sources/shiboken6/ApiExtractor/typesystem.cpp index 5e32b10e3..cc5f9469e 100644 --- a/sources/shiboken6/ApiExtractor/typesystem.cpp +++ b/sources/shiboken6/ApiExtractor/typesystem.cpp @@ -1786,28 +1786,28 @@ class SmartPointerTypeEntryPrivate : public ComplexTypeEntryPrivate public: SmartPointerTypeEntryPrivate(const QString &entryName, const QString &getterName, - const QString &smartPointerType, + TypeSystem::SmartPointerType type, const QString &refCountMethodName, const QVersionNumber &vr, const TypeEntry *parent) : ComplexTypeEntryPrivate(entryName, TypeEntry::SmartPointerType, vr, parent), m_getterName(getterName), - m_smartPointerType(smartPointerType), - m_refCountMethodName(refCountMethodName) + m_refCountMethodName(refCountMethodName), + m_smartPointerType(type) { } QString m_getterName; - QString m_smartPointerType; QString m_refCountMethodName; QString m_valueCheckMethod; QString m_nullCheckMethod; QString m_resetMethod; SmartPointerTypeEntry::Instantiations m_instantiations; + TypeSystem::SmartPointerType m_smartPointerType; }; SmartPointerTypeEntry::SmartPointerTypeEntry(const QString &entryName, const QString &getterName, - const QString &smartPointerType, + TypeSystem::SmartPointerType smartPointerType, const QString &refCountMethodName, const QVersionNumber &vr, const TypeEntry *parent) : ComplexTypeEntry(new SmartPointerTypeEntryPrivate(entryName, getterName, smartPointerType, @@ -1815,6 +1815,12 @@ SmartPointerTypeEntry::SmartPointerTypeEntry(const QString &entryName, { } +TypeSystem::SmartPointerType SmartPointerTypeEntry::smartPointerType() const +{ + S_D(const SmartPointerTypeEntry); + return d->m_smartPointerType; +} + QString SmartPointerTypeEntry::getter() const { S_D(const SmartPointerTypeEntry); diff --git a/sources/shiboken6/ApiExtractor/typesystem.h b/sources/shiboken6/ApiExtractor/typesystem.h index 3d61a86dd..42ca4ac13 100644 --- a/sources/shiboken6/ApiExtractor/typesystem.h +++ b/sources/shiboken6/ApiExtractor/typesystem.h @@ -729,11 +729,13 @@ public: explicit SmartPointerTypeEntry(const QString &entryName, const QString &getterName, - const QString &smartPointerType, + TypeSystem::SmartPointerType type, const QString &refCountMethodName, const QVersionNumber &vr, const TypeEntry *parent); + TypeSystem::SmartPointerType smartPointerType() const; + QString getter() const; QString refCountMethodName() const; diff --git a/sources/shiboken6/ApiExtractor/typesystem_enums.h b/sources/shiboken6/ApiExtractor/typesystem_enums.h index 484320b8c..8a69ff3d0 100644 --- a/sources/shiboken6/ApiExtractor/typesystem_enums.h +++ b/sources/shiboken6/ApiExtractor/typesystem_enums.h @@ -115,6 +115,12 @@ enum class QtMetaTypeRegistration Disabled }; +enum class SmartPointerType { + Shared, + Handle, + ValueHandle +}; + enum : int { OverloadNumberUnset = -1, OverloadNumberDefault = 99999 }; } // namespace TypeSystem diff --git a/sources/shiboken6/ApiExtractor/typesystemparser.cpp b/sources/shiboken6/ApiExtractor/typesystemparser.cpp index 1452eedf9..46d58217b 100644 --- a/sources/shiboken6/ApiExtractor/typesystemparser.cpp +++ b/sources/shiboken6/ApiExtractor/typesystemparser.cpp @@ -398,6 +398,15 @@ ENUM_LOOKUP_BEGIN(TypeSystem::ExceptionHandling, Qt::CaseSensitive, }; ENUM_LOOKUP_LINEAR_SEARCH() +ENUM_LOOKUP_BEGIN(TypeSystem::SmartPointerType, Qt::CaseSensitive, + smartPointerTypeFromAttribute) +{ + {u"handle", TypeSystem::SmartPointerType::Handle}, + {u"value-handle", TypeSystem::SmartPointerType::ValueHandle}, + {u"shared", TypeSystem::SmartPointerType::Shared} +}; +ENUM_LOOKUP_LINEAR_SEARCH() + template <class EnumType> static std::optional<EnumType> lookupHashElement(const QHash<QStringView, EnumType> &hash, @@ -1337,7 +1346,7 @@ SmartPointerTypeEntry * { if (!checkRootElement()) return nullptr; - QString smartPointerType; + TypeSystem::SmartPointerType smartPointerType = TypeSystem::SmartPointerType::Shared; QString getter; QString refCountMethodName; QString valueCheckMethod; @@ -1347,7 +1356,13 @@ SmartPointerTypeEntry * for (int i = attributes->size() - 1; i >= 0; --i) { const auto name = attributes->at(i).qualifiedName(); if (name == u"type") { - smartPointerType = attributes->takeAt(i).value().toString(); + const auto attribute = attributes->takeAt(i); + const auto typeOpt = smartPointerTypeFromAttribute(attribute.value()); + if (!typeOpt.has_value()) { + m_error = msgInvalidAttributeValue(attribute); + return nullptr; + } + smartPointerType = typeOpt.value(); } else if (name == u"getter") { getter = attributes->takeAt(i).value().toString(); } else if (name == u"ref-count-method") { @@ -1363,15 +1378,6 @@ SmartPointerTypeEntry * } } - if (smartPointerType.isEmpty()) { - m_error = u"No type specified for the smart pointer. Currently supported types: 'shared',"_s; - return nullptr; - } - if (smartPointerType != u"shared") { - m_error = u"Currently only the 'shared' type is supported."_s; - return nullptr; - } - if (getter.isEmpty()) { m_error = u"No function getter name specified for getting the raw pointer held by the smart pointer."_s; return nullptr; diff --git a/sources/shiboken6/doc/typesystem_specifying_types.rst b/sources/shiboken6/doc/typesystem_specifying_types.rst index 164fc002c..e1500d117 100644 --- a/sources/shiboken6/doc/typesystem_specifying_types.rst +++ b/sources/shiboken6/doc/typesystem_specifying_types.rst @@ -601,8 +601,7 @@ smart-pointer-type The ``smart pointer`` type node indicates that the given class is a smart pointer and requires inserting calls to **getter** to access the pointeee. - Currently, only the **type** *shared* is supported and the usage is limited - to function return values. + Currently, the usage is limited to function return values. **ref-count-method** specifies the name of the method used to do reference counting. It is a child of the :ref:`typesystem` node or other type nodes. @@ -619,7 +618,7 @@ smart-pointer-type <typesystem> <smart-pointer-type name="..." since="..." - type="..." + type="shared | handle | value-handle" getter="..." ref-count-method="..." value-check-method="..." @@ -638,6 +637,18 @@ smart-pointer-type The *optional* attribute **reset-method** specifies a method that can be used to clear the pointer. + The *optional* attribute **type** specifies the type: + + *shared* + A standard shared pointer. + *handle* + A basic pointer handle which has a getter function and an + ``operator->``. + *value-handle* + A handle which has a getter function returning a value + (``T`` instead of ``T *`` as for the other types). + It can be used for ``std::optional``. + The example below shows an entry for a ``std::shared_ptr``: .. code-block:: xml diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp index b6189e8d4..0b3a80f95 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp +++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp @@ -391,8 +391,13 @@ static void writePyGetSetDefEntry(TextStream &s, const QString &name, static bool generateRichComparison(const GeneratorContext &c) { - return c.forSmartPointer() - || (!c.metaClass()->isNamespace() && c.metaClass()->hasComparisonOperatorOverload()); + auto *metaClass = c.metaClass(); + if (c.forSmartPointer()) { + auto *te = static_cast<const SmartPointerTypeEntry *>(metaClass->typeEntry()); + return te->smartPointerType() == TypeSystem::SmartPointerType::Shared; + } + + return !metaClass->isNamespace() && metaClass->hasComparisonOperatorOverload(); } void CppGenerator::generateIncludes(TextStream &s, const GeneratorContext &classContext, @@ -821,6 +826,8 @@ void CppGenerator::generateSmartPointerClass(TextStream &s, const GeneratorConte const AbstractMetaClass *metaClass = classContext.metaClass(); const auto *typeEntry = static_cast<const SmartPointerTypeEntry *>(metaClass->typeEntry()); const bool hasPointeeClass = classContext.pointeeClass() != nullptr; + const auto smartPointerType = typeEntry->smartPointerType(); + const bool isValueHandle = smartPointerType ==TypeSystem::SmartPointerType::ValueHandle; IncludeGroup includes{u"Extra includes"_s, typeEntry->extraIncludes()}; generateIncludes(s, classContext, {includes}); @@ -851,7 +858,7 @@ void CppGenerator::generateSmartPointerClass(TextStream &s, const GeneratorConte // methods declared in the type entry. auto ctors = metaClass->queryFunctions(FunctionQueryOption::Constructors); - if (!hasPointeeClass) { // Cannot generate "int*" + if (!hasPointeeClass && !isValueHandle) { // Cannot generate "int*" auto end = std::remove_if(ctors.begin(), ctors.end(), hasParameterPredicate); ctors.erase(end, ctors.end()); } @@ -867,7 +874,7 @@ void CppGenerator::generateSmartPointerClass(TextStream &s, const GeneratorConte if (it == functionGroups.cend()) throw Exception(msgCannotFindSmartPointerMethod(typeEntry, typeEntry->resetMethod())); AbstractMetaFunctionCList resets = it.value(); - if (!hasPointeeClass) { // Cannot generate "int*" + if (!hasPointeeClass && !isValueHandle) { // Cannot generate "int*" auto end = std::remove_if(resets.begin(), resets.end(), hasParameterPredicate); resets.erase(end, resets.end()); } @@ -919,7 +926,8 @@ void CppGenerator::generateSmartPointerClass(TextStream &s, const GeneratorConte if (boolCastOpt.has_value()) writeNbBoolFunction(classContext, boolCastOpt.value(), s); - writeSmartPointerRichCompareFunction(s, classContext); + if (smartPointerType == TypeSystem::SmartPointerType::Shared) + writeSmartPointerRichCompareFunction(s, classContext); s << closeExternC; |