From 4d12849bc72cd54f4aec3118f9daf89af156e2c2 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 23 Oct 2019 10:14:35 +0200 Subject: shiboken: Give the type system entries a pointer to their parent This helpful when building the qualified names including namepaces whose names may not appear (due to them being C++ inline namespaces or generation being disabled). With this, an accessor to the type system entry can be added, which helps to avoid ambiguities. Task-number: PYSIDE-990 Task-number: PYSIDE-1074 Change-Id: I7dce742770fbdbbc6ed0c3fce5120108dd12ffc4 Reviewed-by: Cristian Maureira-Fredes Reviewed-by: Renato Araujo Oliveira Filho --- .../shiboken2/ApiExtractor/abstractmetabuilder.cpp | 22 +++-- sources/shiboken2/ApiExtractor/messages.cpp | 5 ++ sources/shiboken2/ApiExtractor/messages.h | 2 + sources/shiboken2/ApiExtractor/typesystem.cpp | 99 ++++++++++++++-------- sources/shiboken2/ApiExtractor/typesystem.h | 63 ++++++++++---- .../shiboken2/ApiExtractor/typesystemparser.cpp | 74 ++++++++++++---- sources/shiboken2/ApiExtractor/typesystemparser.h | 2 + 7 files changed, 189 insertions(+), 78 deletions(-) diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp index 73a887577..12dafb47d 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp @@ -836,13 +836,15 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(const EnumModelItem & QString qualifiedName = enumItem->qualifiedName().join(colonColon()); TypeEntry *typeEntry = nullptr; + const TypeEntry *enclosingTypeEntry = enclosing ? enclosing->typeEntry() : nullptr; if (enumItem->accessPolicy() == CodeModel::Private) { QStringList names = enumItem->qualifiedName(); const QString &enumName = names.constLast(); QString nspace; if (names.size() > 1) nspace = QStringList(names.mid(0, names.size() - 1)).join(colonColon()); - typeEntry = new EnumTypeEntry(nspace, enumName, QVersionNumber(0, 0)); + typeEntry = new EnumTypeEntry(nspace, enumName, QVersionNumber(0, 0), + enclosingTypeEntry); TypeDatabase::instance()->addType(typeEntry); } else if (enumItem->enumKind() != AnonymousEnum) { typeEntry = TypeDatabase::instance()->findType(qualifiedName); @@ -862,8 +864,8 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(const EnumModelItem & QString enumName = enumItem->name(); QString className; - if (enclosing) - className = enclosing->typeEntry()->qualifiedCppName(); + if (enclosingTypeEntry) + className = enclosingTypeEntry->qualifiedCppName(); QString rejectReason; if (TypeDatabase::instance()->isEnumRejected(className, enumName, &rejectReason)) { @@ -963,7 +965,8 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(const EnumModelItem & } EnumValueTypeEntry *enumValue = new EnumValueTypeEntry(prefix + e->name(), e->stringValue(), - enumTypeEntry, enumTypeEntry->version()); + enumTypeEntry, enumTypeEntry->version(), + enumTypeEntry->parent()); TypeDatabase::instance()->addType(enumValue); if (e->value().isNullValue()) enumTypeEntry->setNullValue(enumValue); @@ -1097,9 +1100,11 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem TemplateParameterList template_parameters = classItem->templateParameters(); QVector template_args; template_args.clear(); + auto argumentParent = metaClass->typeEntry()->typeSystemTypeEntry(); for (int i = 0; i < template_parameters.size(); ++i) { const TemplateParameterModelItem ¶m = template_parameters.at(i); - TemplateArgumentEntry *param_type = new TemplateArgumentEntry(param->name(), type->version()); + auto param_type = new TemplateArgumentEntry(param->name(), type->version(), + argumentParent); param_type->setOrdinal(i); template_args.append(param_type); } @@ -2251,7 +2256,9 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo if (_ok) arrayType->setArrayElementCount(int(elems)); } - arrayType->setTypeEntry(new ArrayTypeEntry(elementType->typeEntry() , elementType->typeEntry()->version())); + auto elementTypeEntry = elementType->typeEntry(); + arrayType->setTypeEntry(new ArrayTypeEntry(elementTypeEntry, elementTypeEntry->version(), + elementTypeEntry->parent())); arrayType->decideUsagePattern(); elementType = arrayType; @@ -2675,7 +2682,8 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass, t = typeDb->findType(typeName); if (!t) { t = new EnumValueTypeEntry(typeName, typeName, nullptr, - QVersionNumber(0, 0)); + QVersionNumber(0, 0), + subclass->typeEntry()->parent()); t->setCodeGeneration(0); typeDb->addType(t); } diff --git a/sources/shiboken2/ApiExtractor/messages.cpp b/sources/shiboken2/ApiExtractor/messages.cpp index b571c08b9..b60e1f73b 100644 --- a/sources/shiboken2/ApiExtractor/messages.cpp +++ b/sources/shiboken2/ApiExtractor/messages.cpp @@ -475,6 +475,11 @@ QString msgInvalidRegularExpression(const QString &pattern, const QString &why) return QLatin1String("Invalid pattern \"") + pattern + QLatin1String("\": ") + why; } +QString msgNoRootTypeSystemEntry() +{ + return QLatin1String("Type system entry appears out of order, there does not seem to be a root type system element."); +} + // qtdocgenerator.cpp QString msgTagWarning(const QXmlStreamReader &reader, const QString &context, diff --git a/sources/shiboken2/ApiExtractor/messages.h b/sources/shiboken2/ApiExtractor/messages.h index 4d66a89b8..5bbd7ba58 100644 --- a/sources/shiboken2/ApiExtractor/messages.h +++ b/sources/shiboken2/ApiExtractor/messages.h @@ -131,6 +131,8 @@ QString msgExtendingNamespaceRequiresPattern(const QString &name); QString msgInvalidRegularExpression(const QString &pattern, const QString &why); +QString msgNoRootTypeSystemEntry(); + QString msgCyclicDependency(const QString &funcName, const QString &graphName, const QVector &involvedConversions); diff --git a/sources/shiboken2/ApiExtractor/typesystem.cpp b/sources/shiboken2/ApiExtractor/typesystem.cpp index 47feb2c19..a5572354f 100644 --- a/sources/shiboken2/ApiExtractor/typesystem.cpp +++ b/sources/shiboken2/ApiExtractor/typesystem.cpp @@ -43,8 +43,9 @@ static QString strings_jobject = QLatin1String("jobject"); static inline QString callOperator() { return QStringLiteral("operator()"); } -PrimitiveTypeEntry::PrimitiveTypeEntry(const QString &name, const QVersionNumber &vr) : - TypeEntry(name, PrimitiveType, vr), +PrimitiveTypeEntry::PrimitiveTypeEntry(const QString &name, const QVersionNumber &vr, + const TypeEntry *parent) : + TypeEntry(name, PrimitiveType, vr, parent), m_preferredTargetLangType(true) { } @@ -617,8 +618,9 @@ AddedFunction::TypeInfo AddedFunction::TypeInfo::fromSignature(const QString& si } ComplexTypeEntry::ComplexTypeEntry(const QString &name, TypeEntry::Type t, - const QVersionNumber &vr) : - TypeEntry(name, t, vr), + const QVersionNumber &vr, + const TypeEntry *parent) : + TypeEntry(name, t, vr, parent), m_qualifiedCppName(name), m_polymorphicBase(false), m_genericClass(false), @@ -717,7 +719,9 @@ bool TypeEntry::isCppPrimitive() const return typeName.contains(QLatin1Char(' ')) || primitiveCppTypes().contains(typeName); } -TypeEntry::TypeEntry(const QString &name, TypeEntry::Type t, const QVersionNumber &vr) : +TypeEntry::TypeEntry(const QString &name, TypeEntry::Type t, const QVersionNumber &vr, + const TypeEntry *parent) : + m_parent(parent), m_name(name), m_version(vr), m_type(t) @@ -729,6 +733,15 @@ TypeEntry::~TypeEntry() delete m_customConversion; } +const TypeSystemTypeEntry *TypeEntry::typeSystemTypeEntry() const +{ + for (auto e = this; e; e = e->parent()) { + if (e->type() == TypeEntry::TypeSystemType) + return static_cast(e); + } + return nullptr; +} + bool TypeEntry::hasCustomConversion() const { return m_customConversion != nullptr; @@ -760,8 +773,9 @@ void TypeEntry::useAsTypedef(const TypeEntry *source) TypeEntry::TypeEntry(const TypeEntry &) = default; -TypeSystemTypeEntry::TypeSystemTypeEntry(const QString &name, const QVersionNumber &vr) : - TypeEntry(name, TypeSystemType, vr) +TypeSystemTypeEntry::TypeSystemTypeEntry(const QString &name, const QVersionNumber &vr, + const TypeEntry *parent) : + TypeEntry(name, TypeSystemType, vr, parent) { } @@ -773,7 +787,7 @@ TypeEntry *TypeSystemTypeEntry::clone() const TypeSystemTypeEntry::TypeSystemTypeEntry(const TypeSystemTypeEntry &) = default; VoidTypeEntry::VoidTypeEntry() : - TypeEntry(QLatin1String("void"), VoidType, QVersionNumber(0, 0)) + TypeEntry(QLatin1String("void"), VoidType, QVersionNumber(0, 0), nullptr) { } @@ -785,7 +799,7 @@ TypeEntry *VoidTypeEntry::clone() const VoidTypeEntry::VoidTypeEntry(const VoidTypeEntry &) = default; VarargsTypeEntry::VarargsTypeEntry() : - TypeEntry(QLatin1String("..."), VarargsType, QVersionNumber(0, 0)) + TypeEntry(QLatin1String("..."), VarargsType, QVersionNumber(0, 0), nullptr) { } @@ -796,8 +810,9 @@ TypeEntry *VarargsTypeEntry::clone() const VarargsTypeEntry::VarargsTypeEntry(const VarargsTypeEntry &) = default; -TemplateArgumentEntry::TemplateArgumentEntry(const QString &name, const QVersionNumber &vr) : - TypeEntry(name, TemplateArgumentType, vr) +TemplateArgumentEntry::TemplateArgumentEntry(const QString &name, const QVersionNumber &vr, + const TypeEntry *parent) : + TypeEntry(name, TemplateArgumentType, vr, parent) { } @@ -808,8 +823,9 @@ TypeEntry *TemplateArgumentEntry::clone() const TemplateArgumentEntry::TemplateArgumentEntry(const TemplateArgumentEntry &) = default; -ArrayTypeEntry::ArrayTypeEntry(const TypeEntry *nested_type, const QVersionNumber &vr) : - TypeEntry(QLatin1String("Array"), ArrayType, vr), +ArrayTypeEntry::ArrayTypeEntry(const TypeEntry *nested_type, const QVersionNumber &vr, + const TypeEntry *parent) : + TypeEntry(QLatin1String("Array"), ArrayType, vr, parent), m_nestedType(nested_type) { Q_ASSERT(m_nestedType); @@ -835,9 +851,10 @@ TypeEntry *ArrayTypeEntry::clone() const ArrayTypeEntry::ArrayTypeEntry(const ArrayTypeEntry &) = default; EnumTypeEntry::EnumTypeEntry(const QString &nspace, const QString &enumName, - const QVersionNumber &vr) : + const QVersionNumber &vr, + const TypeEntry *parent) : TypeEntry(nspace.isEmpty() ? enumName : nspace + QLatin1String("::") + enumName, - EnumType, vr), + EnumType, vr, parent), m_qualifier(nspace), m_targetLangName(enumName) { @@ -850,8 +867,8 @@ QString EnumTypeEntry::targetLangName() const EnumValueTypeEntry::EnumValueTypeEntry(const QString &name, const QString &value, const EnumTypeEntry *enclosingEnum, - const QVersionNumber &vr) : - TypeEntry(name, TypeEntry::EnumValue, vr), + const QVersionNumber &vr, const TypeEntry *parent) : + TypeEntry(name, TypeEntry::EnumValue, vr, parent), m_value(value), m_enclosingEnum(enclosingEnum) { @@ -864,16 +881,17 @@ TypeEntry *EnumValueTypeEntry::clone() const EnumValueTypeEntry::EnumValueTypeEntry(const EnumValueTypeEntry &) = default; -FlagsTypeEntry::FlagsTypeEntry(const QString &name, const QVersionNumber &vr) : - TypeEntry(name, FlagsType, vr) +FlagsTypeEntry::FlagsTypeEntry(const QString &name, const QVersionNumber &vr, + const TypeEntry *parent) : + TypeEntry(name, FlagsType, vr, parent) { } /* A typedef entry allows for specifying template specializations in the * typesystem XML file. */ TypedefEntry::TypedefEntry(const QString &name, const QString &sourceType, - const QVersionNumber &vr) : - ComplexTypeEntry(name, TypedefType, vr), + const QVersionNumber &vr, const TypeEntry *parent) : + ComplexTypeEntry(name, TypedefType, vr, parent), m_sourceType(sourceType) { } @@ -886,8 +904,9 @@ TypeEntry *TypedefEntry::clone() const TypedefEntry::TypedefEntry(const TypedefEntry &) = default; ContainerTypeEntry::ContainerTypeEntry(const QString &name, Type type, - const QVersionNumber &vr) : - ComplexTypeEntry(name, ContainerType, vr), + const QVersionNumber &vr, + const TypeEntry *parent) : + ComplexTypeEntry(name, ContainerType, vr, parent), m_type(type) { setCodeGeneration(GenerateForSubclass); @@ -897,8 +916,8 @@ SmartPointerTypeEntry::SmartPointerTypeEntry(const QString &name, const QString &getterName, const QString &smartPointerType, const QString &refCountMethodName, - const QVersionNumber &vr) : - ComplexTypeEntry(name, SmartPointerType, vr), + const QVersionNumber &vr, const TypeEntry *parent) : + ComplexTypeEntry(name, SmartPointerType, vr, parent), m_getterName(getterName), m_smartPointerType(smartPointerType), m_refCountMethodName(refCountMethodName) @@ -912,8 +931,9 @@ TypeEntry *SmartPointerTypeEntry::clone() const SmartPointerTypeEntry::SmartPointerTypeEntry(const SmartPointerTypeEntry &) = default; -NamespaceTypeEntry::NamespaceTypeEntry(const QString &name, const QVersionNumber &vr) : - ComplexTypeEntry(name, NamespaceType, vr) +NamespaceTypeEntry::NamespaceTypeEntry(const QString &name, const QVersionNumber &vr, + const TypeEntry *parent) : + ComplexTypeEntry(name, NamespaceType, vr, parent) { } @@ -937,8 +957,9 @@ bool NamespaceTypeEntry::matchesFile(const QString &needle) const return m_filePattern.match(needle).hasMatch(); } -ValueTypeEntry::ValueTypeEntry(const QString &name, const QVersionNumber &vr) : - ComplexTypeEntry(name, BasicValueType, vr) +ValueTypeEntry::ValueTypeEntry(const QString &name, const QVersionNumber &vr, + const TypeEntry *parent) : + ComplexTypeEntry(name, BasicValueType, vr, parent) { } @@ -959,8 +980,9 @@ TypeEntry *ValueTypeEntry::clone() const ValueTypeEntry::ValueTypeEntry(const ValueTypeEntry &) = default; -ValueTypeEntry::ValueTypeEntry(const QString &name, Type t, const QVersionNumber &vr) : - ComplexTypeEntry(name, t, vr) +ValueTypeEntry::ValueTypeEntry(const QString &name, Type t, const QVersionNumber &vr, + const TypeEntry *parent) : + ComplexTypeEntry(name, t, vr, parent) { } @@ -1098,8 +1120,9 @@ void CustomConversion::TargetToNativeConversion::setConversion(const QString& co m_d->conversion = conversion; } -InterfaceTypeEntry::InterfaceTypeEntry(const QString &name, const QVersionNumber &vr) : - ComplexTypeEntry(name, InterfaceType, vr) +InterfaceTypeEntry::InterfaceTypeEntry(const QString &name, const QVersionNumber &vr, + const TypeEntry *parent) : + ComplexTypeEntry(name, InterfaceType, vr, parent) { } @@ -1122,8 +1145,9 @@ TypeEntry *InterfaceTypeEntry::clone() const InterfaceTypeEntry::InterfaceTypeEntry(const InterfaceTypeEntry &) = default; FunctionTypeEntry::FunctionTypeEntry(const QString &name, const QString &signature, - const QVersionNumber &vr) : - TypeEntry(name, FunctionType, vr) + const QVersionNumber &vr, + const TypeEntry *parent) : + TypeEntry(name, FunctionType, vr, parent) { addSignature(signature); } @@ -1135,8 +1159,9 @@ TypeEntry *FunctionTypeEntry::clone() const FunctionTypeEntry::FunctionTypeEntry(const FunctionTypeEntry &) = default; -ObjectTypeEntry::ObjectTypeEntry(const QString &name, const QVersionNumber &vr) - : ComplexTypeEntry(name, ObjectType, vr) +ObjectTypeEntry::ObjectTypeEntry(const QString &name, const QVersionNumber &vr, + const TypeEntry *parent) + : ComplexTypeEntry(name, ObjectType, vr, parent) { } diff --git a/sources/shiboken2/ApiExtractor/typesystem.h b/sources/shiboken2/ApiExtractor/typesystem.h index b55d5dac5..6d7a9d450 100644 --- a/sources/shiboken2/ApiExtractor/typesystem.h +++ b/sources/shiboken2/ApiExtractor/typesystem.h @@ -543,6 +543,7 @@ private: }; class CustomConversion; +class TypeSystemTypeEntry; class TypeEntry { @@ -591,7 +592,8 @@ public: }; Q_ENUM(CodeGeneration) - explicit TypeEntry(const QString &name, Type t, const QVersionNumber &vr); + explicit TypeEntry(const QString &name, Type t, const QVersionNumber &vr, + const TypeEntry *parent); virtual ~TypeEntry(); @@ -599,6 +601,11 @@ public: { return m_type; } + + const TypeEntry *parent() const { return m_parent; } + void setParent(const TypeEntry *p) { m_parent = p; } + const TypeSystemTypeEntry *typeSystemTypeEntry() const; + bool isPrimitive() const { return m_type == PrimitiveType; @@ -899,6 +906,7 @@ protected: TypeEntry(const TypeEntry &); private: + const TypeEntry *m_parent; QString m_name; QString m_targetLangPackage; CustomFunction m_customConstructor; @@ -920,7 +928,8 @@ private: class TypeSystemTypeEntry : public TypeEntry { public: - explicit TypeSystemTypeEntry(const QString &name, const QVersionNumber &vr); + explicit TypeSystemTypeEntry(const QString &name, const QVersionNumber &vr, + const TypeEntry *parent); TypeEntry *clone() const override; @@ -953,7 +962,8 @@ protected: class TemplateArgumentEntry : public TypeEntry { public: - explicit TemplateArgumentEntry(const QString &name, const QVersionNumber &vr); + explicit TemplateArgumentEntry(const QString &name, const QVersionNumber &vr, + const TypeEntry *parent); int ordinal() const { @@ -976,7 +986,8 @@ private: class ArrayTypeEntry : public TypeEntry { public: - explicit ArrayTypeEntry(const TypeEntry *nested_type, const QVersionNumber &vr); + explicit ArrayTypeEntry(const TypeEntry *nested_type, const QVersionNumber &vr, + const TypeEntry *parent); void setNestedTypeEntry(TypeEntry *nested) { @@ -1003,7 +1014,8 @@ private: class PrimitiveTypeEntry : public TypeEntry { public: - explicit PrimitiveTypeEntry(const QString &name, const QVersionNumber &vr); + explicit PrimitiveTypeEntry(const QString &name, const QVersionNumber &vr, + const TypeEntry *parent); QString targetLangName() const override; void setTargetLangName(const QString &targetLangName) @@ -1083,7 +1095,8 @@ class EnumTypeEntry : public TypeEntry { public: explicit EnumTypeEntry(const QString &nspace, const QString &enumName, - const QVersionNumber &vr); + const QVersionNumber &vr, + const TypeEntry *parent); QString targetLangName() const override; QString targetLangQualifier() const; @@ -1149,7 +1162,10 @@ private: class EnumValueTypeEntry : public TypeEntry { public: - explicit EnumValueTypeEntry(const QString& name, const QString& value, const EnumTypeEntry* enclosingEnum, const QVersionNumber &vr); + explicit EnumValueTypeEntry(const QString& name, const QString& value, + const EnumTypeEntry* enclosingEnum, + const QVersionNumber &vr, + const TypeEntry *parent); QString value() const { return m_value; } const EnumTypeEntry* enclosingEnum() const { return m_enclosingEnum; } @@ -1167,7 +1183,8 @@ private: class FlagsTypeEntry : public TypeEntry { public: - explicit FlagsTypeEntry(const QString &name, const QVersionNumber &vr); + explicit FlagsTypeEntry(const QString &name, const QVersionNumber &vr, + const TypeEntry *parent); QString qualifiedTargetLangName() const override; QString targetLangName() const override; @@ -1226,7 +1243,8 @@ public: Unknown }; - explicit ComplexTypeEntry(const QString &name, Type t, const QVersionNumber &vr); + explicit ComplexTypeEntry(const QString &name, Type t, const QVersionNumber &vr, + const TypeEntry *parent); bool isComplex() const override; @@ -1427,7 +1445,8 @@ class TypedefEntry : public ComplexTypeEntry public: explicit TypedefEntry(const QString &name, const QString &sourceType, - const QVersionNumber &vr); + const QVersionNumber &vr, + const TypeEntry *parent); QString sourceType() const { return m_sourceType; } void setSourceType(const QString &s) { m_sourceType =s; } @@ -1473,7 +1492,8 @@ public: }; Q_ENUM(Type) - explicit ContainerTypeEntry(const QString &name, Type type, const QVersionNumber &vr); + explicit ContainerTypeEntry(const QString &name, Type type, const QVersionNumber &vr, + const TypeEntry *parent); Type type() const { @@ -1503,7 +1523,8 @@ public: const QString &getterName, const QString &smartPointerType, const QString &refCountMethodName, - const QVersionNumber &vr); + const QVersionNumber &vr, + const TypeEntry *parent); QString getter() const { @@ -1529,7 +1550,8 @@ private: class NamespaceTypeEntry : public ComplexTypeEntry { public: - explicit NamespaceTypeEntry(const QString &name, const QVersionNumber &vr); + explicit NamespaceTypeEntry(const QString &name, const QVersionNumber &vr, + const TypeEntry *parent); TypeEntry *clone() const override; @@ -1559,7 +1581,8 @@ private: class ValueTypeEntry : public ComplexTypeEntry { public: - explicit ValueTypeEntry(const QString &name, const QVersionNumber &vr); + explicit ValueTypeEntry(const QString &name, const QVersionNumber &vr, + const TypeEntry *parent); bool isValue() const override; @@ -1568,14 +1591,16 @@ public: TypeEntry *clone() const override; protected: - explicit ValueTypeEntry(const QString &name, Type t, const QVersionNumber &vr); + explicit ValueTypeEntry(const QString &name, Type t, const QVersionNumber &vr, + const TypeEntry *parent); ValueTypeEntry(const ValueTypeEntry &); }; class InterfaceTypeEntry : public ComplexTypeEntry { public: - explicit InterfaceTypeEntry(const QString &name, const QVersionNumber &vr); + explicit InterfaceTypeEntry(const QString &name, const QVersionNumber &vr, + const TypeEntry *parent); static QString interfaceName(const QString &name) { @@ -1608,7 +1633,8 @@ class FunctionTypeEntry : public TypeEntry { public: explicit FunctionTypeEntry(const QString& name, const QString& signature, - const QVersionNumber &vr); + const QVersionNumber &vr, + const TypeEntry *parent); void addSignature(const QString& signature) { m_signatures << signature; @@ -1636,7 +1662,8 @@ private: class ObjectTypeEntry : public ComplexTypeEntry { public: - explicit ObjectTypeEntry(const QString &name, const QVersionNumber &vr); + explicit ObjectTypeEntry(const QString &name, const QVersionNumber &vr, + const TypeEntry *parent); InterfaceTypeEntry *designatedInterface() const override; void setDesignatedInterface(InterfaceTypeEntry *entry) diff --git a/sources/shiboken2/ApiExtractor/typesystemparser.cpp b/sources/shiboken2/ApiExtractor/typesystemparser.cpp index 5440de5c0..6ecdf1dc9 100644 --- a/sources/shiboken2/ApiExtractor/typesystemparser.cpp +++ b/sources/shiboken2/ApiExtractor/typesystemparser.cpp @@ -1040,6 +1040,19 @@ static QString checkSignatureError(const QString& signature, const QString& tag) return QString(); } +inline const TypeEntry *TypeSystemParser::currentParentTypeEntry() const +{ + return m_current ? m_current->entry : nullptr; +} + +bool TypeSystemParser::checkRootElement() +{ + const bool ok = currentParentTypeEntry() != nullptr; + if (!ok) + m_error = msgNoRootTypeSystemEntry(); + return ok; +} + void TypeSystemParser::applyCommonAttributes(TypeEntry *type, QXmlStreamAttributes *attributes) const { type->setCodeGeneration(m_generate); @@ -1057,7 +1070,11 @@ FlagsTypeEntry * QXmlStreamAttributes *attributes) { - FlagsTypeEntry *ftype = new FlagsTypeEntry(QLatin1String("QFlags<") + name + QLatin1Char('>'), since); + if (!checkRootElement()) + return nullptr; + auto ftype = new FlagsTypeEntry(QLatin1String("QFlags<") + name + QLatin1Char('>'), + since, + currentParentTypeEntry()->typeSystemTypeEntry()); ftype->setOriginator(enumEntry); ftype->setTargetLangPackage(enumEntry->targetLangPackage()); // Try to get the guess the qualified flag name @@ -1096,6 +1113,8 @@ SmartPointerTypeEntry * const QString &name, const QVersionNumber &since, QXmlStreamAttributes *attributes) { + if (!checkRootElement()) + return nullptr; QString smartPointerType; QString getter; QString refCountMethodName; @@ -1138,7 +1157,8 @@ SmartPointerTypeEntry * return nullptr; } - auto *type = new SmartPointerTypeEntry(name, getter, smartPointerType, refCountMethodName, since); + auto *type = new SmartPointerTypeEntry(name, getter, smartPointerType, + refCountMethodName, since, currentParentTypeEntry()); applyCommonAttributes(type, attributes); return type; } @@ -1148,7 +1168,9 @@ PrimitiveTypeEntry * const QString &name, const QVersionNumber &since, QXmlStreamAttributes *attributes) { - auto *type = new PrimitiveTypeEntry(name, since); + if (!checkRootElement()) + return nullptr; + auto *type = new PrimitiveTypeEntry(name, since, currentParentTypeEntry()); applyCommonAttributes(type, attributes); for (int i = attributes->size() - 1; i >= 0; --i) { const QStringRef name = attributes->at(i).qualifiedName(); @@ -1181,6 +1203,8 @@ ContainerTypeEntry * const QString &name, const QVersionNumber &since, QXmlStreamAttributes *attributes) { + if (!checkRootElement()) + return nullptr; const int typeIndex = indexOfAttribute(*attributes, u"type"); if (typeIndex == -1) { m_error = QLatin1String("no 'type' attribute specified"); @@ -1192,7 +1216,7 @@ ContainerTypeEntry * m_error = QLatin1String("there is no container of type ") + typeName.toString(); return nullptr; } - auto *type = new ContainerTypeEntry(name, containerType, since); + auto *type = new ContainerTypeEntry(name, containerType, since, currentParentTypeEntry()); applyCommonAttributes(type, attributes); return type; } @@ -1202,6 +1226,8 @@ EnumTypeEntry * const QString &fullName, const QVersionNumber &since, QXmlStreamAttributes *attributes) { + if (!checkRootElement()) + return nullptr; QString scope; QString name = fullName; const int sep = fullName.lastIndexOf(colonColon()); @@ -1209,7 +1235,7 @@ EnumTypeEntry * scope = fullName.left(sep); name = fullName.right(fullName.size() - sep - 2); } - auto *entry = new EnumTypeEntry(scope, name, since); + auto *entry = new EnumTypeEntry(scope, name, since, currentParentTypeEntry()); applyCommonAttributes(entry, attributes); entry->setTargetLangPackage(m_defaultPackage); @@ -1247,7 +1273,9 @@ ObjectTypeEntry * const QString &name, const QVersionNumber &since, QXmlStreamAttributes *attributes) { - auto *otype = new ObjectTypeEntry(name, since); + if (!checkRootElement()) + return nullptr; + auto *otype = new ObjectTypeEntry(name, since, currentParentTypeEntry()); applyCommonAttributes(otype, attributes); QString targetLangName = name; bool generate = true; @@ -1261,8 +1289,8 @@ ObjectTypeEntry * } } - InterfaceTypeEntry *itype = - new InterfaceTypeEntry(InterfaceTypeEntry::interfaceName(targetLangName), since); + auto itype = new InterfaceTypeEntry(InterfaceTypeEntry::interfaceName(targetLangName), + since, currentParentTypeEntry()); if (generate) itype->setCodeGeneration(m_generate); @@ -1279,7 +1307,9 @@ NamespaceTypeEntry * const QString &name, const QVersionNumber &since, QXmlStreamAttributes *attributes) { - QScopedPointer result(new NamespaceTypeEntry(name, since)); + if (!checkRootElement()) + return nullptr; + QScopedPointer result(new NamespaceTypeEntry(name, since, currentParentTypeEntry())); applyCommonAttributes(result.data(), attributes); applyComplexTypeAttributes(reader, result.data(), attributes); for (int i = attributes->size() - 1; i >= 0; --i) { @@ -1320,7 +1350,9 @@ ValueTypeEntry * const QString &name, const QVersionNumber &since, QXmlStreamAttributes *attributes) { - auto *typeEntry = new ValueTypeEntry(name, since); + if (!checkRootElement()) + return nullptr; + auto *typeEntry = new ValueTypeEntry(name, since, currentParentTypeEntry()); applyCommonAttributes(typeEntry, attributes); const int defaultCtIndex = indexOfAttribute(*attributes, u"default-constructor"); @@ -1334,6 +1366,8 @@ FunctionTypeEntry * const QString &name, const QVersionNumber &since, QXmlStreamAttributes *attributes) { + if (!checkRootElement()) + return nullptr; const int signatureIndex = indexOfAttribute(*attributes, signatureAttribute()); if (signatureIndex == -1) { m_error = msgMissingAttribute(signatureAttribute()); @@ -1345,7 +1379,7 @@ FunctionTypeEntry * TypeEntry *existingType = m_database->findType(name); if (!existingType) { - auto *result = new FunctionTypeEntry(name, signature, since); + auto *result = new FunctionTypeEntry(name, signature, since, currentParentTypeEntry()); applyCommonAttributes(result, attributes); return result; } @@ -1366,6 +1400,8 @@ TypedefEntry * const QVersionNumber &since, QXmlStreamAttributes *attributes) { + if (!checkRootElement()) + return nullptr; if (m_current && m_current->type != StackElement::Root && m_current->type != StackElement::NamespaceTypeEntry) { m_error = QLatin1String("typedef entries must be nested in namespaces or type system."); @@ -1377,7 +1413,7 @@ TypedefEntry * return nullptr; } const QString sourceType = attributes->takeAt(sourceIndex).value().toString(); - auto result = new TypedefEntry(name, sourceType, since); + auto result = new TypedefEntry(name, sourceType, since, currentParentTypeEntry()); applyCommonAttributes(result, attributes); return result; } @@ -1618,8 +1654,10 @@ TypeSystemTypeEntry *TypeSystemParser::parseRootElement(const QXmlStreamReader & auto *moduleEntry = const_cast(m_database->findTypeSystemType(m_defaultPackage)); const bool add = moduleEntry == nullptr; - if (add) - moduleEntry = new TypeSystemTypeEntry(m_defaultPackage, since); + if (add) { + moduleEntry = new TypeSystemTypeEntry(m_defaultPackage, since, + currentParentTypeEntry()); + } moduleEntry->setCodeGeneration(m_generate); if ((m_generate == TypeEntry::GenerateForSubclass || @@ -2691,7 +2729,9 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader) switch (element->type) { case StackElement::CustomTypeEntry: - element->entry = new TypeEntry(name, TypeEntry::CustomType, since); + if (!checkRootElement()) + return false; + element->entry = new TypeEntry(name, TypeEntry::CustomType, since, m_current->entry); break; case StackElement::PrimitiveTypeEntry: element->entry = parsePrimitiveTypeEntry(reader, name, since, &attributes); @@ -2745,7 +2785,9 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader) return false; break; case StackElement::ObjectTypeEntry: - element->entry = new ObjectTypeEntry(name, since); + if (!checkRootElement()) + return false; + element->entry = new ObjectTypeEntry(name, since, currentParentTypeEntry()); applyCommonAttributes(element->entry, &attributes); applyComplexTypeAttributes(reader, static_cast(element->entry), &attributes); break; diff --git a/sources/shiboken2/ApiExtractor/typesystemparser.h b/sources/shiboken2/ApiExtractor/typesystemparser.h index aaf22353e..afe68a689 100644 --- a/sources/shiboken2/ApiExtractor/typesystemparser.h +++ b/sources/shiboken2/ApiExtractor/typesystemparser.h @@ -162,6 +162,8 @@ private: bool importFileElement(const QXmlStreamAttributes &atts); + const TypeEntry *currentParentTypeEntry() const; + bool checkRootElement(); void applyCommonAttributes(TypeEntry *type, QXmlStreamAttributes *attributes) const; PrimitiveTypeEntry * parsePrimitiveTypeEntry(const QXmlStreamReader &, const QString &name, -- cgit v1.2.3