diff options
Diffstat (limited to 'sources/shiboken2/ApiExtractor/typedatabase.cpp')
-rw-r--r-- | sources/shiboken2/ApiExtractor/typedatabase.cpp | 1039 |
1 files changed, 0 insertions, 1039 deletions
diff --git a/sources/shiboken2/ApiExtractor/typedatabase.cpp b/sources/shiboken2/ApiExtractor/typedatabase.cpp deleted file mode 100644 index 4a29a25c9..000000000 --- a/sources/shiboken2/ApiExtractor/typedatabase.cpp +++ /dev/null @@ -1,1039 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "typedatabase.h" -#include "typesystem.h" -#include "typesystemparser.h" - -#include <QtCore/QFile> -#include <QtCore/QDebug> -#include <QtCore/QDir> -#include <QtCore/QPair> -#include <QtCore/QVector> -#include <QtCore/QRegularExpression> -#include <QtCore/QVersionNumber> -#include <QtCore/QXmlStreamReader> -#include "reporthandler.h" -// #include <tr1/tuple> -#include <algorithm> - -// package -> api-version - -static QString wildcardToRegExp(QString w) -{ - w.replace(QLatin1Char('?'), QLatin1Char('.')); - w.replace(QLatin1Char('*'), QStringLiteral(".*")); - return w; -} - -using ApiVersion =QPair<QRegularExpression, QVersionNumber>; -using ApiVersions = QVector<ApiVersion>; - -Q_GLOBAL_STATIC(ApiVersions, apiVersions) - -TypeDatabase::TypeDatabase() -{ - addType(new VoidTypeEntry()); - addType(new VarargsTypeEntry()); -} - -TypeDatabase::~TypeDatabase() = default; - -TypeDatabase* TypeDatabase::instance(bool newInstance) -{ - static TypeDatabase *db = nullptr; - if (!db || newInstance) { - delete db; - db = new TypeDatabase; - } - return db; -} - -// A list of regex/replacements to fix int types like "ushort" to "unsigned short" -// unless present in TypeDatabase -struct IntTypeNormalizationEntry -{ - QRegularExpression regex; - QString replacement; -}; - -using IntTypeNormalizationEntries = QVector<IntTypeNormalizationEntry>; - -static const IntTypeNormalizationEntries &intTypeNormalizationEntries() -{ - static IntTypeNormalizationEntries result; - static bool firstTime = true; - if (firstTime) { - firstTime = false; - for (auto t : {"char", "short", "int", "long"}) { - const QString intType = QLatin1String(t); - if (!TypeDatabase::instance()->findType(QLatin1Char('u') + intType)) { - IntTypeNormalizationEntry entry; - entry.replacement = QStringLiteral("unsigned ") + intType; - entry.regex.setPattern(QStringLiteral("\\bu") + intType + QStringLiteral("\\b")); - Q_ASSERT(entry.regex.isValid()); - result.append(entry); - } - } - } - return result; -} - -QString TypeDatabase::normalizedSignature(const QString &signature) -{ - QString normalized = QLatin1String(QMetaObject::normalizedSignature(signature.toUtf8().constData())); - - if (instance() && signature.contains(QLatin1String("unsigned"))) { - const IntTypeNormalizationEntries &entries = intTypeNormalizationEntries(); - for (const auto &entry : entries) - normalized.replace(entry.regex, entry.replacement); - } - - return normalized; -} - -QStringList TypeDatabase::requiredTargetImports() const -{ - return m_requiredTargetImports; -} - -void TypeDatabase::addRequiredTargetImport(const QString& moduleName) -{ - if (!m_requiredTargetImports.contains(moduleName)) - m_requiredTargetImports << moduleName; -} - -void TypeDatabase::addTypesystemPath(const QString& typesystem_paths) -{ - #if defined(Q_OS_WIN32) - const char path_splitter = ';'; - #else - const char path_splitter = ':'; - #endif - m_typesystemPaths += typesystem_paths.split(QLatin1Char(path_splitter)); -} - -IncludeList TypeDatabase::extraIncludes(const QString& className) const -{ - ComplexTypeEntry* typeEntry = findComplexType(className); - return typeEntry ? typeEntry->extraIncludes() : IncludeList(); -} - -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; - - int pos = name.indexOf(QLatin1Char('<')); - if (pos > 0) - template_name = name.left(pos); - - TypeEntry* type_entry = findType(template_name); - if (type_entry && type_entry->isContainer()) - return static_cast<ContainerTypeEntry*>(type_entry); - return nullptr; -} - -static bool inline useType(const TypeEntry *t) -{ - return !t->isPrimitive() - || static_cast<const PrimitiveTypeEntry *>(t)->preferredTargetLangType(); -} - -FunctionTypeEntry* TypeDatabase::findFunctionType(const QString& name) const -{ - const auto entries = findTypeRange(name); - for (TypeEntry *entry : entries) { - if (entry->type() == TypeEntry::FunctionType && useType(entry)) - return static_cast<FunctionTypeEntry*>(entry); - } - return nullptr; -} - -void TypeDatabase::addTypeSystemType(const TypeSystemTypeEntry *e) -{ - m_typeSystemEntries.append(e); -} - -const TypeSystemTypeEntry *TypeDatabase::findTypeSystemType(const QString &name) const -{ - for (auto entry : m_typeSystemEntries) { - if (entry->name() == name) - return entry; - } - return nullptr; -} - -const TypeSystemTypeEntry *TypeDatabase::defaultTypeSystemType() const -{ - return m_typeSystemEntries.value(0, nullptr); -} - -QString TypeDatabase::defaultPackageName() const -{ - Q_ASSERT(!m_typeSystemEntries.isEmpty()); - return m_typeSystemEntries.constFirst()->name(); -} - -TypeEntry* TypeDatabase::findType(const QString& name) const -{ - const auto entries = findTypeRange(name); - for (TypeEntry *entry : entries) { - if (useType(entry)) - return entry; - } - return nullptr; -} - -template <class Predicate> -TypeEntries TypeDatabase::findTypesHelper(const QString &name, Predicate pred) const -{ - TypeEntries result; - const auto entries = findTypeRange(name); - for (TypeEntry *entry : entries) { - if (pred(entry)) - result.append(entry); - } - return result; -} - -TypeEntries TypeDatabase::findTypes(const QString &name) const -{ - return findTypesHelper(name, useType); -} - -static bool useCppType(const TypeEntry *t) -{ - bool result = false; - switch (t->type()) { - case TypeEntry::PrimitiveType: - case TypeEntry::VoidType: - case TypeEntry::FlagsType: - case TypeEntry::EnumType: - case TypeEntry::TemplateArgumentType: - case TypeEntry::BasicValueType: - case TypeEntry::ContainerType: - case TypeEntry::ObjectType: - case TypeEntry::ArrayType: - case TypeEntry::CustomType: - case TypeEntry::SmartPointerType: - case TypeEntry::TypedefType: - result = useType(t); - break; - default: - break; - } - return result; -} - -TypeEntries TypeDatabase::findCppTypes(const QString &name) const -{ - return findTypesHelper(name, useCppType); -} - -TypeEntryMultiMapConstIteratorRange TypeDatabase::findTypeRange(const QString &name) const -{ - const auto range = m_entries.equal_range(name); - return {range.first, range.second}; -} - -PrimitiveTypeEntryList TypeDatabase::primitiveTypes() const -{ - PrimitiveTypeEntryList returned; - for (auto it = m_entries.cbegin(), end = m_entries.cend(); it != end; ++it) { - TypeEntry *typeEntry = it.value(); - if (typeEntry->isPrimitive()) - returned.append(static_cast<PrimitiveTypeEntry *>(typeEntry)); - } - return returned; -} - -ContainerTypeEntryList TypeDatabase::containerTypes() const -{ - ContainerTypeEntryList returned; - for (auto it = m_entries.cbegin(), end = m_entries.cend(); it != end; ++it) { - TypeEntry *typeEntry = it.value(); - if (typeEntry->isContainer()) - returned.append(static_cast<ContainerTypeEntry *>(typeEntry)); - } - return returned; -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const TypeRejection &r) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "TypeRejection(type=" << r.matchType << ", class=" - << r.className.pattern() << ", pattern=" << r.pattern.pattern() << ')'; - return d; -} -#endif // !QT_NO_DEBUG_STREAM - -void TypeDatabase::addRejection(const TypeRejection &r) -{ - m_rejections << r; -} - -static inline QString msgRejectReason(const TypeRejection &r, const QString &needle = QString()) -{ - QString result; - QTextStream str(&result); - switch (r.matchType) { - case TypeRejection::ExcludeClass: - str << " matches class exclusion \"" << r.className.pattern() << '"'; - break; - case TypeRejection::Function: - case TypeRejection::Field: - case TypeRejection::Enum: - str << " matches class \"" << r.className.pattern() << "\" and \"" << r.pattern.pattern() << '"'; - break; - case TypeRejection::ArgumentType: - case TypeRejection::ReturnType: - str << " matches class \"" << r.className.pattern() << "\" and \"" << needle - << "\" matches \"" << r.pattern.pattern() << '"'; - break; - case TypeRejection::Invalid: - break; - } - return result; -} - -// Match class name only -bool TypeDatabase::isClassRejected(const QString& className, QString *reason) const -{ - for (const TypeRejection& r : m_rejections) { - if (r.matchType == TypeRejection::ExcludeClass && r.className.match(className).hasMatch()) { - if (reason) - *reason = msgRejectReason(r); - return true; - } - } - return false; -} - -// Match class name and function/enum/field -static bool findRejection(const QVector<TypeRejection> &rejections, - TypeRejection::MatchType matchType, - const QString& className, const QString& name, - QString *reason = nullptr) -{ - Q_ASSERT(matchType != TypeRejection::ExcludeClass); - for (const TypeRejection& r : rejections) { - if (r.matchType == matchType && r.pattern.match(name).hasMatch() - && r.className.match(className).hasMatch()) { - if (reason) - *reason = msgRejectReason(r, name); - return true; - } - } - return false; -} - -bool TypeDatabase::isEnumRejected(const QString& className, const QString& enumName, QString *reason) const -{ - return findRejection(m_rejections, TypeRejection::Enum, className, enumName, reason); -} - -TypeEntry *TypeDatabase::resolveTypeDefEntry(TypedefEntry *typedefEntry, - QString *errorMessage) -{ - QString sourceName = typedefEntry->sourceType(); - const int lessThanPos = sourceName.indexOf(QLatin1Char('<')); - if (lessThanPos != -1) - sourceName.truncate(lessThanPos); - ComplexTypeEntry *source = nullptr; - for (TypeEntry *e : findTypeRange(sourceName)) { - switch (e->type()) { - case TypeEntry::BasicValueType: - case TypeEntry::ContainerType: - case TypeEntry::ObjectType: - case TypeEntry::SmartPointerType: - source = dynamic_cast<ComplexTypeEntry *>(e); - Q_ASSERT(source); - break; - default: - break; - } - } - if (!source) { - if (errorMessage) - *errorMessage = QLatin1String("Unable to resolve typedef \"") - + typedefEntry->sourceType() + QLatin1Char('"'); - return nullptr; - } - - auto *result = static_cast<ComplexTypeEntry *>(source->clone()); - result->useAsTypedef(typedefEntry); - typedefEntry->setSource(source); - typedefEntry->setTarget(result); - m_typedefEntries.insert(typedefEntry->qualifiedCppName(), typedefEntry); - return result; -} - -bool TypeDatabase::addType(TypeEntry *e, QString *errorMessage) -{ - if (e->type() == TypeEntry::TypedefType) { - e = resolveTypeDefEntry(static_cast<TypedefEntry *>(e), errorMessage); - if (Q_UNLIKELY(!e)) - return false; - } - m_entries.insert(e->qualifiedCppName(), e); - return true; -} - -// Add a dummy value entry for non-type template parameters -ConstantValueTypeEntry * - TypeDatabase::addConstantValueTypeEntry(const QString &value, - const TypeEntry *parent) -{ - auto result = new ConstantValueTypeEntry(value, parent); - result->setCodeGeneration(0); - addType(result); - return result; -} - -bool TypeDatabase::isFunctionRejected(const QString& className, const QString& functionName, - QString *reason) const -{ - return findRejection(m_rejections, TypeRejection::Function, className, functionName, reason); -} - -bool TypeDatabase::isFieldRejected(const QString& className, const QString& fieldName, - QString *reason) const -{ - return findRejection(m_rejections, TypeRejection::Field, className, fieldName, reason); -} - -bool TypeDatabase::isArgumentTypeRejected(const QString& className, const QString& typeName, - QString *reason) const -{ - return findRejection(m_rejections, TypeRejection::ArgumentType, className, typeName, reason); -} - -bool TypeDatabase::isReturnTypeRejected(const QString& className, const QString& typeName, - QString *reason) const -{ - return findRejection(m_rejections, TypeRejection::ReturnType, className, typeName, reason); -} - -FlagsTypeEntry* TypeDatabase::findFlagsType(const QString &name) const -{ - TypeEntry *fte = findType(name); - if (!fte) { - fte = m_flagsEntries.value(name); - if (!fte) { - //last hope, search for flag without scope inside of flags hash - for (auto it = m_flagsEntries.cbegin(), end = m_flagsEntries.cend(); it != end; ++it) { - if (it.key().endsWith(name)) { - fte = it.value(); - break; - } - } - } - } - return static_cast<FlagsTypeEntry *>(fte); -} - -void TypeDatabase::addFlagsType(FlagsTypeEntry *fte) -{ - m_flagsEntries[fte->originalName()] = fte; -} - -void TypeDatabase::addTemplate(TemplateEntry *t) -{ - m_templates[t->name()] = t; -} - -void TypeDatabase::addGlobalUserFunctions(const AddedFunctionList &functions) -{ - m_globalUserFunctions << functions; -} - -AddedFunctionList TypeDatabase::findGlobalUserFunctions(const QString& name) const -{ - AddedFunctionList addedFunctions; - for (const AddedFunctionPtr &func : m_globalUserFunctions) { - if (func->name() == name) - addedFunctions.append(func); - } - return addedFunctions; -} - -void TypeDatabase::addGlobalUserFunctionModifications(const FunctionModificationList &functionModifications) -{ - m_functionMods << functionModifications; -} - -QString TypeDatabase::globalNamespaceClassName(const TypeEntry * /*entry*/) -{ - return QLatin1String("Global"); -} - -FunctionModificationList TypeDatabase::functionModifications(const QString& signature) const -{ - FunctionModificationList lst; - for (int i = 0; i < m_functionMods.count(); ++i) { - const FunctionModification& mod = m_functionMods.at(i); - if (mod.matches(signature)) - lst << mod; - } - - return lst; -} - -bool TypeDatabase::addSuppressedWarning(const QString &warning, QString *errorMessage) -{ - QString pattern; - if (warning.startsWith(QLatin1Char('^')) && warning.endsWith(QLatin1Char('$'))) { - pattern = warning; - } else { - // Legacy syntax: Use wildcards '*' (unless escaped by '\') - QVector<int> asteriskPositions; - const int warningSize = warning.size(); - for (int i = 0; i < warningSize; ++i) { - if (warning.at(i) == QLatin1Char('\\')) - ++i; - else if (warning.at(i) == QLatin1Char('*')) - asteriskPositions.append(i); - } - asteriskPositions.append(warningSize); - - pattern.append(QLatin1Char('^')); - int lastPos = 0; - for (int a = 0, aSize = asteriskPositions.size(); a < aSize; ++a) { - if (a) - pattern.append(QStringLiteral(".*")); - const int nextPos = asteriskPositions.at(a); - if (nextPos > lastPos) - pattern.append(QRegularExpression::escape(warning.mid(lastPos, nextPos - lastPos))); - lastPos = nextPos + 1; - } - pattern.append(QLatin1Char('$')); - } - - QRegularExpression expression(pattern); - if (!expression.isValid()) { - *errorMessage = QLatin1String("Invalid message pattern \"") + warning - + QLatin1String("\": ") + expression.errorString(); - return false; - } - expression.setPatternOptions(expression.patternOptions() | QRegularExpression::MultilineOption); - - m_suppressedWarnings.append(expression); - return true; -} - -bool TypeDatabase::isSuppressedWarning(const QString& s) const -{ - if (!m_suppressWarnings) - return false; - - for (const QRegularExpression &warning : m_suppressedWarnings) { - if (warning.match(s).hasMatch()) - return true; - } - - return false; -} - -QString TypeDatabase::modifiedTypesystemFilepath(const QString& tsFile, const QString ¤tPath) const -{ - const QFileInfo tsFi(tsFile); - if (tsFi.isAbsolute()) // No point in further lookups - return tsFi.absoluteFilePath(); - if (tsFi.isFile()) // Make path absolute - return tsFi.absoluteFilePath(); - if (!currentPath.isEmpty()) { - const QFileInfo fi(currentPath + QLatin1Char('/') + tsFile); - if (fi.isFile()) - return fi.absoluteFilePath(); - } - for (const QString &path : m_typesystemPaths) { - const QFileInfo fi(path + QLatin1Char('/') + tsFile); - if (fi.isFile()) - return fi.absoluteFilePath(); - } - return tsFile; -} - -bool TypeDatabase::parseFile(const QString &filename, bool generate) -{ - return parseFile(filename, QString(), generate); -} - -bool TypeDatabase::parseFile(const QString &filename, const QString ¤tPath, bool generate) -{ - - QString filepath = modifiedTypesystemFilepath(filename, currentPath); - if (m_parsedTypesystemFiles.contains(filepath)) - return m_parsedTypesystemFiles[filepath]; - - m_parsedTypesystemFiles[filepath] = true; // Prevent recursion when including self. - - QFile file(filepath); - if (!file.exists()) { - m_parsedTypesystemFiles[filepath] = false; - QString message = QLatin1String("Can't find ") + filename; - if (!currentPath.isEmpty()) - message += QLatin1String(", current path: ") + currentPath; - message += QLatin1String(", typesystem paths: ") + m_typesystemPaths.join(QLatin1String(", ")); - qCWarning(lcShiboken).noquote().nospace() << message; - return false; - } - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - m_parsedTypesystemFiles[filepath] = false; - qCWarning(lcShiboken).noquote().nospace() - << "Can't open " << QDir::toNativeSeparators(filename) << ": " << file.errorString(); - return false; - } - - bool ok = parseFile(&file, generate); - m_parsedTypesystemFiles[filepath] = ok; - return ok; -} - -bool TypeDatabase::parseFile(QIODevice* device, bool generate) -{ - QXmlStreamReader reader(device); - TypeSystemParser handler(this, generate); - const bool result = handler.parse(reader); - if (!result) - qCWarning(lcShiboken, "%s", qPrintable(handler.errorString())); - return result; -} - -PrimitiveTypeEntry *TypeDatabase::findPrimitiveType(const QString& name) const -{ - const auto entries = findTypeRange(name); - for (TypeEntry *entry : entries) { - if (entry->isPrimitive()) { - auto *pe = static_cast<PrimitiveTypeEntry *>(entry); - if (pe->preferredTargetLangType()) - return pe; - } - } - - return nullptr; -} - -ComplexTypeEntry* TypeDatabase::findComplexType(const QString& name) const -{ - const auto entries = findTypeRange(name); - for (TypeEntry *entry : entries) { - if (entry->isComplex() && useType(entry)) - return static_cast<ComplexTypeEntry*>(entry); - } - return nullptr; -} - -ObjectTypeEntry* TypeDatabase::findObjectType(const QString& name) const -{ - const auto entries = findTypeRange(name); - for (TypeEntry *entry : entries) { - if (entry && entry->isObject() && useType(entry)) - return static_cast<ObjectTypeEntry*>(entry); - } - return nullptr; -} - -NamespaceTypeEntryList TypeDatabase::findNamespaceTypes(const QString& name) const -{ - NamespaceTypeEntryList result; - const auto entries = findTypeRange(name); - for (TypeEntry *entry : entries) { - if (entry->isNamespace()) - result.append(static_cast<NamespaceTypeEntry*>(entry)); - } - return result; -} - -NamespaceTypeEntry *TypeDatabase::findNamespaceType(const QString& name, - const QString &fileName) const -{ - const auto entries = findNamespaceTypes(name); - // Preferably check on matching file name first, if a pattern was given. - if (!fileName.isEmpty()) { - for (NamespaceTypeEntry *entry : entries) { - if (entry->hasPattern() && entry->matchesFile(fileName)) - return entry; - } - } - for (NamespaceTypeEntry *entry : entries) { - if (!entry->hasPattern()) - return entry; - } - return nullptr; -} - -bool TypeDatabase::shouldDropTypeEntry(const QString& fullTypeName) const -{ - return m_dropTypeEntries.contains(fullTypeName); -} - -void TypeDatabase::setDropTypeEntries(QStringList dropTypeEntries) -{ - m_dropTypeEntries = dropTypeEntries; - m_dropTypeEntries.sort(); -} - -static bool computeTypeIndexes = true; -static int maxTypeIndex; - -static bool typeEntryLessThan(const TypeEntry* t1, const TypeEntry* t2) -{ - if (t1->revision() < t2->revision()) - return true; - return t1->revision() == t2->revision() - && t1->qualifiedCppName() < t2->qualifiedCppName(); -} - -static void _computeTypeIndexes() -{ - TypeDatabase* tdb = TypeDatabase::instance(); - - TypeEntryList list; - - // Group type entries by revision numbers - const auto &allEntries = tdb->entries(); - list.reserve(allEntries.size()); - for (auto tit = allEntries.cbegin(), end = allEntries.cend(); tit != end; ++tit) { - TypeEntry *entry = tit.value(); - if (entry->isPrimitive() - || entry->isContainer() - || entry->isFunction() - || !entry->generateCode() - || entry->isEnumValue() - || entry->isVarargs() - || entry->isTypeSystem() - || entry->isVoid() - || entry->isCustom()) - continue; - 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; - for (TypeEntry *e : qAsConst(list)) - e->setSbkIndex(maxTypeIndex++); - 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) { - m_revision = r; - computeTypeIndexes = true; - } -} - -int TypeEntry::sbkIndex() const -{ - if (computeTypeIndexes) - _computeTypeIndexes(); - return m_sbkIndex; -} - -int getMaxTypeIndex() -{ - if (computeTypeIndexes) - _computeTypeIndexes(); - return maxTypeIndex; -} - -void TypeDatabase::clearApiVersions() -{ - apiVersions()->clear(); -} - -bool TypeDatabase::setApiVersion(const QString& packageWildcardPattern, const QString &version) -{ - const QString packagePattern = wildcardToRegExp(packageWildcardPattern.trimmed()); - const QVersionNumber versionNumber = QVersionNumber::fromString(version); - if (versionNumber.isNull()) - return false; - ApiVersions &versions = *apiVersions(); - for (int i = 0, size = versions.size(); i < size; ++i) { - if (versions.at(i).first.pattern() == packagePattern) { - versions[i].second = versionNumber; - return true; - } - } - const QRegularExpression packageRegex(packagePattern); - if (!packageRegex.isValid()) - return false; - versions.append(qMakePair(packageRegex, versionNumber)); - return true; -} - -bool TypeDatabase::checkApiVersion(const QString &package, - const VersionRange &vr) -{ - const ApiVersions &versions = *apiVersions(); - if (versions.isEmpty()) // Nothing specified: use latest. - return true; - for (int i = 0, size = versions.size(); i < size; ++i) { - if (versions.at(i).first.match(package).hasMatch()) - return versions.at(i).second >= vr.since - && versions.at(i).second <= vr.until; - } - return false; -} - -#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; - -template <class Container, class Separator> -static void formatList(QDebug &d, const char *name, const Container &c, Separator sep) -{ - if (const int size = c.size()) { - d << ", " << name << '[' << size << "]=("; - for (int i = 0; i < size; ++i) { - if (i) - d << sep; - d << c.at(i); - } - d << ')'; - } -} - -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" - << Qt::hex << m_codeGeneration << Qt::dec - << ", target=\"" << targetLangName() << '"'; - FORMAT_NONEMPTY_STRING("package", m_targetLangPackage) - 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; - formatList(d, "extraIncludes", m_extraIncludes, ", "); -} - -void ComplexTypeEntry::formatDebug(QDebug &d) const -{ - TypeEntry::formatDebug(d); - FORMAT_BOOL("polymorphicBase", m_polymorphicBase) - FORMAT_BOOL("genericClass", m_genericClass) - FORMAT_BOOL("deleteInMainThread", m_deleteInMainThread) - if (m_typeFlags != 0) - d << ", typeFlags=" << m_typeFlags; - d << ", copyableFlag=" << m_copyableFlag - << ", except=" << int(m_exceptionHandling); - FORMAT_NONEMPTY_STRING("defaultSuperclass", m_defaultSuperclass) - FORMAT_NONEMPTY_STRING("polymorphicIdValue", m_polymorphicIdValue) - FORMAT_NONEMPTY_STRING("targetType", m_targetType) - FORMAT_NONEMPTY_STRING("hash", m_hashFunction) - FORMAT_LIST_SIZE("addedFunctions", m_addedFunctions) - formatList(d, "functionMods", m_functionMods, ", "); - FORMAT_LIST_SIZE("fieldMods", m_fieldMods) -} - -void TypedefEntry::formatDebug(QDebug &d) const -{ - ComplexTypeEntry::formatDebug(d); - d << ", sourceType=\"" << m_sourceType << '"' - << ", source=" << m_source << ", target=" << m_target; -} - -void EnumTypeEntry::formatDebug(QDebug &d) const -{ - TypeEntry::formatDebug(d); - if (m_flags) - d << ", flags=(" << m_flags << ')'; -} - -void NamespaceTypeEntry::formatDebug(QDebug &d) const -{ - ComplexTypeEntry::formatDebug(d); - auto pattern = m_filePattern.pattern(); - FORMAT_NONEMPTY_STRING("pattern", pattern) - d << ",visibility=" << m_visibility; - if (m_inlineNamespace) - d << "[inline]"; -} - -void ContainerTypeEntry::formatDebug(QDebug &d) const -{ - ComplexTypeEntry::formatDebug(d); - d << ", type=" << m_containerKind << ",\"" << typeName() << '"'; -} - -void SmartPointerTypeEntry::formatDebug(QDebug &d) const -{ - ComplexTypeEntry::formatDebug(d); - if (!m_instantiations.isEmpty()) { - d << ", instantiations[" << m_instantiations.size() << "]=("; - for (auto i : m_instantiations) - d << i->name() << ','; - d << ')'; - } -} - -QDebug operator<<(QDebug d, const TypeEntry *te) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "TypeEntry("; - if (te) - te->formatDebug(d); - else - d << '0'; - d << ')'; - return d; -} - -QDebug operator<<(QDebug d, const TemplateEntry *te) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "TemplateEntry("; - if (te) { - d << '"' << te->name() << '"'; - } else { - d << '0'; - } - d << ')'; - return d; -} - -void TypeDatabase::formatDebug(QDebug &d) const -{ - d << "TypeDatabase(" - << "entries[" << m_entries.size() << "]="; - for (auto it = m_entries.cbegin(), end = m_entries.cend(); it != end; ++it) - d << " " << it.value() << '\n'; - if (!m_templates.isEmpty()) { - d << "templates[" << m_templates.size() << "]=("; - const auto begin = m_templates.cbegin(); - for (auto it = begin, end = m_templates.cend(); it != end; ++it) { - if (it != begin) - d << ", "; - d << it.value(); - } - d << ")\n"; - } - if (!m_flagsEntries.isEmpty()) { - d << "flags[" << m_flagsEntries.size() << "]=("; - const auto begin = m_flagsEntries.cbegin(); - for (auto it = begin, end = m_flagsEntries.cend(); it != end; ++it) { - if (it != begin) - d << ", "; - d << it.value(); - } - d << ")\n"; - } - d <<"\nglobalUserFunctions=" << m_globalUserFunctions << '\n'; - formatList(d, "globalFunctionMods", m_functionMods, '\n'); - d << ')'; -} - -QDebug operator<<(QDebug d, const TypeDatabase &db) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - db.formatDebug(d); - return d; -} -#endif // !QT_NO_DEBUG_STREAM |