aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/ApiExtractor/typedatabase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2/ApiExtractor/typedatabase.cpp')
-rw-r--r--sources/shiboken2/ApiExtractor/typedatabase.cpp167
1 files changed, 113 insertions, 54 deletions
diff --git a/sources/shiboken2/ApiExtractor/typedatabase.cpp b/sources/shiboken2/ApiExtractor/typedatabase.cpp
index 9529de40a..6372a8715 100644
--- a/sources/shiboken2/ApiExtractor/typedatabase.cpp
+++ b/sources/shiboken2/ApiExtractor/typedatabase.cpp
@@ -263,6 +263,8 @@ static inline QString msgRejectReason(const TypeRejection &r, const QString &nee
str << " matches class \"" << r.className.pattern() << "\" and \"" << needle
<< "\" matches \"" << r.pattern.pattern() << '"';
break;
+ case TypeRejection::Invalid:
+ break;
}
return result;
}
@@ -518,7 +520,10 @@ bool TypeDatabase::parseFile(QIODevice* device, bool generate)
{
QXmlStreamReader reader(device);
Handler handler(this, generate);
- return handler.parse(reader);
+ const bool result = handler.parse(reader);
+ if (!result)
+ qCWarning(lcShiboken, "%s", qPrintable(handler.errorString()));
+ return result;
}
PrimitiveTypeEntry *TypeDatabase::findPrimitiveType(const QString& name) const
@@ -574,28 +579,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<const TypeEntry*, std::pair<int, int> > TypeRevisionMap;
-Q_GLOBAL_STATIC(TypeRevisionMap, typeEntryFields);
static bool computeTypeIndexes = true;
static int maxTypeIndex;
-int getTypeRevision(const TypeEntry* typeEntry)
-{
- return typeEntryFields()->value(typeEntry).first;
-}
-
-void setTypeRevision(TypeEntry* typeEntry, int revision)
+static bool typeEntryLessThan(const TypeEntry* t1, const TypeEntry* t2)
{
- (*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()
@@ -604,8 +596,11 @@ static void _computeTypeIndexes()
typedef QMap<int, TypeEntryList> 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()
@@ -618,31 +613,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()
@@ -684,33 +681,95 @@ bool TypeDatabase::checkApiVersion(const QString &package,
}
#ifndef QT_NO_DEBUG_STREAM
+
+#define FORMAT_BOOL(name, var) \
+ if (var) \
+ d << ", [" << name << ']';
+
+#define FORMAT_NONEMPTY_STRING(name, var) \
+ if (!var.isEmpty()) \
+ d << ", " << name << "=\"" << var << '"';
+
+#define FORMAT_LIST_SIZE(name, var) \
+ if (!var.isEmpty()) \
+ d << ", " << var.size() << ' ' << name;
+
+void TypeEntry::formatDebug(QDebug &d) const
+{
+ const QString cppName = qualifiedCppName();
+ d << '"' << m_name << '"';
+ if (m_name != cppName)
+ d << "\", cppName=\"" << cppName << '"';
+ d << ", type=" << m_type << ", codeGeneration=0x"
+ << hex << m_codeGeneration << dec;
+ FORMAT_NONEMPTY_STRING("package", m_targetLangPackage)
+ FORMAT_BOOL("preferredConversion", m_preferredConversion)
+ FORMAT_BOOL("stream", m_stream)
+ FORMAT_LIST_SIZE("codeSnips", m_codeSnips)
+ FORMAT_NONEMPTY_STRING("conversionRule", m_conversionRule)
+ if (!m_version.isNull() && m_version > QVersionNumber(0, 0))
+ d << ", version=" << m_version;
+ if (m_revision)
+ d << ", revision=" << m_revision;
+ if (m_sbkIndex)
+ d << ", sbkIndex=" << m_sbkIndex;
+ if (m_include.isValid())
+ d << ", include=" << m_include;
+ if (const int count = m_extraIncludes.size()) {
+ d << ", extraIncludes[" << count << "]=";
+ for (int i = 0; i < count; ++i) {
+ if (i)
+ d << ", ";
+ d << m_extraIncludes.at(i);
+ }
+ }
+}
+
+void ComplexTypeEntry::formatDebug(QDebug &d) const
+{
+ TypeEntry::formatDebug(d);
+ FORMAT_NONEMPTY_STRING("targetLangName", m_targetLangName)
+ FORMAT_BOOL("QObject", m_qobject)
+ FORMAT_BOOL("polymorphicBase", m_polymorphicBase)
+ FORMAT_BOOL("genericClass", m_genericClass)
+ if (m_typeFlags != 0)
+ d << ", typeFlags=" << m_typeFlags;
+ d << ", copyableFlag=" << m_copyableFlag;
+ FORMAT_NONEMPTY_STRING("defaultSuperclass", m_defaultSuperclass)
+ FORMAT_NONEMPTY_STRING("polymorphicIdValue", m_polymorphicIdValue)
+ FORMAT_NONEMPTY_STRING("held", m_heldTypeValue)
+ FORMAT_NONEMPTY_STRING("lookupName", m_lookupName)
+ FORMAT_NONEMPTY_STRING("targetType", m_targetType)
+ FORMAT_NONEMPTY_STRING("hash", m_hashFunction)
+ FORMAT_LIST_SIZE("addedFunctions", m_addedFunctions)
+ FORMAT_LIST_SIZE("functionMods", m_functionMods)
+ FORMAT_LIST_SIZE("fieldMods", m_fieldMods)
+}
+
+void EnumTypeEntry::formatDebug(QDebug &d) const
+{
+ TypeEntry::formatDebug(d);
+ FORMAT_NONEMPTY_STRING("package", m_packageName)
+ FORMAT_NONEMPTY_STRING("qualifier", m_qualifier)
+ FORMAT_NONEMPTY_STRING("targetLangName", m_targetLangName)
+ FORMAT_NONEMPTY_STRING("lowerBound", m_lowerBound)
+ FORMAT_NONEMPTY_STRING("lupperBound", m_upperBound)
+ FORMAT_BOOL("extensible", m_extensible)
+ FORMAT_BOOL("forceInteger", m_forceInteger)
+ if (m_flags)
+ d << ", flags=(" << m_flags << ')';
+}
+
QDebug operator<<(QDebug d, const TypeEntry *te)
{
QDebugStateSaver saver(d);
d.noquote();
d.nospace();
d << "TypeEntry(";
- if (te) {
- const QString name = te->name();
- const QString cppName = te->qualifiedCppName();
- d << '"' << name << '"';
- if (name != cppName)
- d << "\", cppName=\"" << cppName << '"';
- d << ", type=" << te->type();
- if (te->include().isValid())
- d << ", include=" << te->include();
- const IncludeList &extraIncludes = te->extraIncludes();
- if (const int count = extraIncludes.size()) {
- d << ", extraIncludes[" << count << "]=";
- for (int i = 0; i < count; ++i) {
- if (i)
- d << ", ";
- d << extraIncludes.at(i);
- }
- }
- } else {
+ if (te)
+ te->formatDebug(d);
+ else
d << '0';
- }
d << ')';
return d;
}