aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2019-12-12 09:59:35 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2019-12-13 08:49:12 +0100
commitbbf9de174c92c1c7813d6e9f6320f40a21080df2 (patch)
tree8443275abf4a2a5c201b868d705f6c33b8f5e0b0
parenta0ed5a2a8cc92209440de755953ca1745aa1d6fa (diff)
shiboken/TypeDatabase: Add a look up for names excluding inline namespaces
Ensure for example the std::shared_ptr of AppleClang STL is found which is in an inline namespace std::__1. Add a shortName() to TypeEntry to represent the name and add lookups for it to the TypeDatabase once an inline namespace is traversed. Task-number: PYSIDE-454 Task-number: PYSIDE-990 Change-Id: I21d86ba3a77926d0910f11201cbd8978c13ca705 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp6
-rw-r--r--sources/shiboken2/ApiExtractor/typedatabase.cpp43
-rw-r--r--sources/shiboken2/ApiExtractor/typedatabase.h4
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.cpp9
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.h6
5 files changed, 65 insertions, 3 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
index 1adbb52d4..f6c9e407c 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
@@ -755,7 +755,11 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel
<< QStringLiteral("namespace '%1' does not have a type entry").arg(namespaceName);
return nullptr;
}
- type->setInlineNamespace(namespaceItem->type() == NamespaceType::Inline);
+
+ if (namespaceItem->type() == NamespaceType::Inline) {
+ type->setInlineNamespace(true);
+ TypeDatabase::instance()->addInlineNamespaceLookups(type);
+ }
// Continue populating namespace?
AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_metaClasses, type);
diff --git a/sources/shiboken2/ApiExtractor/typedatabase.cpp b/sources/shiboken2/ApiExtractor/typedatabase.cpp
index 659a69922..c952f7b0e 100644
--- a/sources/shiboken2/ApiExtractor/typedatabase.cpp
+++ b/sources/shiboken2/ApiExtractor/typedatabase.cpp
@@ -149,6 +149,20 @@ void TypeDatabase::addSystemInclude(const QString &name)
m_systemIncludes.append(name.toUtf8());
}
+// Add a lookup for the short name excluding inline namespaces
+// so that "std::shared_ptr" finds "std::__1::shared_ptr" as well.
+// Note: This inserts duplicate TypeEntry * into m_entries.
+void TypeDatabase::addInlineNamespaceLookups(const NamespaceTypeEntry *n)
+{
+ QVector<TypeEntry *> additionalEntries; // Store before modifying the hash
+ for (TypeEntry *entry : m_entries) {
+ if (entry->isChildOf(n))
+ additionalEntries.append(entry);
+ }
+ for (const auto &ae : additionalEntries)
+ m_entries.insert(ae->shortName(), ae);
+}
+
ContainerTypeEntry* TypeDatabase::findContainerType(const QString &name) const
{
QString template_name = name;
@@ -703,6 +717,35 @@ static void _computeTypeIndexes()
computeTypeIndexes = false;
}
+// Build the C++ name excluding any inline namespaces
+// ("std::__1::shared_ptr" -> "std::shared_ptr"
+QString TypeEntry::shortName() const
+{
+ if (m_cachedShortName.isEmpty()) {
+ QVarLengthArray<const TypeEntry *> parents;
+ bool foundInlineNamespace = false;
+ for (auto p = m_parent; p != nullptr && p->type() != TypeEntry::TypeSystemType; p = p->parent()) {
+ if (p->type() == TypeEntry::NamespaceType
+ && static_cast<const NamespaceTypeEntry *>(p)->isInlineNamespace()) {
+ foundInlineNamespace = true;
+ } else {
+ parents.append(p);
+ }
+ }
+ if (foundInlineNamespace) {
+ m_cachedShortName.reserve(m_name.size());
+ for (int i = parents.size() - 1; i >= 0; --i) {
+ m_cachedShortName.append(parents.at(i)->entryName());
+ m_cachedShortName.append(QLatin1String("::"));
+ }
+ m_cachedShortName.append(m_entryName);
+ } else {
+ m_cachedShortName = m_name;
+ }
+ }
+ return m_cachedShortName;
+}
+
void TypeEntry::setRevision(int r)
{
if (m_revision != r) {
diff --git a/sources/shiboken2/ApiExtractor/typedatabase.h b/sources/shiboken2/ApiExtractor/typedatabase.h
index 6d800a3f0..f1bd0ac9f 100644
--- a/sources/shiboken2/ApiExtractor/typedatabase.h
+++ b/sources/shiboken2/ApiExtractor/typedatabase.h
@@ -87,6 +87,8 @@ public:
const QByteArrayList &systemIncludes() const { return m_systemIncludes; }
void addSystemInclude(const QString &name);
+ void addInlineNamespaceLookups(const NamespaceTypeEntry *n);
+
PrimitiveTypeEntry *findPrimitiveType(const QString &name) const;
ComplexTypeEntry *findComplexType(const QString &name) const;
ObjectTypeEntry *findObjectType(const QString &name) const;
@@ -174,7 +176,7 @@ private:
TypeEntry *resolveTypeDefEntry(TypedefEntry *typedefEntry, QString *errorMessage);
bool m_suppressWarnings = true;
- TypeEntryMultiMap m_entries;
+ TypeEntryMultiMap m_entries; // Contains duplicate entries (cf addInlineNamespaceLookups).
TypeEntryMap m_flagsEntries;
TypedefEntryMap m_typedefEntries;
TemplateEntryMap m_templates;
diff --git a/sources/shiboken2/ApiExtractor/typesystem.cpp b/sources/shiboken2/ApiExtractor/typesystem.cpp
index 637dde363..f8199622a 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.cpp
+++ b/sources/shiboken2/ApiExtractor/typesystem.cpp
@@ -684,6 +684,15 @@ TypeEntry::~TypeEntry()
delete m_customConversion;
}
+bool TypeEntry::isChildOf(const TypeEntry *p) const
+{
+ for (auto e = m_parent; e; e = e->parent()) {
+ if (e == p)
+ return true;
+ }
+ return false;
+}
+
const TypeSystemTypeEntry *TypeEntry::typeSystemTypeEntry() const
{
for (auto e = this; e; e = e->parent()) {
diff --git a/sources/shiboken2/ApiExtractor/typesystem.h b/sources/shiboken2/ApiExtractor/typesystem.h
index 8e155eb60..d0739c19b 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.h
+++ b/sources/shiboken2/ApiExtractor/typesystem.h
@@ -599,6 +599,7 @@ public:
const TypeEntry *parent() const { return m_parent; }
void setParent(const TypeEntry *p) { m_parent = p; }
+ bool isChildOf(const TypeEntry *p) const;
const TypeSystemTypeEntry *typeSystemTypeEntry() const;
// cf AbstractMetaClass::targetLangEnclosingClass()
const TypeEntry *targetLangEnclosingEntry() const;
@@ -680,6 +681,8 @@ public:
// The type's name in C++, fully qualified
QString name() const { return m_name; }
+ // C++ excluding inline namespaces
+ QString shortName() const;
// Name as specified in XML
QString entryName() const { return m_entryName; }
@@ -868,7 +871,8 @@ protected:
private:
const TypeEntry *m_parent;
- QString m_name; // fully qualified
+ QString m_name; // C++ fully qualified
+ mutable QString m_cachedShortName; // C++ excluding inline namespaces
QString m_entryName;
QString m_targetLangPackage;
mutable QString m_cachedTargetLangName; // "Foo.Bar"