diff options
Diffstat (limited to 'sources/shiboken2/ApiExtractor')
16 files changed, 114 insertions, 93 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp index 0b11b1666..e62a2a78a 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp @@ -669,7 +669,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) checkFunctionModifications(); // sort all classes topologically - m_metaClasses = classesTopologicalSorted(); + m_metaClasses = classesTopologicalSorted(m_metaClasses); for (AbstractMetaClass* cls : qAsConst(m_metaClasses)) { // setupEquals(cls); @@ -681,7 +681,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) if (!cls->typeEntry()->codeGeneration() || cls->innerClasses().size() < 2) continue; - cls->setInnerClasses(classesTopologicalSorted(cls)); + cls->setInnerClasses(classesTopologicalSorted(cls->innerClasses())); } dumpLog(); @@ -3085,27 +3085,37 @@ void AbstractMetaBuilderPrivate::dumpLog() const writeRejectLogFile(m_logDirectory + QLatin1String("mjb_rejected_fields.log"), m_rejectedFields); } -AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const AbstractMetaClass *cppClass, - const Dependencies &additionalDependencies) const +using ClassIndexHash = QHash<AbstractMetaClass *, int>; + +static ClassIndexHash::ConstIterator findByTypeEntry(const ClassIndexHash &map, + const TypeEntry *typeEntry) { - QLinkedList<int> unmappedResult; - QHash<QString, int> map; - QHash<int, AbstractMetaClass*> reverseMap; + auto it = map.cbegin(); + for (auto end = map.cend(); it != end; ++it) { + if (it.key()->typeEntry() == typeEntry) + break; + } + return it; +} - const AbstractMetaClassList& classList = cppClass ? cppClass->innerClasses() : m_metaClasses; +AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const AbstractMetaClassList &classList, + const Dependencies &additionalDependencies) const +{ + ClassIndexHash map; + QHash<int, AbstractMetaClass *> reverseMap; int i = 0; for (AbstractMetaClass *clazz : classList) { - if (map.contains(clazz->qualifiedCppName())) + if (map.contains(clazz)) continue; - map[clazz->qualifiedCppName()] = i; - reverseMap[i] = clazz; + map.insert(clazz, i); + reverseMap.insert(i, clazz); i++; } Graph graph(map.count()); - for (const Dependency &dep : additionalDependencies) { + for (const auto &dep : additionalDependencies) { const int parentIndex = map.value(dep.parent, -1); const int childIndex = map.value(dep.child, -1); if (parentIndex >= 0 && childIndex >= 0) { @@ -3113,18 +3123,17 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const } else { qCWarning(lcShiboken).noquote().nospace() << "AbstractMetaBuilder::classesTopologicalSorted(): Invalid additional dependency: " - << dep.child << " -> " << dep.parent << '.'; + << dep.child->name() << " -> " << dep.parent->name() << '.'; } } - // TODO choose a better name to these regexs - static const QRegularExpression regex1(QStringLiteral("\\(.*\\)")); - Q_ASSERT(regex1.isValid()); - static const QRegularExpression regex2(QStringLiteral("::.*")); - Q_ASSERT(regex2.isValid()); for (AbstractMetaClass *clazz : classList) { - if (clazz->enclosingClass() && map.contains(clazz->enclosingClass()->qualifiedCppName())) - graph.addEdge(map[clazz->enclosingClass()->qualifiedCppName()], map[clazz->qualifiedCppName()]); + const int classIndex = map.value(clazz); + if (auto enclosing = clazz->enclosingClass()) { + const auto enclosingIt = map.constFind(const_cast< AbstractMetaClass *>(enclosing)); + if (enclosingIt!= map.cend()) + graph.addEdge(enclosingIt.value(), classIndex); + } const AbstractMetaClassList &bases = getBaseClasses(clazz); for (AbstractMetaClass *baseClass : bases) { @@ -3132,58 +3141,39 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const if (clazz->baseClass() == baseClass) clazz->setBaseClass(baseClass); - if (map.contains(baseClass->qualifiedCppName())) - graph.addEdge(map[baseClass->qualifiedCppName()], map[clazz->qualifiedCppName()]); + const auto baseIt = map.constFind(baseClass); + if (baseIt!= map.cend()) + graph.addEdge(baseIt.value(), classIndex); } const AbstractMetaFunctionList &functions = clazz->functions(); for (AbstractMetaFunction *func : functions) { const AbstractMetaArgumentList &arguments = func->arguments(); for (AbstractMetaArgument *arg : arguments) { - // check methods with default args - QString defaultExpression = arg->originalDefaultValueExpression(); - if (!defaultExpression.isEmpty()) { - if (defaultExpression == QLatin1String("0") && arg->type()->isValue()) - defaultExpression = arg->type()->name(); - - defaultExpression.remove(regex1); - defaultExpression.remove(regex2); - } - if (!defaultExpression.isEmpty()) { - QString exprClassName = clazz->qualifiedCppName() + colonColon() + defaultExpression; - if (!map.contains(exprClassName)) { - bool found = false; - for (AbstractMetaClass *baseClass : bases) { - exprClassName = baseClass->qualifiedCppName() + colonColon() + defaultExpression; - if (map.contains(exprClassName)) { - found = true; - break; - } - } - if (!found) { - if (map.contains(defaultExpression)) - exprClassName = defaultExpression; - else - exprClassName.clear(); - } + // Check methods with default args: If a class is instantiated by value, + // ("QString s = QString()"), add a dependency. + if (!arg->originalDefaultValueExpression().isEmpty() + && arg->type()->isValue()) { + auto typeEntry = arg->type()->typeEntry(); + if (typeEntry->isComplex() && typeEntry != clazz->typeEntry()) { + auto ait = findByTypeEntry(map, typeEntry); + if (ait != map.cend() && ait.key()->enclosingClass() != clazz) + graph.addEdge(ait.value(), classIndex); } - if (!exprClassName.isEmpty() && exprClassName != clazz->qualifiedCppName()) - graph.addEdge(map[exprClassName], map[clazz->qualifiedCppName()]); } } } } AbstractMetaClassList result; - unmappedResult = graph.topologicalSort(); + const auto unmappedResult = graph.topologicalSort(); if (unmappedResult.isEmpty() && graph.nodeCount()) { - QTemporaryFile tempFile; + QTemporaryFile tempFile(QDir::tempPath() + QLatin1String("/cyclic_depXXXXXX.dot")); tempFile.setAutoRemove(false); tempFile.open(); QHash<int, QString> hash; - QHash<QString, int>::iterator it = map.begin(); - for (; it != map.end(); ++it) - hash[it.value()] = it.key(); + for (auto it = map.cbegin(), end = map.cend(); it != end; ++it) + hash.insert(it.value(), it.key()->qualifiedCppName()); graph.dumpDot(hash, tempFile.fileName()); qCWarning(lcShiboken).noquote().nospace() << "Cyclic dependency found! Graph can be found at " @@ -3199,10 +3189,10 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const return result; } -AbstractMetaClassList AbstractMetaBuilder::classesTopologicalSorted(const AbstractMetaClass *cppClass, +AbstractMetaClassList AbstractMetaBuilder::classesTopologicalSorted(const AbstractMetaClassList &classList, const Dependencies &additionalDependencies) const { - return d->classesTopologicalSorted(cppClass, additionalDependencies); + return d->classesTopologicalSorted(classList, additionalDependencies); } AbstractMetaArgumentList AbstractMetaBuilderPrivate::reverseList(const AbstractMetaArgumentList &list) diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h index 7e5c1fc79..ed89060ac 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h @@ -68,12 +68,10 @@ public: AbstractMetaEnum *findEnum(const TypeEntry *typeEntry) const; /** - * Sorts a list of classes topologically, if an AbstractMetaClass object - * is passed the list of classes will be its inner classes, otherwise - * the list will be the module global classes. + * Sorts a list of classes topologically. * \return a list of classes sorted topologically */ - AbstractMetaClassList classesTopologicalSorted(const AbstractMetaClass *cppClass = Q_NULLPTR, + AbstractMetaClassList classesTopologicalSorted(const AbstractMetaClassList &classList, const Dependencies &additionalDependencies = Dependencies()) const; bool build(const QByteArrayList &arguments, diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h index 185dd0e30..d8203a586 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h @@ -52,7 +52,7 @@ public: void traverseDom(const FileModelItem &dom); void dumpLog() const; - AbstractMetaClassList classesTopologicalSorted(const AbstractMetaClass *cppClass = Q_NULLPTR, + AbstractMetaClassList classesTopologicalSorted(const AbstractMetaClassList &classList, const Dependencies &additionalDependencies = Dependencies()) const; ScopeModelItem popScope() { return m_scopes.takeLast(); } diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h index 9d36706ac..0c652a39a 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.h +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h @@ -95,6 +95,8 @@ public: return m_format; } + void setFormat(Format f) { m_format = f; } + private: QString m_data; Format m_format = Documentation::Native; diff --git a/sources/shiboken2/ApiExtractor/apiextractor.cpp b/sources/shiboken2/ApiExtractor/apiextractor.cpp index 7d2ce250e..e301d891f 100644 --- a/sources/shiboken2/ApiExtractor/apiextractor.cpp +++ b/sources/shiboken2/ApiExtractor/apiextractor.cpp @@ -153,7 +153,7 @@ AbstractMetaClassList ApiExtractor::smartPointers() const AbstractMetaClassList ApiExtractor::classesTopologicalSorted(const Dependencies &additionalDependencies) const { Q_ASSERT(m_builder); - return m_builder->classesTopologicalSorted(Q_NULLPTR, additionalDependencies); + return m_builder->classesTopologicalSorted(m_builder->classes(), additionalDependencies); } PrimitiveTypeEntryList ApiExtractor::primitiveTypes() const diff --git a/sources/shiboken2/ApiExtractor/dependency.h b/sources/shiboken2/ApiExtractor/dependency.h index 97ae32df9..d563e9094 100644 --- a/sources/shiboken2/ApiExtractor/dependency.h +++ b/sources/shiboken2/ApiExtractor/dependency.h @@ -29,13 +29,17 @@ #ifndef DEPENDENCY_H #define DEPENDENCY_H -#include <QtCore/QString> #include <QtCore/QVector> +#include <utility> + // Dependencies for topologically sorting classes + +class AbstractMetaClass; + struct Dependency { - QString parent; - QString child; + AbstractMetaClass *parent; + AbstractMetaClass *child; }; typedef QVector<Dependency> Dependencies; diff --git a/sources/shiboken2/ApiExtractor/doc/_themes/pysidedocs/static/logo_indt.jpg b/sources/shiboken2/ApiExtractor/doc/_themes/pysidedocs/static/logo_indt.jpg Binary files differdeleted file mode 100644 index 2a1fbe7a1..000000000 --- a/sources/shiboken2/ApiExtractor/doc/_themes/pysidedocs/static/logo_indt.jpg +++ /dev/null diff --git a/sources/shiboken2/ApiExtractor/doc/_themes/pysidedocs/static/pysidelogo.png b/sources/shiboken2/ApiExtractor/doc/_themes/pysidedocs/static/pysidelogo.png Binary files differindex 076c1057c..3a2f2bd17 100644 --- a/sources/shiboken2/ApiExtractor/doc/_themes/pysidedocs/static/pysidelogo.png +++ b/sources/shiboken2/ApiExtractor/doc/_themes/pysidedocs/static/pysidelogo.png diff --git a/sources/shiboken2/ApiExtractor/graph.cpp b/sources/shiboken2/ApiExtractor/graph.cpp index 65f33e373..c2ac81e6c 100644 --- a/sources/shiboken2/ApiExtractor/graph.cpp +++ b/sources/shiboken2/ApiExtractor/graph.cpp @@ -29,7 +29,6 @@ #include "graph.h" #include <QVector> #include <QDebug> -#include <QLinkedList> #include <QSet> #include <iterator> #include <algorithm> @@ -48,7 +47,7 @@ struct Graph::GraphPrivate { } - void dfsVisit(int node, QLinkedList<int>& result, QVector<Color>& colors) const + void dfsVisit(int node, Graph::Indexes &result, QVector<Color> &colors) const { colors[node] = GRAY; EdgeIterator it = edges[node].begin(); @@ -59,7 +58,7 @@ struct Graph::GraphPrivate return; } colors[node] = BLACK; - result.push_front(node); + result.append(node); } }; @@ -77,10 +76,12 @@ int Graph::nodeCount() const return m_d->edges.size(); } -QLinkedList<int> Graph::topologicalSort() const +Graph::Indexes Graph::topologicalSort() const { - int nodeCount = Graph::nodeCount(); - QLinkedList<int> result; + const int nodeCount = Graph::nodeCount(); + Indexes result; + result.reserve(nodeCount); + QVector<GraphPrivate::Color> colors(nodeCount, GraphPrivate::WHITE); for (int i = 0; i < nodeCount; ++i) { @@ -88,9 +89,10 @@ QLinkedList<int> Graph::topologicalSort() const m_d->dfsVisit(i, result, colors); } - // Not a DAG! - if (result.size() != nodeCount) - return QLinkedList<int>(); + if (result.size() == nodeCount) + std::reverse(result.begin(), result.end()); + else + result.clear(); // Not a DAG! return result; } diff --git a/sources/shiboken2/ApiExtractor/graph.h b/sources/shiboken2/ApiExtractor/graph.h index 879ac97e4..043a182b5 100644 --- a/sources/shiboken2/ApiExtractor/graph.h +++ b/sources/shiboken2/ApiExtractor/graph.h @@ -29,7 +29,7 @@ #ifndef GRAPH_H #define GRAPH_H -#include <QLinkedList> +#include <QVector> #include <QHash> #include <QString> @@ -37,6 +37,8 @@ class Graph { public: + using Indexes = QVector<int>; + /// Create a new graph with \p numNodes nodes. Graph(int numNodes); ~Graph(); @@ -60,9 +62,10 @@ public: /** * Topologically sort this graph. - * \return A collection with all nodes topologically sorted or an empty collection if a ciclic dependency was found. + * \return A collection with all nodes topologically sorted or an empty collection if a cyclic + * dependency was found. */ - QLinkedList<int> topologicalSort() const; + Indexes topologicalSort() const; private: struct GraphPrivate; diff --git a/sources/shiboken2/ApiExtractor/tests/testextrainclude.cpp b/sources/shiboken2/ApiExtractor/tests/testextrainclude.cpp index 216101215..7e5664842 100644 --- a/sources/shiboken2/ApiExtractor/tests/testextrainclude.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testextrainclude.cpp @@ -73,8 +73,9 @@ void TestExtraInclude::testGlobalExtraIncludes() QVERIFY(AbstractMetaClass::findClass(classes, QLatin1String("A"))); TypeDatabase* td = TypeDatabase::instance(); - TypeEntry* module = td->findType(QLatin1String("Foo")); + const TypeSystemTypeEntry *module = td->defaultTypeSystemType(); QVERIFY(module); + QCOMPARE(module->name(), QLatin1String("Foo")); QVector<Include> includes = module->extraIncludes(); QCOMPARE(includes.count(), 2); diff --git a/sources/shiboken2/ApiExtractor/tests/testinserttemplate.cpp b/sources/shiboken2/ApiExtractor/tests/testinserttemplate.cpp index 8962f83ff..2d1692ee9 100644 --- a/sources/shiboken2/ApiExtractor/tests/testinserttemplate.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testinserttemplate.cpp @@ -74,7 +74,9 @@ void TestInsertTemplate::testInsertTemplateOnModuleInjectCode() AbstractMetaClassList classes = builder->classes(); QVERIFY(classes.isEmpty()); - TypeEntry* module = TypeDatabase::instance()->findType(QLatin1String("Foo")); + const TypeSystemTypeEntry *module = TypeDatabase::instance()->defaultTypeSystemType(); + QVERIFY(module); + QCOMPARE(module->name(), QLatin1String("Foo")); QVERIFY(module); QCOMPARE(module->codeSnips().count(), 1); QString code = module->codeSnips().first().code().trimmed(); diff --git a/sources/shiboken2/ApiExtractor/tests/testtoposort.cpp b/sources/shiboken2/ApiExtractor/tests/testtoposort.cpp index 9d7729513..c59fa8c3d 100644 --- a/sources/shiboken2/ApiExtractor/tests/testtoposort.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testtoposort.cpp @@ -33,23 +33,22 @@ void TestTopoSort::testTopoSort() { - QLinkedList<int> result; { Graph g(3); g.addEdge(1, 2); g.addEdge(0, 1); - result = g.topologicalSort(); + const auto result = g.topologicalSort(); QCOMPARE(result.size(), 3); - QLinkedList<int>::iterator it = result.begin(); + auto it = result.begin(); QCOMPARE(*it, 0); QCOMPARE(*(++it), 1); QCOMPARE(*(++it), 2); } { Graph g(2); - result = g.topologicalSort(); + const auto result = g.topologicalSort(); QCOMPARE(result.size(), 2); - QLinkedList<int>::iterator it = result.begin(); + auto it = result.begin(); QCOMPARE(*it, 1); QCOMPARE(*(++it), 0); } @@ -61,7 +60,7 @@ void TestTopoSort::testCiclicGraph() g.addEdge(0, 1); g.addEdge(1, 2); g.addEdge(2, 0); - QLinkedList<int> result = g.topologicalSort(); + const auto result = g.topologicalSort(); QVERIFY(result.isEmpty()); } diff --git a/sources/shiboken2/ApiExtractor/typedatabase.cpp b/sources/shiboken2/ApiExtractor/typedatabase.cpp index c0999e7ab..4ce2790f5 100644 --- a/sources/shiboken2/ApiExtractor/typedatabase.cpp +++ b/sources/shiboken2/ApiExtractor/typedatabase.cpp @@ -182,16 +182,31 @@ FunctionTypeEntry* TypeDatabase::findFunctionType(const QString& name) const return 0; } +void TypeDatabase::addTypeSystemType(const TypeSystemTypeEntry *e) +{ + m_typeSystemEntries.append(e); +} + const TypeSystemTypeEntry *TypeDatabase::findTypeSystemType(const QString &name) const { - const auto entries = findTypes(name); - for (const TypeEntry *entry : entries) { - if (entry->type() == TypeEntry::TypeSystemType) - return static_cast<const TypeSystemTypeEntry *>(entry); + 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 = findTypes(name); diff --git a/sources/shiboken2/ApiExtractor/typedatabase.h b/sources/shiboken2/ApiExtractor/typedatabase.h index 247d74362..0040364bf 100644 --- a/sources/shiboken2/ApiExtractor/typedatabase.h +++ b/sources/shiboken2/ApiExtractor/typedatabase.h @@ -91,6 +91,8 @@ public: ContainerTypeEntry* findContainerType(const QString& name) const; FunctionTypeEntry* findFunctionType(const QString& name) const; const TypeSystemTypeEntry *findTypeSystemType(const QString &name) const; + const TypeSystemTypeEntry *defaultTypeSystemType() const; + QString defaultPackageName() const; TypeEntry* findType(const QString& name) const; @@ -115,6 +117,7 @@ public: QString *reason = nullptr) const; bool addType(TypeEntry* e, QString *errorMessage = nullptr); + void addTypeSystemType(const TypeSystemTypeEntry *e); FlagsTypeEntry* findFlagsType(const QString& name) const; void addFlagsType(FlagsTypeEntry* fte); @@ -172,6 +175,7 @@ private: TypedefEntryMap m_typedefEntries; TemplateEntryMap m_templates; QVector<QRegularExpression> m_suppressedWarnings; + QVector<const TypeSystemTypeEntry *> m_typeSystemEntries; // maintain order, default is first. AddedFunctionList m_globalUserFunctions; FunctionModificationList m_functionMods; diff --git a/sources/shiboken2/ApiExtractor/typesystem.cpp b/sources/shiboken2/ApiExtractor/typesystem.cpp index 204253777..ad97e40ee 100644 --- a/sources/shiboken2/ApiExtractor/typesystem.cpp +++ b/sources/shiboken2/ApiExtractor/typesystem.cpp @@ -1509,7 +1509,8 @@ TypeSystemTypeEntry *Handler::parseRootElement(const QXmlStreamReader &, TypeSystemTypeEntry *moduleEntry = const_cast<TypeSystemTypeEntry *>(m_database->findTypeSystemType(m_defaultPackage)); - if (!moduleEntry) + const bool add = moduleEntry == nullptr; + if (add) moduleEntry = new TypeSystemTypeEntry(m_defaultPackage, since); moduleEntry->setCodeGeneration(m_generate); @@ -1517,8 +1518,8 @@ TypeSystemTypeEntry *Handler::parseRootElement(const QXmlStreamReader &, m_generate == TypeEntry::GenerateNothing) && !m_defaultPackage.isEmpty()) TypeDatabase::instance()->addRequiredTargetImport(m_defaultPackage); - if (!moduleEntry->qualifiedCppName().isEmpty()) - m_database->addType(moduleEntry); + if (add) + m_database->addTypeSystemType(moduleEntry); return moduleEntry; } |