diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2020-09-02 10:52:18 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2020-09-30 08:21:03 +0000 |
commit | 0f922f604297a2022527f04a696da121396ddc0a (patch) | |
tree | 5a40599046ff6ab940aff6d639530237ce08c4d8 /sources/shiboken2/ApiExtractor | |
parent | 7af97fa4136d66bbad6c7907de6e7bd823de2e43 (diff) |
Add QStringView/QByteArrayView
View types as function parameters cannot be converted in the standard
way shiboken does it:
QStringView cppArg0;
pythonToCpp(pyArg, &cppArg0);
since they reference some other data.
Introduce a new "viewOn" member to type system entry for them. It
causes the function arguments to be replaced by their viewed-on types
(stringview->string) via metatype.
Add a test in libsample and a test for QUuid::fromString(QStringView).
Test returning QStringView via QRegularExpressionMatch::capturedView().
Task-number: QTBUG-84319
Task-number: PYSIDE-1339
Task-number: PYSIDE-904
Task-number: PYSIDE-487
Change-Id: Iddb4ea268a54928d290e29012e2738772fae83f0
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'sources/shiboken2/ApiExtractor')
-rw-r--r-- | sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp | 11 | ||||
-rw-r--r-- | sources/shiboken2/ApiExtractor/abstractmetalang.cpp | 5 | ||||
-rw-r--r-- | sources/shiboken2/ApiExtractor/abstractmetalang.h | 10 | ||||
-rw-r--r-- | sources/shiboken2/ApiExtractor/messages.cpp | 6 | ||||
-rw-r--r-- | sources/shiboken2/ApiExtractor/messages.h | 2 | ||||
-rw-r--r-- | sources/shiboken2/ApiExtractor/typedatabase.cpp | 2 | ||||
-rw-r--r-- | sources/shiboken2/ApiExtractor/typesystem.h | 7 | ||||
-rw-r--r-- | sources/shiboken2/ApiExtractor/typesystemparser.cpp | 52 | ||||
-rw-r--r-- | sources/shiboken2/ApiExtractor/typesystemparser.h | 4 |
9 files changed, 85 insertions, 14 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp index 899d910bc..d06a338a3 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp @@ -1884,6 +1884,17 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio return nullptr; } + // Add view substitution for simple view types of function arguments + // std::string_view -> std::string for foo(std::string_view) + auto viewOnTypeEntry = metaType->typeEntry()->viewOn(); + if (viewOnTypeEntry != nullptr && metaType->indirections() == 0 + && metaType->arrayElementType() == nullptr + && !metaType->hasInstantiations()) { + auto viewOn = new AbstractMetaType(*metaType); + viewOn->setTypeEntry(viewOnTypeEntry); + metaType->setViewOn(viewOn); + } + auto *metaArgument = new AbstractMetaArgument; metaArgument->setType(metaType); diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp index 7d98d9ae8..edb449b04 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp @@ -194,10 +194,13 @@ AbstractMetaType::AbstractMetaType() : { } +AbstractMetaType::AbstractMetaType(const AbstractMetaType &rhs) = default; + AbstractMetaType::~AbstractMetaType() { qDeleteAll(m_children); m_instantiations.clear(); + delete m_viewOn; } QString AbstractMetaType::package() const @@ -449,6 +452,8 @@ QDebug operator<<(QDebug d, const AbstractMetaType *at) } } d << '>'; + if (at->viewOn()) + d << ", views " << at->viewOn()->name(); } } else { d << '0'; diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h index 648c792b3..0e187fbcf 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.h +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h @@ -303,6 +303,7 @@ public: Q_DECLARE_FLAGS(ComparisonFlags, ComparisonFlag); AbstractMetaType(); + AbstractMetaType(const AbstractMetaType &); ~AbstractMetaType(); QString package() const; @@ -530,6 +531,12 @@ public: bool compare(const AbstractMetaType &rhs, ComparisonFlags = {}) const; + // View on: Type to use for function argument conversion, fex + // std::string_view -> std::string for foo(std::string_view); + // cf TypeEntry::viewOn() + const AbstractMetaType *viewOn() const { return m_viewOn; } + void setViewOn(const AbstractMetaType *v) { m_viewOn = v; } + private: TypeUsagePattern determineUsagePattern() const; QString formatSignature(bool minimal) const; @@ -545,6 +552,7 @@ private: int m_arrayElementCount = -1; const AbstractMetaType *m_arrayElementType = nullptr; const AbstractMetaType *m_originalTemplateType = nullptr; + const AbstractMetaType *m_viewOn = nullptr; Indirections m_indirections; TypeUsagePattern m_pattern = InvalidPattern; @@ -555,8 +563,6 @@ private: ReferenceType m_referenceType = NoReference; AbstractMetaTypeList m_children; - - Q_DISABLE_COPY(AbstractMetaType) }; Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaType::ComparisonFlags); diff --git a/sources/shiboken2/ApiExtractor/messages.cpp b/sources/shiboken2/ApiExtractor/messages.cpp index 55c51ffa4..a660f7e76 100644 --- a/sources/shiboken2/ApiExtractor/messages.cpp +++ b/sources/shiboken2/ApiExtractor/messages.cpp @@ -649,6 +649,12 @@ QString msgIncorrectlyNestedName(const QString &name) + name + QLatin1String(")."); } +QString msgCannotFindView(const QString &viewedName, const QString &name) +{ + return QLatin1String("Unable to find viewed type ") + viewedName + + QLatin1String(" for ") + name; +} + // qtdocgenerator.cpp QString msgTagWarning(const QXmlStreamReader &reader, const QString &context, diff --git a/sources/shiboken2/ApiExtractor/messages.h b/sources/shiboken2/ApiExtractor/messages.h index 6c173dc09..55481270c 100644 --- a/sources/shiboken2/ApiExtractor/messages.h +++ b/sources/shiboken2/ApiExtractor/messages.h @@ -179,6 +179,8 @@ QString msgNoRootTypeSystemEntry(); QString msgIncorrectlyNestedName(const QString &name); +QString msgCannotFindView(const QString &viewedName, const QString &name); + QString msgCyclicDependency(const QString &funcName, const QString &graphName, const QVector<const AbstractMetaFunction *> &involvedConversions); diff --git a/sources/shiboken2/ApiExtractor/typedatabase.cpp b/sources/shiboken2/ApiExtractor/typedatabase.cpp index 6aa5513fa..87f5c49df 100644 --- a/sources/shiboken2/ApiExtractor/typedatabase.cpp +++ b/sources/shiboken2/ApiExtractor/typedatabase.cpp @@ -894,6 +894,8 @@ void TypeEntry::formatDebug(QDebug &d) const FORMAT_BOOL("stream", m_stream) FORMAT_LIST_SIZE("codeSnips", m_codeSnips) FORMAT_NONEMPTY_STRING("conversionRule", m_conversionRule) + if (m_viewOn) + d << ", views=" << m_viewOn->name(); if (!m_version.isNull() && m_version > QVersionNumber(0, 0)) d << ", version=" << m_version; if (m_revision) diff --git a/sources/shiboken2/ApiExtractor/typesystem.h b/sources/shiboken2/ApiExtractor/typesystem.h index fa3eae9fc..00f56c51e 100644 --- a/sources/shiboken2/ApiExtractor/typesystem.h +++ b/sources/shiboken2/ApiExtractor/typesystem.h @@ -863,6 +863,12 @@ public: void setCustomConversion(CustomConversion* customConversion); CustomConversion* customConversion() const; + // View on: Type to use for function argument conversion, fex + // std::string_view -> std::string for foo(std::string_view). + // cf AbstractMetaType::viewOn() + TypeEntry *viewOn() const { return m_viewOn; } + void setViewOn(TypeEntry *v) { m_viewOn = v; } + virtual TypeEntry *clone() const; void useAsTypedef(const TypeEntry *source); @@ -898,6 +904,7 @@ private: CustomConversion *m_customConversion = nullptr; SourceLocation m_sourceLocation; // XML file uint m_codeGeneration = GenerateAll; + TypeEntry *m_viewOn = nullptr; int m_revision = 0; int m_sbkIndex = 0; Type m_type; diff --git a/sources/shiboken2/ApiExtractor/typesystemparser.cpp b/sources/shiboken2/ApiExtractor/typesystemparser.cpp index b71a247f3..7323e01f6 100644 --- a/sources/shiboken2/ApiExtractor/typesystemparser.cpp +++ b/sources/shiboken2/ApiExtractor/typesystemparser.cpp @@ -1112,16 +1112,44 @@ bool TypeSystemParser::checkRootElement() return ok; } -void TypeSystemParser::applyCommonAttributes(const QXmlStreamReader &reader, TypeEntry *type, - QXmlStreamAttributes *attributes) const +static TypeEntry *findViewedType(const QString &name) +{ + const auto range = TypeDatabase::instance()->entries().equal_range(name); + for (auto i = range.first; i != range.second; ++i) { + switch (i.value()->type()) { + case TypeEntry::BasicValueType: + case TypeEntry::PrimitiveType: + case TypeEntry::ContainerType: + case TypeEntry::ObjectType: + return i.value(); + default: + break; + } + } + return nullptr; +} + +bool TypeSystemParser::applyCommonAttributes(const QXmlStreamReader &reader, TypeEntry *type, + QXmlStreamAttributes *attributes) { type->setSourceLocation(SourceLocation(m_currentFile, reader.lineNumber())); type->setCodeGeneration(m_generate); - const int revisionIndex = - indexOfAttribute(*attributes, u"revision"); - if (revisionIndex != -1) - type->setRevision(attributes->takeAt(revisionIndex).value().toInt()); + for (int i = attributes->size() - 1; i >= 0; --i) { + const auto name = attributes->at(i).qualifiedName(); + if (name == u"revision") { + type->setRevision(attributes->takeAt(i).value().toInt()); + } else if (name == u"view-on") { + const QString name = attributes->takeAt(i).value().toString(); + TypeEntry *views = findViewedType(name); + if (views == nullptr) { + m_error = msgCannotFindView(name, type->name()); + return false; + } + type->setViewOn(views); + } + } + return true; } FlagsTypeEntry * @@ -1146,7 +1174,8 @@ FlagsTypeEntry * } ftype->setOriginalName(flagName); - applyCommonAttributes(reader, ftype, attributes); + if (!applyCommonAttributes(reader, ftype, attributes)) + return nullptr; QStringList lst = flagName.split(colonColon()); const QString targetLangFlagName = QStringList(lst.mid(0, lst.size() - 1)).join(QLatin1Char('.')); @@ -1225,7 +1254,8 @@ SmartPointerTypeEntry * auto *type = new SmartPointerTypeEntry(name, getter, smartPointerType, refCountMethodName, since, currentParentTypeEntry()); - applyCommonAttributes(reader, type, attributes); + if (!applyCommonAttributes(reader, type, attributes)) + return nullptr; m_smartPointerInstantiations.insert(type, instantiations); return type; } @@ -1238,7 +1268,8 @@ PrimitiveTypeEntry * if (!checkRootElement()) return nullptr; auto *type = new PrimitiveTypeEntry(name, since, currentParentTypeEntry()); - applyCommonAttributes(reader, type, attributes); + if (!applyCommonAttributes(reader, type, attributes)) + return nullptr; for (int i = attributes->size() - 1; i >= 0; --i) { const auto name = attributes->at(i).qualifiedName(); if (name == targetLangNameAttribute()) { @@ -1282,7 +1313,8 @@ ContainerTypeEntry * return nullptr; } auto *type = new ContainerTypeEntry(name, containerType, since, currentParentTypeEntry()); - applyCommonAttributes(reader, type, attributes); + if (!applyCommonAttributes(reader, type, attributes)) + return nullptr; return type; } diff --git a/sources/shiboken2/ApiExtractor/typesystemparser.h b/sources/shiboken2/ApiExtractor/typesystemparser.h index 3eaa74f04..130d8d3d2 100644 --- a/sources/shiboken2/ApiExtractor/typesystemparser.h +++ b/sources/shiboken2/ApiExtractor/typesystemparser.h @@ -169,8 +169,8 @@ private: const TypeEntry *currentParentTypeEntry() const; bool checkRootElement(); - void applyCommonAttributes(const QXmlStreamReader &reader, TypeEntry *type, - QXmlStreamAttributes *attributes) const; + bool applyCommonAttributes(const QXmlStreamReader &reader, TypeEntry *type, + QXmlStreamAttributes *attributes); PrimitiveTypeEntry * parsePrimitiveTypeEntry(const QXmlStreamReader &, const QString &name, const QVersionNumber &since, QXmlStreamAttributes *); |