From bfd065a98865ad1fafeacc8a4a140fecd73ddd38 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 13 Jul 2018 11:06:39 +0200 Subject: shiboken: Make revision and SBK index a member of TypeEntry They were previously stored in a global hash, apparently due to BC issues. Replace the global set/getTypeIndex/Revision functions by member functions of TypeEntry in typedatabase.cpp. As a drive-by change, simplify the code assigning the SBK numbers to use a flat list of entries ordered by revision and name instead of a grouped hash (bearing in mind that revision is rarely used) and might be removed one day). Also replace the use of std::unique() by the !contains()/append() pattern since std::unique() assumes an ordered list which is likely not the case. Task-number: PYSIDE-725 Task-number: PYSIDE-743 Change-Id: I9356acf1f5795446c08f266c1323f1db65cd490c Reviewed-by: Christian Tismer --- .../ApiExtractor/tests/testtyperevision.cpp | 15 +++--- sources/shiboken2/ApiExtractor/typedatabase.cpp | 58 ++++++++++------------ sources/shiboken2/ApiExtractor/typedatabase.h | 3 -- sources/shiboken2/ApiExtractor/typesystem.cpp | 4 +- sources/shiboken2/ApiExtractor/typesystem.h | 7 +++ 5 files changed, 42 insertions(+), 45 deletions(-) (limited to 'sources/shiboken2/ApiExtractor') diff --git a/sources/shiboken2/ApiExtractor/tests/testtyperevision.cpp b/sources/shiboken2/ApiExtractor/tests/testtyperevision.cpp index 1ec7ce025..a3130e499 100644 --- a/sources/shiboken2/ApiExtractor/tests/testtyperevision.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testtyperevision.cpp @@ -49,21 +49,22 @@ void TestTypeRevision::testRevisionAttr() QVERIFY(!builder.isNull()); AbstractMetaClassList classes = builder->classes(); const AbstractMetaClass *rev0 = AbstractMetaClass::findClass(classes, QLatin1String("Rev_0")); - QCOMPARE(getTypeRevision(rev0->typeEntry()), 0); + QCOMPARE(rev0->typeEntry()->revision(), 0); const AbstractMetaClass *rev1 = AbstractMetaClass::findClass(classes, QLatin1String("Rev_1")); - QCOMPARE(getTypeRevision(rev1->typeEntry()), 1); + QCOMPARE(rev1->typeEntry()->revision(), 1); AbstractMetaClass *rev2 = AbstractMetaClass::findClass(classes, QLatin1String("Rev_2")); - QCOMPARE(getTypeRevision(rev2->typeEntry()), 2); + QCOMPARE(rev2->typeEntry()->revision(), 2); AbstractMetaEnum* rev3 = rev2->findEnum(QLatin1String("Rev_3")); - QCOMPARE(getTypeRevision(rev3->typeEntry()), 3); + QCOMPARE(rev3->typeEntry()->revision(), 3); FlagsTypeEntry* rev4 = rev3->typeEntry()->flags(); - QCOMPARE(getTypeRevision(rev4), 4); + QCOMPARE(rev4->revision(), 4); AbstractMetaEnum* rev5 = rev2->findEnum(QLatin1String("Rev_5")); - QCOMPARE(getTypeRevision(rev5->typeEntry()), 5); - QCOMPARE(getTypeRevision(rev5->typeEntry()->flags()), 5); + const EnumTypeEntry *revEnumTypeEntry = rev5->typeEntry(); + QCOMPARE(revEnumTypeEntry->revision(), 5); + QCOMPARE(revEnumTypeEntry->flags()->revision(), 5); } QTEST_APPLESS_MAIN(TestTypeRevision) diff --git a/sources/shiboken2/ApiExtractor/typedatabase.cpp b/sources/shiboken2/ApiExtractor/typedatabase.cpp index e494ba174..0814575ea 100644 --- a/sources/shiboken2/ApiExtractor/typedatabase.cpp +++ b/sources/shiboken2/ApiExtractor/typedatabase.cpp @@ -577,28 +577,15 @@ void TypeDatabase::setDropTypeEntries(QStringList dropTypeEntries) m_dropTypeEntries.sort(); } -// Using std::pair to save some memory -// the pair means (revision, typeIndex) -// This global variable exists only because we can't break the ABI -typedef QHash > TypeRevisionMap; -Q_GLOBAL_STATIC(TypeRevisionMap, typeEntryFields); static bool computeTypeIndexes = true; static int maxTypeIndex; -int getTypeRevision(const TypeEntry* typeEntry) +static bool typeEntryLessThan(const TypeEntry* t1, const TypeEntry* t2) { - return typeEntryFields()->value(typeEntry).first; -} - -void setTypeRevision(TypeEntry* typeEntry, int revision) -{ - (*typeEntryFields())[typeEntry].first = revision; - computeTypeIndexes = true; -} - -static bool compareTypeEntriesByName(const TypeEntry* t1, const TypeEntry* t2) -{ - return t1->qualifiedCppName() < t2->qualifiedCppName(); + if (t1->revision() < t2->revision()) + return true; + return t1->revision() == t2->revision() + && t1->qualifiedCppName() < t2->qualifiedCppName(); } static void _computeTypeIndexes() @@ -607,8 +594,11 @@ static void _computeTypeIndexes() typedef QMap GroupedTypeEntries; GroupedTypeEntries groupedEntries; + TypeEntryList list; + // Group type entries by revision numbers const TypeEntryHash &allEntries = tdb->allEntries(); + list.reserve(allEntries.size()); for (TypeEntryHash::const_iterator tit = allEntries.cbegin(), end = allEntries.cend(); tit != end; ++tit) { for (TypeEntry *entry : tit.value()) { if (entry->isPrimitive() @@ -621,31 +611,33 @@ static void _computeTypeIndexes() || entry->isVoid() || entry->isCustom()) continue; - groupedEntries[getTypeRevision(entry)] << entry; + if (!list.contains(entry)) // Remove duplicates + list.append(entry); } } + // Sort the type entries by revision, name + std::sort(list.begin(), list.end(), typeEntryLessThan); + maxTypeIndex = 0; - GroupedTypeEntries::iterator it = groupedEntries.begin(); - for (; it != groupedEntries.end(); ++it) { - // Remove duplicates - TypeEntryList::iterator newEnd = std::unique(it.value().begin(), it.value().end()); - it.value().erase(newEnd, it.value().end()); - // Sort the type entries by name - qSort(it.value().begin(), newEnd, compareTypeEntriesByName); - - for (TypeEntry *entry : qAsConst(it.value())) { - (*typeEntryFields())[entry].second = maxTypeIndex++; - } - } + for (TypeEntry *e : qAsConst(list)) + e->setSbkIndex(maxTypeIndex++); computeTypeIndexes = false; } -int getTypeIndex(const TypeEntry* typeEntry) +void TypeEntry::setRevision(int r) +{ + if (m_revision != r) { + m_revision = r; + computeTypeIndexes = true; + } +} + +int TypeEntry::sbkIndex() const { if (computeTypeIndexes) _computeTypeIndexes(); - return typeEntryFields()->value(typeEntry).second; + return m_sbkIndex; } int getMaxTypeIndex() diff --git a/sources/shiboken2/ApiExtractor/typedatabase.h b/sources/shiboken2/ApiExtractor/typedatabase.h index 2e7b009c2..3664d76b7 100644 --- a/sources/shiboken2/ApiExtractor/typedatabase.h +++ b/sources/shiboken2/ApiExtractor/typedatabase.h @@ -54,9 +54,6 @@ struct TypeRejection; QT_FORWARD_DECLARE_CLASS(QDebug) -void setTypeRevision(TypeEntry* typeEntry, int revision); -int getTypeRevision(const TypeEntry* typeEntry); -int getTypeIndex(const TypeEntry* typeEntry); int getMaxTypeIndex(); class ContainerTypeEntry; diff --git a/sources/shiboken2/ApiExtractor/typesystem.cpp b/sources/shiboken2/ApiExtractor/typesystem.cpp index 511b67ec8..41d08cb34 100644 --- a/sources/shiboken2/ApiExtractor/typesystem.cpp +++ b/sources/shiboken2/ApiExtractor/typesystem.cpp @@ -642,7 +642,7 @@ void Handler::addFlags(const QString &name, QString flagName, QString revision = attributes.value(QLatin1String("flags-revision")); if (revision.isEmpty()) revision = attributes.value(QLatin1String("revision")); - setTypeRevision(ftype, revision.toInt()); + ftype->setRevision(revision.toInt()); } bool Handler::handleSmartPointerEntry(StackElement *element, @@ -1098,7 +1098,7 @@ bool Handler::startElement(const QStringRef &n, const QXmlStreamAttributes &atts if (element->entry) { m_database->addType(element->entry); - setTypeRevision(element->entry, attributes[QLatin1String("revision")].toInt()); + element->entry->setRevision(attributes.value(QLatin1String("revision")).toInt()); } else { qCWarning(lcShiboken).noquote().nospace() << QStringLiteral("Type: %1 was rejected by typesystem").arg(name); diff --git a/sources/shiboken2/ApiExtractor/typesystem.h b/sources/shiboken2/ApiExtractor/typesystem.h index 4b937faa6..dd4f39e7a 100644 --- a/sources/shiboken2/ApiExtractor/typesystem.h +++ b/sources/shiboken2/ApiExtractor/typesystem.h @@ -715,6 +715,11 @@ public: && m_codeGeneration != TypeEntry::GenerateNothing; } + int revision() const { return m_revision; } + void setRevision(int r); // see typedatabase.cpp + int sbkIndex() const; + void setSbkIndex(int i) { m_sbkIndex = i; } + virtual QString qualifiedCppName() const { return m_name; @@ -904,6 +909,8 @@ private: bool m_stream = false; QVersionNumber m_version; CustomConversion *m_customConversion = nullptr; + int m_revision = 0; + int m_sbkIndex = 0; }; class TypeSystemTypeEntry : public TypeEntry -- cgit v1.2.3