diff options
| author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2019-12-12 09:59:35 +0100 |
|---|---|---|
| committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2019-12-13 08:49:12 +0100 |
| commit | bbf9de174c92c1c7813d6e9f6320f40a21080df2 (patch) | |
| tree | 8443275abf4a2a5c201b868d705f6c33b8f5e0b0 | |
| parent | a0ed5a2a8cc92209440de755953ca1745aa1d6fa (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.cpp | 6 | ||||
| -rw-r--r-- | sources/shiboken2/ApiExtractor/typedatabase.cpp | 43 | ||||
| -rw-r--r-- | sources/shiboken2/ApiExtractor/typedatabase.h | 4 | ||||
| -rw-r--r-- | sources/shiboken2/ApiExtractor/typesystem.cpp | 9 | ||||
| -rw-r--r-- | sources/shiboken2/ApiExtractor/typesystem.h | 6 |
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" |
