aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/ApiExtractor
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2020-09-02 10:52:18 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2020-09-30 08:21:03 +0000
commit0f922f604297a2022527f04a696da121396ddc0a (patch)
tree5a40599046ff6ab940aff6d639530237ce08c4d8 /sources/shiboken2/ApiExtractor
parent7af97fa4136d66bbad6c7907de6e7bd823de2e43 (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.cpp11
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.cpp5
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.h10
-rw-r--r--sources/shiboken2/ApiExtractor/messages.cpp6
-rw-r--r--sources/shiboken2/ApiExtractor/messages.h2
-rw-r--r--sources/shiboken2/ApiExtractor/typedatabase.cpp2
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.h7
-rw-r--r--sources/shiboken2/ApiExtractor/typesystemparser.cpp52
-rw-r--r--sources/shiboken2/ApiExtractor/typesystemparser.h4
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 *);