aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/ApiExtractor/abstractmetatype.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken6/ApiExtractor/abstractmetatype.cpp')
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetatype.cpp163
1 files changed, 112 insertions, 51 deletions
diff --git a/sources/shiboken6/ApiExtractor/abstractmetatype.cpp b/sources/shiboken6/ApiExtractor/abstractmetatype.cpp
index 19e030330..3ec07509d 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetatype.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetatype.cpp
@@ -7,6 +7,8 @@
#include "messages.h"
#include "typedatabase.h"
#include "containertypeentry.h"
+#include "enumtypeentry.h"
+#include "flagstypeentry.h"
#include "qtcompat.h"
#include "typeinfo.h"
@@ -17,12 +19,13 @@
#include <QtCore/QHash>
#include <QtCore/QSharedData>
-#include <QtCore/QSharedPointer>
#include <QtCore/QStack>
+#include <memory>
+
using namespace Qt::StringLiterals;
-using AbstractMetaTypeCPtr = QSharedPointer<const AbstractMetaType>;
+using AbstractMetaTypeCPtr = std::shared_ptr<const AbstractMetaType>;
const QSet<QString> &AbstractMetaType::cppFloatTypes()
{
@@ -116,6 +119,7 @@ public:
QString formatPythonSignature() const;
bool isEquivalent(const AbstractMetaTypeData &rhs) const;
bool equals(const AbstractMetaTypeData &rhs) const;
+ QStringList instantiationCppSignatures() const;
template <class Predicate>
bool generateOpaqueContainer(Predicate p) const;
@@ -151,6 +155,14 @@ AbstractMetaTypeData::AbstractMetaTypeData(const TypeEntryCPtr &t) :
{
}
+QStringList AbstractMetaTypeData::instantiationCppSignatures() const
+{
+ QStringList result;
+ for (const auto &i : m_instantiations)
+ result.append(i.cppSignature());
+ return result;
+}
+
AbstractMetaType::AbstractMetaType(const TypeEntryCPtr &t) :
d(new AbstractMetaTypeData(t))
{
@@ -166,9 +178,9 @@ AbstractMetaType &AbstractMetaType::operator=(const AbstractMetaType &) = defaul
AbstractMetaType::AbstractMetaType(const AbstractMetaType &rhs) = default;
-AbstractMetaType::AbstractMetaType(AbstractMetaType &&) = default;
+AbstractMetaType::AbstractMetaType(AbstractMetaType &&) noexcept = default;
-AbstractMetaType &AbstractMetaType::operator=(AbstractMetaType &&) = default;
+AbstractMetaType &AbstractMetaType::operator=(AbstractMetaType &&) noexcept = default;
AbstractMetaType::~AbstractMetaType() = default;
@@ -219,6 +231,11 @@ const AbstractMetaTypeList &AbstractMetaType::instantiations() const
return d->m_instantiations;
}
+QStringList AbstractMetaType::instantiationCppSignatures() const
+{
+ return d->instantiationCppSignatures();
+}
+
// For applying the <array> function argument modification: change into a type
// where "int *" becomes "int[]".
bool AbstractMetaType::applyArrayModification(QString *errorMessage)
@@ -228,7 +245,7 @@ bool AbstractMetaType::applyArrayModification(QString *errorMessage)
*errorMessage = u"<array> modification already applied."_s;
return false;
}
- if (!d->m_arrayElementType.isNull()) {
+ if (d->m_arrayElementType) {
QTextStream(errorMessage) << "The type \"" << cppSignature()
<< "\" is an array of " << d->m_arrayElementType->name() << '.';
return false;
@@ -276,13 +293,13 @@ QString AbstractMetaType::originalTypeDescription() const
void AbstractMetaType::setOriginalTemplateType(const AbstractMetaType &type)
{
- if (d->m_originalTemplateType.isNull() || *d->m_originalTemplateType != type)
+ if (!d->m_originalTemplateType || *d->m_originalTemplateType != type)
d->m_originalTemplateType.reset(new AbstractMetaType(type));
}
const AbstractMetaType *AbstractMetaType::originalTemplateType() const
{
- return d->m_originalTemplateType.data();
+ return d->m_originalTemplateType.get();
}
AbstractMetaType AbstractMetaType::getSmartPointerInnerType() const
@@ -311,7 +328,7 @@ AbstractMetaTypeList AbstractMetaType::nestedArrayTypes() const
}
break;
case NativePointerAsArrayPattern:
- result.append(*d->m_arrayElementType.data());
+ result.append(*d->m_arrayElementType.get());
break;
default:
break;
@@ -339,6 +356,12 @@ bool AbstractMetaType::passByValue() const
return d->passByValue();
}
+bool AbstractMetaType::useStdMove() const
+{
+ return (isUniquePointer() && d->passByValue())
+ || d->m_referenceType == RValueReference;
+}
+
ReferenceType AbstractMetaType::referenceType() const
{
return d->m_referenceType;
@@ -417,17 +440,28 @@ int AbstractMetaType::arrayElementCount() const
const AbstractMetaType *AbstractMetaType::arrayElementType() const
{
- return d->m_arrayElementType.data();
+ return d->m_arrayElementType.get();
}
void AbstractMetaType::setArrayElementType(const AbstractMetaType &t)
{
- if (d->m_arrayElementType.isNull() || *d->m_arrayElementType != t) {
+ if (!d->m_arrayElementType || *d->m_arrayElementType != t) {
d->m_arrayElementType.reset(new AbstractMetaType(t));
d->m_signaturesDirty = true;
}
}
+AbstractMetaType AbstractMetaType::plainType() const
+{
+ AbstractMetaType result = *this;
+ result.clearIndirections();
+ result.setReferenceType(NoReference);
+ result.setConstant(false);
+ result.setVolatile(false);
+ result.decideUsagePattern();
+ return result;
+}
+
QString AbstractMetaType::cppSignature() const
{
const AbstractMetaTypeData *cd = d.constData();
@@ -509,6 +543,7 @@ void AbstractMetaType::decideUsagePattern()
pattern = ObjectPattern;
}
setTypeUsagePattern(pattern);
+ Q_ASSERT(pattern != ContainerPattern || !d->m_instantiations.isEmpty());
}
bool AbstractMetaTypeData::hasTemplateChildren() const
@@ -542,6 +577,29 @@ static inline QString formatArraySize(int e)
return result;
}
+// Return the number of template parameters; remove the default
+// non template type parameter of std::span from the signature.
+static qsizetype stripDefaultTemplateArgs(const TypeEntryCPtr &te,
+ const AbstractMetaTypeList &instantiations)
+{
+ static const char16_t dynamicExtent64[] = u"18446744073709551615"; // size_t(-1)
+ static const char16_t dynamicExtent32[] = u"4294967295";
+
+ qsizetype result = instantiations.size();
+ if (result == 0 || !te->isContainer())
+ return result;
+ auto cte = std::static_pointer_cast<const ContainerTypeEntry>(te);
+ if (cte->containerKind() != ContainerTypeEntry::SpanContainer)
+ return result;
+ const auto lastTe = instantiations.constLast().typeEntry();
+ if (lastTe->type() == TypeEntry::ConstantValueType) {
+ const QString &name = lastTe->name();
+ if (name == dynamicExtent64 || name == dynamicExtent32)
+ --result;
+ }
+ return result;
+}
+
QString AbstractMetaTypeData::formatSignature(bool minimal) const
{
QString result;
@@ -564,12 +622,13 @@ QString AbstractMetaTypeData::formatSignature(bool minimal) const
result += u'<';
if (minimal)
result += u' ';
- for (qsizetype i = 0, size = m_instantiations.size(); i < size; ++i) {
+ const auto size = stripDefaultTemplateArgs(m_typeEntry, m_instantiations);
+ for (qsizetype i = 0; i < size; ++i) {
if (i > 0)
result += u',';
result += m_instantiations.at(i).minimalSignature();
}
- result += u" >"_s;
+ result += u'>';
}
if (!minimal && (!m_indirections.isEmpty() || m_referenceType != NoReference))
@@ -642,10 +701,12 @@ QString AbstractMetaTypeData::formatPythonSignature() const
if (m_typeEntry->isPrimitive())
for (Indirection i : m_indirections)
result += TypeInfo::indirectionKeyword(i);
- // If it is a flags type, we replace it with the full name:
- // "PySide6.QtCore.Qt.ItemFlags" instead of "PySide6.QtCore.QFlags<Qt.ItemFlag>"
- if (m_typeEntry->isFlags())
- result = m_typeEntry->qualifiedTargetLangName();
+ // If it is a flags type, we replace it with the full name of the enum:
+ // "PySide6.QtCore.Qt.ItemFlag" instead of "PySide6.QtCore.QFlags<Qt.ItemFlag>"
+ if (m_typeEntry->isFlags()) {
+ const auto fte = std::static_pointer_cast<const FlagsTypeEntry>(m_typeEntry);
+ result = fte->originator()->qualifiedTargetLangName();
+ }
result.replace(u"::"_s, u"."_s);
return result;
}
@@ -688,9 +749,9 @@ void AbstractMetaType::setVolatile(bool v)
static bool equalsCPtr(const AbstractMetaTypeCPtr &t1, const AbstractMetaTypeCPtr &t2)
{
- if (t1.isNull() != t2.isNull())
+ if (bool(t1) != bool(t2))
return false;
- return t1.isNull() || *t1 == *t2;
+ return !t1 || *t1 == *t2;
}
bool AbstractMetaTypeData::isEquivalent(const AbstractMetaTypeData &rhs) const
@@ -718,9 +779,9 @@ bool AbstractMetaTypeData::equals(const AbstractMetaTypeData &rhs) const
&& m_referenceType == rhs.m_referenceType && isEquivalent(rhs);
}
-bool AbstractMetaType::equals(const AbstractMetaType &rhs) const
+bool comparesEqual(const AbstractMetaType &lhs, const AbstractMetaType &rhs) noexcept
{
- return d->equals(*rhs.d);
+ return lhs.d->equals(*rhs.d);
}
bool AbstractMetaType::isEquivalent(const AbstractMetaType &rhs) const
@@ -730,12 +791,12 @@ bool AbstractMetaType::isEquivalent(const AbstractMetaType &rhs) const
const AbstractMetaType *AbstractMetaType::viewOn() const
{
- return d->m_viewOn.data();
+ return d->m_viewOn.get();
}
void AbstractMetaType::setViewOn(const AbstractMetaType &v)
{
- if (d->m_viewOn.isNull() || *d->m_viewOn != v)
+ if (!d->m_viewOn || *d->m_viewOn != v)
d->m_viewOn.reset(new AbstractMetaType(v));
}
@@ -744,7 +805,7 @@ AbstractMetaType AbstractMetaType::createVoid()
static QScopedPointer<AbstractMetaType> metaType;
if (metaType.isNull()) {
static TypeEntryCPtr voidTypeEntry = TypeDatabase::instance()->findType(u"void"_s);
- Q_ASSERT(!voidTypeEntry.isNull());
+ Q_ASSERT(voidTypeEntry);
metaType.reset(new AbstractMetaType(voidTypeEntry));
metaType->decideUsagePattern();
}
@@ -871,7 +932,7 @@ bool AbstractMetaType::isValueTypeWithCopyConstructorOnly() const
{
bool result = false;
if (d->m_typeEntry->isComplex()) {
- const auto cte = qSharedPointerCast<const ComplexTypeEntry>(d->m_typeEntry);
+ const auto cte = std::static_pointer_cast<const ComplexTypeEntry>(d->m_typeEntry);
result = cte->isValueTypeWithCopyConstructorOnly();
}
return result;
@@ -888,14 +949,18 @@ using AbstractMetaTypeCache = QHash<QString, AbstractMetaType>;
Q_GLOBAL_STATIC(AbstractMetaTypeCache, metaTypeFromStringCache)
std::optional<AbstractMetaType>
-AbstractMetaType::fromString(QString typeSignature, QString *errorMessage)
+AbstractMetaType::fromString(const QString &typeSignatureIn, QString *errorMessage)
{
- typeSignature = typeSignature.trimmed();
+ auto &cache = *metaTypeFromStringCache();
+ auto it = cache.find(typeSignatureIn);
+ if (it != cache.end())
+ return it.value();
+
+ QString typeSignature = typeSignatureIn.trimmed();
if (typeSignature.startsWith(u"::"))
typeSignature.remove(0, 2);
- auto &cache = *metaTypeFromStringCache();
- auto it = cache.find(typeSignature);
+ it = cache.find(typeSignature);
if (it == cache.end()) {
auto metaType =
AbstractMetaBuilder::translateType(typeSignature, nullptr, {}, errorMessage);
@@ -904,6 +969,8 @@ AbstractMetaType::fromString(QString typeSignature, QString *errorMessage)
errorMessage->prepend(msgCannotBuildMetaType(typeSignature));
return {};
}
+ if (typeSignature != typeSignatureIn)
+ cache.insert(typeSignatureIn, metaType.value());
it = cache.insert(typeSignature, metaType.value());
}
return it.value();
@@ -918,16 +985,12 @@ AbstractMetaType AbstractMetaType::fromTypeEntry(const TypeEntryCPtr &typeEntry)
auto it = cache.find(typeName);
if (it != cache.end())
return it.value();
- AbstractMetaType metaType(typeEntry);
- metaType.clearIndirections();
- metaType.setReferenceType(NoReference);
- metaType.setConstant(false);
- metaType.decideUsagePattern();
+ AbstractMetaType metaType = AbstractMetaType(typeEntry).plainType();
cache.insert(typeName, metaType);
return metaType;
}
-AbstractMetaType AbstractMetaType::fromAbstractMetaClass(const AbstractMetaClass *metaClass)
+AbstractMetaType AbstractMetaType::fromAbstractMetaClass(const AbstractMetaClassCPtr &metaClass)
{
return fromTypeEntry(metaClass->typeEntry());
}
@@ -940,37 +1003,34 @@ bool AbstractMetaTypeData::generateOpaqueContainer(Predicate pred) const
return false;
if (m_indirections.size() > 1)
return false;
- auto containerTypeEntry = qSharedPointerCast<const ContainerTypeEntry>(m_typeEntry);
+ auto containerTypeEntry = std::static_pointer_cast<const ContainerTypeEntry>(m_typeEntry);
auto kind = containerTypeEntry->containerKind();
- if (kind != ContainerTypeEntry::ListContainer)
- return false;
- const auto &instantation = m_instantiations.constFirst();
- if (instantation.referenceType() != NoReference)
+ if (kind != ContainerTypeEntry::ListContainer && kind != ContainerTypeEntry::SpanContainer)
return false;
- const QString signature = instantation.cppSignature();
- bool result = false;
- auto instTypEntry = instantation.typeEntry();
- switch (instTypEntry->type()) {
+ const auto &firstInstantiation = m_instantiations.constFirst();
+ if (firstInstantiation.referenceType() != NoReference)
+ return false;
+ switch (firstInstantiation.typeEntry()->type()) {
case TypeEntry::PrimitiveType:
case TypeEntry::FlagsType:
case TypeEntry::EnumType:
case TypeEntry::BasicValueType:
case TypeEntry::ObjectType:
case TypeEntry::CustomType:
- result = pred(containerTypeEntry, signature);
break;
default:
- break;
+ return false;
}
- return result;
+
+ return pred(containerTypeEntry, instantiationCppSignatures());
}
// Simple predicate for checking whether an opaque container should be generated
static bool opaqueContainerPredicate(const ContainerTypeEntryCPtr &t,
- const QString &signature)
+ const QStringList &instantiations)
{
- return t->generateOpaqueContainer(signature);
+ return t->generateOpaqueContainer(instantiations);
}
bool AbstractMetaType::generateOpaqueContainer() const
@@ -983,8 +1043,9 @@ bool AbstractMetaType::generateOpaqueContainer() const
// (cf AbstractMetaFunction::generateOpaqueContainerReturn())
bool AbstractMetaType::generateOpaqueContainerForGetter(const QString &modifiedType) const
{
- auto predicate = [&modifiedType](const ContainerTypeEntryCPtr &t, const QString &signature) {
- return t->opaqueContainerName(signature) == modifiedType;
+ auto predicate = [&modifiedType](const ContainerTypeEntryCPtr &t,
+ const QStringList &instantiations) {
+ return t->opaqueContainerName(instantiations) == modifiedType;
};
return d->generateOpaqueContainer(predicate);
}
@@ -1008,7 +1069,7 @@ void AbstractMetaType::formatDebug(QDebug &debug) const
for (auto i : indirections)
debug << ' ' << TypeInfo::indirectionKeyword(i);
}
- if (referenceType())
+ if (referenceType() != NoReference)
debug << ", reftype=" << referenceType();
if (isConstant())
debug << ", [const]";