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.cpp225
1 files changed, 150 insertions, 75 deletions
diff --git a/sources/shiboken2/ApiExtractor/typedatabase.cpp b/sources/shiboken2/ApiExtractor/typedatabase.cpp
index 55170d7c1..4a96240c4 100644
--- a/sources/shiboken2/ApiExtractor/typedatabase.cpp
+++ b/sources/shiboken2/ApiExtractor/typedatabase.cpp
@@ -31,6 +31,7 @@
#include "typesystem_p.h"
#include <QtCore/QFile>
+#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QPair>
#include <QtCore/QVector>
@@ -175,8 +176,8 @@ FunctionTypeEntry* TypeDatabase::findFunctionType(const QString& name) const
TypeEntry* TypeDatabase::findType(const QString& name) const
{
- QList<TypeEntry *> entries = findTypes(name);
- foreach (TypeEntry *entry, entries) {
+ const TypeEntryList &entries = findTypes(name);
+ for (TypeEntry *entry : entries) {
if (entry &&
(!entry->isPrimitive() || static_cast<PrimitiveTypeEntry *>(entry)->preferredTargetLangType())) {
return entry;
@@ -185,7 +186,7 @@ TypeEntry* TypeDatabase::findType(const QString& name) const
return 0;
}
-QList<TypeEntry *> TypeDatabase::findTypes(const QString &name) const
+TypeEntryList TypeDatabase::findTypes(const QString &name) const
{
return m_entries.value(name);
}
@@ -201,12 +202,12 @@ SingleTypeEntryHash TypeDatabase::entries() const
return returned;
}
-QList<const PrimitiveTypeEntry*> TypeDatabase::primitiveTypes() const
+PrimitiveTypeEntryList TypeDatabase::primitiveTypes() const
{
TypeEntryHash entries = allEntries();
- QList<const PrimitiveTypeEntry*> returned;
+ PrimitiveTypeEntryList returned;
for (TypeEntryHash::const_iterator it = entries.cbegin(), end = entries.cend(); it != end; ++it) {
- foreach (TypeEntry *typeEntry, it.value()) {
+ for (TypeEntry *typeEntry : it.value()) {
if (typeEntry->isPrimitive())
returned.append(static_cast<PrimitiveTypeEntry *>(typeEntry));
}
@@ -214,75 +215,121 @@ QList<const PrimitiveTypeEntry*> TypeDatabase::primitiveTypes() const
return returned;
}
-QList<const ContainerTypeEntry*> TypeDatabase::containerTypes() const
+ContainerTypeEntryList TypeDatabase::containerTypes() const
{
TypeEntryHash entries = allEntries();
- QList<const ContainerTypeEntry*> returned;
+ ContainerTypeEntryList returned;
for (TypeEntryHash::const_iterator it = entries.cbegin(), end = entries.cend(); it != end; ++it) {
- foreach (TypeEntry *typeEntry, it.value()) {
+ for (TypeEntry *typeEntry : it.value()) {
if (typeEntry->isContainer())
returned.append(static_cast<ContainerTypeEntry *>(typeEntry));
}
}
return returned;
}
-void TypeDatabase::addRejection(const QString& className, const QString& functionName,
- const QString& fieldName, const QString& enumName)
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug d, const TypeRejection &r)
{
- TypeRejection r;
- r.class_name = className;
- r.function_name = functionName;
- r.field_name = fieldName;
- r.enum_name = enumName;
+ 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;
}
-bool TypeDatabase::isClassRejected(const QString& className) const
+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;
+ }
+ return result;
+}
+
+// Match class name only
+bool TypeDatabase::isClassRejected(const QString& className, QString *reason) const
{
- foreach (const TypeRejection& r, m_rejections) {
- if (r.class_name == className && r.function_name == QLatin1String("*")
- && r.field_name == QLatin1String("*") && r.enum_name == QLatin1String("*")) {
+ 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;
}
-bool TypeDatabase::isEnumRejected(const QString& className, const QString& enumName) const
+// 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)
{
- foreach (const TypeRejection& r, m_rejections) {
- if (r.enum_name == enumName
- && (r.class_name == className || r.class_name == QLatin1String("*"))) {
+ 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);
+}
+
void TypeDatabase::addType(TypeEntry *e)
{
m_entries[e->qualifiedCppName()].append(e);
}
-bool TypeDatabase::isFunctionRejected(const QString& className, const QString& functionName) const
+bool TypeDatabase::isFunctionRejected(const QString& className, const QString& functionName,
+ QString *reason) const
{
- foreach (const TypeRejection& r, m_rejections)
- if (r.function_name == functionName &&
- (r.class_name == className || r.class_name == QLatin1String("*")))
- return true;
- return false;
+ 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::isFieldRejected(const QString& className, const QString& fieldName) const
+bool TypeDatabase::isArgumentTypeRejected(const QString& className, const QString& typeName,
+ QString *reason) const
{
- foreach (const TypeRejection& r, m_rejections)
- if (r.field_name == fieldName &&
- (r.class_name == className || r.class_name == QLatin1String("*")))
- return true;
- return false;
+ 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
@@ -321,7 +368,7 @@ void TypeDatabase::addGlobalUserFunctions(const AddedFunctionList &functions)
AddedFunctionList TypeDatabase::findGlobalUserFunctions(const QString& name) const
{
AddedFunctionList addedFunctions;
- foreach (const AddedFunction &func, m_globalUserFunctions) {
+ for (const AddedFunction &func : m_globalUserFunctions) {
if (func.name() == name)
addedFunctions.append(func);
}
@@ -343,16 +390,52 @@ FunctionModificationList TypeDatabase::functionModifications(const QString& sign
FunctionModificationList lst;
for (int i = 0; i < m_functionMods.count(); ++i) {
const FunctionModification& mod = m_functionMods.at(i);
- if (mod.signature == signature)
+ if (mod.matches(signature))
lst << mod;
}
return lst;
}
-void TypeDatabase::addSuppressedWarning(const QString &s)
+bool TypeDatabase::addSuppressedWarning(const QString &warning, QString *errorMessage)
{
- m_suppressedWarnings.append(s);
+ 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('$'));
+ }
+
+ const QRegularExpression expression(pattern);
+ if (!expression.isValid()) {
+ *errorMessage = QLatin1String("Invalid message pattern \"") + warning
+ + QLatin1String("\": ") + expression.errorString();
+ return false;
+ }
+
+ m_suppressedWarnings.append(expression);
+ return true;
}
bool TypeDatabase::isSuppressedWarning(const QString& s) const
@@ -360,36 +443,23 @@ bool TypeDatabase::isSuppressedWarning(const QString& s) const
if (!m_suppressWarnings)
return false;
- foreach (const QString &_warning, m_suppressedWarnings) {
- QString warning = _warning;
- warning.replace(QLatin1String("\\*"), QLatin1String("&place_holder_for_asterisk;"));
-
- QStringList segs = warning.split(QLatin1Char('*'), QString::SkipEmptyParts);
- if (!segs.size())
- continue;
-
- int i = 0;
- int pos = s.indexOf(QString(segs.at(i++)).replace(QLatin1String("&place_holder_for_asterisk;"), QLatin1String("*")));
- //qDebug() << "s == " << s << ", warning == " << segs;
- while (pos != -1) {
- if (i == segs.size())
- return true;
- pos = s.indexOf(QString(segs.at(i++)).replace(QLatin1String("&place_holder_for_asterisk;"), QLatin1String("*")), pos);
- }
+ for (const QRegularExpression &warning : m_suppressedWarnings) {
+ if (warning.match(s).hasMatch())
+ return true;
}
return false;
}
-QString TypeDatabase::modifiedTypesystemFilepath(const QString& tsFile) const
+QString TypeDatabase::modifiedTypesystemFilepath(const QString& tsFile, bool stripPath) 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();
- const QString fileName = tsFi.fileName();
- foreach (const QString &path, m_typesystemPaths) {
+ const QString fileName = stripPath ? tsFi.fileName() : tsFile;
+ for (const QString &path : m_typesystemPaths) {
const QFileInfo fi(path + QLatin1Char('/') + fileName);
if (fi.isFile())
return fi.absoluteFilePath();
@@ -440,9 +510,9 @@ bool TypeDatabase::parseFile(QIODevice* device, bool generate)
PrimitiveTypeEntry *TypeDatabase::findPrimitiveType(const QString& name) const
{
- QList<TypeEntry*> entries = findTypes(name);
+ const TypeEntryList &entries = findTypes(name);
- foreach (TypeEntry* entry, entries) {
+ for (TypeEntry *entry : entries) {
if (entry && entry->isPrimitive() && static_cast<PrimitiveTypeEntry*>(entry)->preferredTargetLangType())
return static_cast<PrimitiveTypeEntry*>(entry);
}
@@ -452,8 +522,8 @@ PrimitiveTypeEntry *TypeDatabase::findPrimitiveType(const QString& name) const
ComplexTypeEntry* TypeDatabase::findComplexType(const QString& name) const
{
- QList<TypeEntry*> entries = findTypes(name);
- foreach (TypeEntry* entry, entries) {
+ const TypeEntryList &entries = findTypes(name);
+ for (TypeEntry *entry : entries) {
if (entry && entry->isComplex())
return static_cast<ComplexTypeEntry*>(entry);
}
@@ -462,8 +532,8 @@ ComplexTypeEntry* TypeDatabase::findComplexType(const QString& name) const
ObjectTypeEntry* TypeDatabase::findObjectType(const QString& name) const
{
- QList<TypeEntry*> entries = findTypes(name);
- foreach (TypeEntry* entry, entries) {
+ const TypeEntryList &entries = findTypes(name);
+ for (TypeEntry *entry : entries) {
if (entry && entry->isObject())
return static_cast<ObjectTypeEntry*>(entry);
}
@@ -472,8 +542,8 @@ ObjectTypeEntry* TypeDatabase::findObjectType(const QString& name) const
NamespaceTypeEntry* TypeDatabase::findNamespaceType(const QString& name) const
{
- QList<TypeEntry*> entries = findTypes(name);
- foreach (TypeEntry* entry, entries) {
+ const TypeEntryList &entries = findTypes(name);
+ for (TypeEntry *entry : entries) {
if (entry && entry->isNamespace())
return static_cast<NamespaceTypeEntry*>(entry);
}
@@ -518,13 +588,13 @@ static bool compareTypeEntriesByName(const TypeEntry* t1, const TypeEntry* t2)
static void _computeTypeIndexes()
{
TypeDatabase* tdb = TypeDatabase::instance();
- typedef QMap<int, QList<TypeEntry*> > GroupedTypeEntries;
+ typedef QMap<int, TypeEntryList> GroupedTypeEntries;
GroupedTypeEntries groupedEntries;
// Group type entries by revision numbers
- TypeEntryHash allEntries = tdb->allEntries();
- foreach (QList<TypeEntry*> entryList, allEntries) {
- foreach (TypeEntry* entry, entryList) {
+ const TypeEntryHash &allEntries = tdb->allEntries();
+ for (TypeEntryHash::const_iterator tit = allEntries.cbegin(), end = allEntries.cend(); tit != end; ++tit) {
+ for (TypeEntry *entry : tit.value()) {
if (entry->isPrimitive()
|| entry->isContainer()
|| entry->isFunction()
@@ -543,12 +613,12 @@ static void _computeTypeIndexes()
GroupedTypeEntries::iterator it = groupedEntries.begin();
for (; it != groupedEntries.end(); ++it) {
// Remove duplicates
- QList<TypeEntry*>::iterator newEnd = std::unique(it.value().begin(), it.value().end());
+ 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);
- foreach (TypeEntry* entry, it.value()) {
+ for (TypeEntry *entry : qAsConst(it.value())) {
(*typeEntryFields())[entry].second = maxTypeIndex++;
}
}
@@ -614,7 +684,12 @@ QDebug operator<<(QDebug d, const TypeEntry *te)
d.nospace();
d << "TypeEntry(";
if (te) {
- d << '"' << te->qualifiedCppName() << "\", type=" << te->type();
+ 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();