diff options
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, |