diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2020-10-14 10:41:33 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2020-10-15 16:23:31 +0200 |
commit | 31e1ec9b5d40e1431dbf0c756b166422c702cad6 (patch) | |
tree | a09ab3eefb7a40cb5fa5c22c75ebb0ad270441af /sources/shiboken2/ApiExtractor | |
parent | 5b29846a91564aef34edb618a7a014df7de96f3a (diff) |
Enable typesystem typedefs across modules
Adding a specialization of template type ValueWithUnit from libsample
to libother would fail since the SBK index array of libsample would
be used with the index from libother for it.
Build up the inheritance for typesystem typedefs early on and add
a lookup which matches the template specializations found during
traversing functions to the type def and the class that is
generated for it so that it can be used.
As a side effect, special case entries for template
specializations can be deleted from the signature mappings since
they change to the class name and thus are normal types.
Task-number: PYSIDE-1202
Change-Id: I5cc9650f70e9dc975171c80919685ebf5e752749
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'sources/shiboken2/ApiExtractor')
3 files changed, 51 insertions, 0 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp index 942d99cd3..8ef2866c2 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp @@ -673,6 +673,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) } m_itemToClass.clear(); + m_typeSystemTypeDefs.clear(); ReportHandler::endProgress(); } @@ -993,6 +994,23 @@ void AbstractMetaBuilderPrivate::traverseTypesystemTypedefs() *metaClass += AbstractMetaAttributes::Public; fillAddedFunctions(metaClass); addAbstractMetaClass(metaClass, nullptr); + // Ensure base classes are set up when traversing functions for the + // type to be resolved. + if (setupInheritance(metaClass)) { + // Create an entry to look up up types obtained from parsing + // functions in reverse. As opposed to container specializations, + // which are generated into every instantiating module (indicated + // by ContainerTypeEntry::targetLangPackage() being empty), the + // correct index array of the module needs to be found by reverse + // mapping the instantiations to the typedef entry. + // Synthesize a AbstractMetaType which would be found by an + // instantiation. + auto sourceType = new AbstractMetaType; + sourceType->setTypeEntry(metaClass->templateBaseClass()->typeEntry()); + sourceType->setInstantiations(metaClass->templateBaseClassInstantiations()); + sourceType->decideUsagePattern(); + m_typeSystemTypeDefs.append({AbstractMetaTypeCPtr(sourceType), metaClass}); + } } } @@ -2093,6 +2111,20 @@ TypeEntries AbstractMetaBuilderPrivate::findTypeEntries(const QString &qualified return {}; } +// Reverse lookup of AbstractMetaType representing a template specialization +// found during traversing function arguments to its type system typedef'ed +// class. +const AbstractMetaClass *AbstractMetaBuilderPrivate::resolveTypeSystemTypeDef(const AbstractMetaType *t) const +{ + if (t->hasInstantiations()) { + auto pred = [t](const TypeClassEntry &e) { return e.type->compare(*t); }; + auto it = std::find_if(m_typeSystemTypeDefs.cbegin(), m_typeSystemTypeDefs.cend(), pred); + if (it != m_typeSystemTypeDefs.cend()) + return it->klass; + } + return nullptr; +} + AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typei, AbstractMetaClass *currentClass, TranslateTypeFlags flags, @@ -2328,6 +2360,15 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo // AbstractMetaType::cppSignature(). metaType->decideUsagePattern(); + if (d) { + // Reverse lookup of type system typedefs. Replace by class. + if (auto klass = d->resolveTypeSystemTypeDef(metaType.data())) { + metaType.reset(new AbstractMetaType); + metaType->setTypeEntry(klass->typeEntry()); + metaType->decideUsagePattern(); + } + } + return metaType.take(); } diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h index 103f16d15..846895089 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h @@ -44,6 +44,12 @@ class TypeDatabase; class AbstractMetaBuilderPrivate { public: + struct TypeClassEntry + { + AbstractMetaTypeCPtr type; + const AbstractMetaClass *klass; + }; + using TranslateTypeFlags = AbstractMetaBuilder::TranslateTypeFlags; Q_DISABLE_COPY(AbstractMetaBuilderPrivate) @@ -175,6 +181,7 @@ public: void fixArgumentNames(AbstractMetaFunction *func, const FunctionModificationList &mods); void fillAddedFunctions(AbstractMetaClass *metaClass); + const AbstractMetaClass *resolveTypeSystemTypeDef(const AbstractMetaType *t) const; AbstractMetaBuilder *q; AbstractMetaClassList m_metaClasses; @@ -201,6 +208,7 @@ public: QFileInfoList m_globalHeaders; QStringList m_headerPaths; mutable QHash<QString, Include> m_resolveIncludeHash; + QVector<TypeClassEntry> m_typeSystemTypeDefs; // look up metatype->class for type system typedefs bool m_skipDeprecated = false; }; diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang_typedefs.h b/sources/shiboken2/ApiExtractor/abstractmetalang_typedefs.h index 617ebcf4f..f8bca07c1 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang_typedefs.h +++ b/sources/shiboken2/ApiExtractor/abstractmetalang_typedefs.h @@ -29,6 +29,7 @@ #ifndef ABSTRACTMETALANG_TYPEDEFS_H #define ABSTRACTMETALANG_TYPEDEFS_H +#include <QtCore/QSharedPointer> #include <QtCore/QVector> class AbstractMetaClass; @@ -45,6 +46,7 @@ using AbstractMetaEnumList = QVector<AbstractMetaEnum *>; using AbstractMetaEnumValueList = QVector<AbstractMetaEnumValue *>; using AbstractMetaFieldList = QVector<AbstractMetaField *>; using AbstractMetaFunctionList = QVector<AbstractMetaFunction *>; +using AbstractMetaTypeCPtr = QSharedPointer<const AbstractMetaType>; using AbstractMetaTypeList = QVector<AbstractMetaType *>; using AbstractMetaTypeCList = QVector<const AbstractMetaType *>; |