aboutsummaryrefslogtreecommitdiffstats
path: root/sources
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2022-04-01 17:29:04 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2022-05-13 14:54:16 +0200
commitb2dd6f135cd8bb2e113e0ec1ab37f350e3a240b2 (patch)
tree5450c594c85280736ad830c858f12c5a1a3a4795 /sources
parentb6aaca48de358b4cfb3c841f05cc82267a6b47dc (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.cpp5
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem.cpp16
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem.h4
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem_enums.h6
-rw-r--r--sources/shiboken6/ApiExtractor/typesystemparser.cpp28
-rw-r--r--sources/shiboken6/doc/typesystem_specifying_types.rst17
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.cpp18
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;