diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2020-11-14 17:12:54 +0100 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2020-11-14 18:55:34 +0000 |
commit | dff115603e6f093f9189977e29511b53a16ec0c6 (patch) | |
tree | ee476b9ffe1dc9382d8bab2dc7977fdfe2d3590b | |
parent | 44e40c9aba1bd6f7568cb52827a8a990d0eed78d (diff) |
shiboken6: Move the base class search out of the generator
The code was relying on class search by string and searched
the default super class as specified in the typesystem on each
invocation.
Make the default super class a member of AbstractMetaClass
that is set by the meta builder and move the functions to
AbstractMetaClass.
Change-Id: I15e4f193067d09f00e7dc17aef07c14c0e969884
Reviewed-by: Christian Tismer <tismer@stackless.com>
7 files changed, 64 insertions, 46 deletions
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp index b0b449f0c..4220665eb 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp @@ -1454,6 +1454,21 @@ bool AbstractMetaBuilderPrivate::setupInheritance(AbstractMetaClass *metaClass) } } + // Super class set by attribute "default-superclass". + const QString defaultSuperclassName = metaClass->typeEntry()->defaultSuperclass(); + if (!defaultSuperclassName.isEmpty()) { + auto defaultSuper = AbstractMetaClass::findClass(m_metaClasses, defaultSuperclassName); + if (defaultSuper != nullptr) { + metaClass->setDefaultSuperclass(defaultSuper); + } else { + QString message; + QTextStream(&message) << "Class \"" << defaultSuperclassName + << "\" specified as \"default-superclass\" of \"" << metaClass->name() + << "\" could not be found in the code model."; + qCWarning(lcShiboken, "%s", qPrintable(message)); + } + } + return true; } diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang.cpp b/sources/shiboken6/ApiExtractor/abstractmetalang.cpp index 25f29118f..7d2457795 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetalang.cpp +++ b/sources/shiboken6/ApiExtractor/abstractmetalang.cpp @@ -90,6 +90,7 @@ public: Documentation m_doc; const AbstractMetaClass *m_enclosingClass = nullptr; + AbstractMetaClass *m_defaultSuperclass = nullptr; AbstractMetaClassList m_baseClasses; // Real base classes after setting up inheritance AbstractMetaTypeList m_baseTemplateInstantiations; AbstractMetaClass *m_extendedNamespace = nullptr; @@ -409,6 +410,17 @@ QString AbstractMetaClass::baseClassName() const return d->m_baseClasses.isEmpty() ? QString() : d->m_baseClasses.constFirst()->name(); } +// Attribute "default-superclass" +AbstractMetaClass *AbstractMetaClass::defaultSuperclass() const +{ + return d->m_defaultSuperclass; +} + +void AbstractMetaClass::setDefaultSuperclass(AbstractMetaClass *s) +{ + d->m_defaultSuperclass = s; +} + AbstractMetaClass *AbstractMetaClass::baseClass() const { return d->m_baseClasses.value(0, nullptr); @@ -419,6 +431,29 @@ const AbstractMetaClassList &AbstractMetaClass::baseClasses() const return d->m_baseClasses; } +// base classes including "defaultSuperclass". +AbstractMetaClassList AbstractMetaClass::typeSystemBaseClasses() const +{ + AbstractMetaClassList result = d->m_baseClasses; + if (d->m_defaultSuperclass != nullptr) { + result.removeAll(d->m_defaultSuperclass); + result.prepend(d->m_defaultSuperclass); + } + return result; +} + +// Recursive list of all base classes including defaultSuperclass +AbstractMetaClassList AbstractMetaClass::allTypeSystemAncestors() const +{ + AbstractMetaClassList result; + const AbstractMetaClassList baseClasses = typeSystemBaseClasses(); + for (AbstractMetaClass *base : baseClasses) { + result.append(base); + result.append(base->allTypeSystemAncestors()); + } + return result; +} + void AbstractMetaClass::addBaseClass(AbstractMetaClass *baseClass) { Q_ASSERT(baseClass); diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang.h b/sources/shiboken6/ApiExtractor/abstractmetalang.h index dd35e9ee2..da4465917 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetalang.h +++ b/sources/shiboken6/ApiExtractor/abstractmetalang.h @@ -193,8 +193,15 @@ public: QString baseClassName() const; + AbstractMetaClass *defaultSuperclass() const; // Attribute "default-superclass" + void setDefaultSuperclass(AbstractMetaClass *s); + AbstractMetaClass *baseClass() const; const AbstractMetaClassList &baseClasses() const; + // base classes including defaultSuperclass + AbstractMetaClassList typeSystemBaseClasses() const; + // Recursive list of all base classes including defaultSuperclass + AbstractMetaClassList allTypeSystemAncestors() const; void addBaseClass(AbstractMetaClass *base_class); void setBaseClass(AbstractMetaClass *base_class); diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp index 1ac609698..6523d1c0e 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp +++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp @@ -1777,7 +1777,7 @@ void CppGenerator::writeSmartPointerConverterFunctions(QTextStream &s, const Abs // TODO: Missing conversion to smart pointer pointer type: s << "// Register smartpointer conversion for all derived classes\n"; - const auto classes = getBaseClasses(targetClass); + const auto classes = targetClass->typeSystemBaseClasses(); for (auto k : classes) { if (smartPointerTypeEntry->matchesInstantiation(k->typeEntry())) { if (auto smartTargetType = findSmartPointerInstantiation(k->typeEntry())) { @@ -3824,7 +3824,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f QStringList CppGenerator::getAncestorMultipleInheritance(const AbstractMetaClass *metaClass) { QStringList result; - const AbstractMetaClassList &baseClases = getBaseClasses(metaClass); + const AbstractMetaClassList &baseClases = metaClass->typeSystemBaseClasses(); if (!baseClases.isEmpty()) { for (const AbstractMetaClass *baseClass : baseClases) { QString offset; @@ -3884,7 +3884,7 @@ void CppGenerator::writeSpecialCastFunction(QTextStream &s, const AbstractMetaCl s << "{\n"; s << INDENT << "auto me = reinterpret_cast< ::" << className << " *>(obj);\n"; bool firstClass = true; - const AbstractMetaClassList &allAncestors = getAllAncestors(metaClass); + const AbstractMetaClassList &allAncestors = metaClass->allTypeSystemAncestors(); for (const AbstractMetaClass *baseClass : allAncestors) { s << INDENT << (!firstClass ? "else " : "") << "if (desiredType == reinterpret_cast<SbkObjectType *>(" << cpythonTypeNameExt(baseClass->typeEntry()) << "))\n"; Indentation indent(INDENT); @@ -4034,7 +4034,7 @@ void CppGenerator::writeSmartPointerConverterInitialization(QTextStream &s, cons if (!klass) return; - const auto classes = getBaseClasses(klass); + const auto classes = klass->typeSystemBaseClasses(); if (classes.isEmpty()) return; @@ -5317,7 +5317,7 @@ void CppGenerator::writeClassRegister(QTextStream &s, // Multiple inheritance QString pyTypeBasesVariable = chopType(pyTypeName) + QLatin1String("_Type_bases"); - const AbstractMetaClassList baseClasses = getBaseClasses(metaClass); + const AbstractMetaClassList baseClasses = metaClass->typeSystemBaseClasses(); if (metaClass->baseClassNames().size() > 1) { s << INDENT << "PyObject *" << pyTypeBasesVariable << " = PyTuple_Pack(" << baseClasses.size() << ',' << Qt::endl; @@ -5598,7 +5598,7 @@ void CppGenerator::writeTypeDiscoveryFunction(QTextStream &s, const AbstractMeta s << INDENT << "return cptr;\n"; } } else if (metaClass->isPolymorphic()) { - const AbstractMetaClassList &ancestors = getAllAncestors(metaClass); + const AbstractMetaClassList &ancestors = metaClass->allTypeSystemAncestors(); for (AbstractMetaClass *ancestor : ancestors) { if (ancestor->baseClass()) continue; diff --git a/sources/shiboken6/generator/shiboken/overloaddata.cpp b/sources/shiboken6/generator/shiboken/overloaddata.cpp index 309151cd5..27cdc82dc 100644 --- a/sources/shiboken6/generator/shiboken/overloaddata.cpp +++ b/sources/shiboken6/generator/shiboken/overloaddata.cpp @@ -335,7 +335,7 @@ void OverloadData::sortNextOverloads() // Process inheritance relationships if (targetType.isValue() || targetType.isObject()) { const AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_generator->classes(), targetType.typeEntry()); - const AbstractMetaClassList &ancestors = m_generator->getAllAncestors(metaClass); + const AbstractMetaClassList &ancestors = metaClass->allTypeSystemAncestors(); for (const AbstractMetaClass *ancestor : ancestors) { QString ancestorTypeName = ancestor->typeEntry()->name(); if (!sortData.map.contains(ancestorTypeName)) diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp index 166cb5aff..8eb019ab0 100644 --- a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp +++ b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp @@ -2336,26 +2336,6 @@ AbstractMetaFunctionList ShibokenGenerator::getMethodsWithBothStaticAndNonStatic return methods; } -AbstractMetaClassList ShibokenGenerator::getBaseClasses(const AbstractMetaClass *metaClass) const -{ - AbstractMetaClassList baseClasses; - if (metaClass) { - QStringList baseClassNames(metaClass->baseClassNames()); - const QString defaultSuperclass = metaClass->typeEntry()->defaultSuperclass(); - if (!defaultSuperclass.isEmpty()) { - int index = baseClassNames.indexOf(defaultSuperclass); - if (index >= 0) - baseClassNames.move(index, 0); - } - for (const QString &parent : baseClassNames) { - AbstractMetaClass *clazz = AbstractMetaClass::findClass(classes(), parent); - if (clazz) - baseClasses << clazz; - } - } - return baseClasses; -} - const AbstractMetaClass *ShibokenGenerator::getMultipleInheritingClass(const AbstractMetaClass *metaClass) { if (!metaClass || metaClass->baseClassNames().isEmpty()) @@ -2365,19 +2345,6 @@ const AbstractMetaClass *ShibokenGenerator::getMultipleInheritingClass(const Abs return getMultipleInheritingClass(metaClass->baseClass()); } -AbstractMetaClassList ShibokenGenerator::getAllAncestors(const AbstractMetaClass *metaClass) const -{ - AbstractMetaClassList result; - if (metaClass) { - AbstractMetaClassList baseClasses = getBaseClasses(metaClass); - for (AbstractMetaClass *base : qAsConst(baseClasses)) { - result.append(base); - result.append(getAllAncestors(base)); - } - } - return result; -} - QString ShibokenGenerator::getModuleHeaderFileName(const QString &moduleName) const { return moduleCppPrefix(moduleName).toLower() + QLatin1String("_python.h"); diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.h b/sources/shiboken6/generator/shiboken/shibokengenerator.h index 4170c5edf..50feb49b9 100644 --- a/sources/shiboken6/generator/shiboken/shibokengenerator.h +++ b/sources/shiboken6/generator/shiboken/shibokengenerator.h @@ -87,9 +87,6 @@ public: const char *name() const override { return "Shiboken"; } - /// Returns a list of all ancestor classes for the given class. - AbstractMetaClassList getAllAncestors(const AbstractMetaClass *metaClass) const; - /// Returns true if the user enabled PySide extensions. bool usePySideExtensions() const; @@ -214,9 +211,6 @@ protected: /// Returns a list of methods of the given class where each one is part of a different overload with both static and non-static method. AbstractMetaFunctionList getMethodsWithBothStaticAndNonStaticMethods(const AbstractMetaClass *metaClass); - /// Returns a list of parent classes for a given class. - AbstractMetaClassList getBaseClasses(const AbstractMetaClass *metaClass) const; - void writeToPythonConversion(QTextStream &s, const AbstractMetaType &type, const AbstractMetaClass *context, const QString &argumentName); void writeToCppConversion(QTextStream &s, const AbstractMetaType &type, const AbstractMetaClass *context, |