aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp')
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp136
1 files changed, 101 insertions, 35 deletions
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
index ce361245c..9807e1ea6 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
@@ -531,13 +531,22 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom,
ReportHandler::startProgress("Generated enum model ("
+ QByteArray::number(enums.size()) + ").");
for (const EnumModelItem &item : enums) {
- auto metaEnum = traverseEnum(item, nullptr, QSet<QString>());
+ auto metaEnum = traverseEnum(item, nullptr);
if (metaEnum.has_value()) {
if (metaEnum->typeEntry()->generateCode())
m_globalEnums << metaEnum.value();
}
}
+ const auto &globalTypeDefs = dom->typeDefs();
+ for (const auto &typeDef : globalTypeDefs) {
+ if (typeDef->underlyingTypeCategory() == TypeCategory::Enum) {
+ const auto metaEnum = traverseTypedefedEnum(dom, typeDef, {});
+ if (metaEnum.has_value())
+ m_globalEnums.append(metaEnum.value());
+ }
+ }
+
const auto &namespaceTypeValues = dom->namespaces();
ReportHandler::startProgress("Generated namespace model ("
+ QByteArray::number(namespaceTypeValues.size()) + ").");
@@ -765,7 +774,7 @@ AbstractMetaClassPtr
AbstractMetaBuilderPrivate::traverseNamespace(const FileModelItem &dom,
const NamespaceModelItem &namespaceItem)
{
- QString namespaceName = currentScope()->qualifiedName().join(u"::"_s);
+ QString namespaceName = currentScope()->qualifiedNameString();
if (!namespaceName.isEmpty())
namespaceName.append(u"::"_s);
namespaceName.append(namespaceItem->name());
@@ -809,7 +818,7 @@ AbstractMetaClassPtr
m_itemToClass.insert(namespaceItem.get(), metaClass);
}
- traverseEnums(namespaceItem, metaClass, namespaceItem->enumsDeclarations());
+ traverseEnums(namespaceItem, metaClass);
pushScope(namespaceItem);
@@ -827,11 +836,20 @@ AbstractMetaClassPtr
// specific typedefs to be used as classes.
const TypeDefList typeDefs = namespaceItem->typeDefs();
for (const TypeDefModelItem &typeDef : typeDefs) {
- const auto cls = traverseTypeDef(dom, typeDef, metaClass);
- if (cls) {
- metaClass->addInnerClass(cls);
- cls->setEnclosingClass(metaClass);
- addAbstractMetaClass(cls, typeDef.get());
+ switch (typeDef->underlyingTypeCategory()) {
+ case TypeCategory::Enum: {
+ const auto metaEnum = traverseTypedefedEnum(dom, typeDef, metaClass);
+ if (metaEnum.has_value())
+ metaClass->addEnum(metaEnum.value());
+ }
+ break;
+ default:
+ if (const auto cls = traverseTypeDef(dom, typeDef, metaClass)) {
+ metaClass->addInnerClass(cls);
+ cls->setEnclosingClass(metaClass);
+ addAbstractMetaClass(cls, typeDef.get());
+ }
+ break;
}
}
@@ -856,16 +874,15 @@ AbstractMetaClassPtr
std::optional<AbstractMetaEnum>
AbstractMetaBuilderPrivate::traverseEnum(const EnumModelItem &enumItem,
- const AbstractMetaClassPtr &enclosing,
- const QSet<QString> &enumsDeclarations)
+ const AbstractMetaClassPtr &enclosing)
{
- QString qualifiedName = enumItem->qualifiedName().join(u"::"_s);
+ QString qualifiedName = enumItem->qualifiedNameString();
TypeEntryPtr typeEntry;
- const auto enclosingTypeEntry = enclosing ? enclosing->typeEntry() : TypeEntryCPtr{};
if (enumItem->accessPolicy() == Access::Private) {
+ Q_ASSERT(enclosing);
typeEntry = std::make_shared<EnumTypeEntry>(enumItem->qualifiedName().constLast(),
- QVersionNumber(0, 0), enclosingTypeEntry);
+ QVersionNumber(0, 0), enclosing->typeEntry());
TypeDatabase::instance()->addType(typeEntry);
} else if (enumItem->enumKind() != AnonymousEnum) {
typeEntry = TypeDatabase::instance()->findType(qualifiedName);
@@ -881,12 +898,17 @@ std::optional<AbstractMetaEnum>
break;
}
}
+ return createMetaEnum(enumItem, qualifiedName, typeEntry, enclosing);
+}
- QString enumName = enumItem->name();
-
- QString className;
- if (enclosingTypeEntry)
- className = enclosingTypeEntry->qualifiedCppName();
+std::optional<AbstractMetaEnum>
+ AbstractMetaBuilderPrivate::createMetaEnum(const EnumModelItem &enumItem,
+ const QString &qualifiedName,
+ const TypeEntryPtr &typeEntry,
+ const AbstractMetaClassPtr &enclosing)
+{
+ const QString enumName = enumItem->name();
+ const QString className = enclosing ? enclosing->typeEntry()->qualifiedCppName() : QString{};
QString rejectReason;
if (TypeDatabase::instance()->isEnumRejected(className, enumName, &rejectReason)) {
@@ -922,10 +944,6 @@ std::optional<AbstractMetaEnum>
metaEnum.setDeprecated(enumItem->isDeprecated());
metaEnum.setUnderlyingType(enumItem->underlyingType());
metaEnum.setSigned(enumItem->isSigned());
- if (enumsDeclarations.contains(qualifiedName)
- || enumsDeclarations.contains(enumName)) {
- metaEnum.setHasQEnumsDeclaration(true);
- }
auto enumTypeEntry = std::static_pointer_cast<EnumTypeEntry>(typeEntry);
metaEnum.setTypeEntry(enumTypeEntry);
@@ -972,6 +990,49 @@ std::optional<AbstractMetaEnum>
return metaEnum;
}
+// Add typedef'ed enumerations ("Using MyEnum=SomeNamespace::MyEnum") for which
+// a type entry exists.
+std::optional<AbstractMetaEnum>
+ AbstractMetaBuilderPrivate::traverseTypedefedEnum(const FileModelItem &dom,
+ const TypeDefModelItem &typeDefItem,
+ const AbstractMetaClassPtr &enclosing)
+{
+ if (enclosing && typeDefItem->accessPolicy() != Access::Public)
+ return std::nullopt; // Only for global/public enums typedef'ed into classes/namespaces
+ auto modelItem = CodeModel::findItem(typeDefItem->type().qualifiedName(), dom);
+ if (!modelItem || modelItem->kind() != _CodeModelItem::Kind_Enum)
+ return std::nullopt;
+ auto enumItem = std::static_pointer_cast<_EnumModelItem>(modelItem);
+ if (enumItem->accessPolicy() != Access::Public)
+ return std::nullopt;
+ // Name in class
+ QString qualifiedName = enclosing
+ ? enclosing->qualifiedCppName() + "::"_L1 + typeDefItem->name() : typeDefItem->name();
+ auto targetTypeEntry = TypeDatabase::instance()->findType(qualifiedName);
+ if (!targetTypeEntry || !targetTypeEntry->isEnum() || !targetTypeEntry->generateCode())
+ return std::nullopt;
+ auto targetEnumTypeEntry = std::static_pointer_cast<EnumTypeEntry>(targetTypeEntry);
+ auto sourceTypeEntry = TypeDatabase::instance()->findType(enumItem->qualifiedNameString());
+ if (!sourceTypeEntry || !sourceTypeEntry->isEnum())
+ return std::nullopt;
+
+ auto sourceEnumTypeEntry = std::static_pointer_cast<EnumTypeEntry>(sourceTypeEntry);
+ if (sourceEnumTypeEntry == targetEnumTypeEntry) // Reject "typedef Enum1 { V1 } Enum1;"
+ return std::nullopt;
+
+ const QString message = "Enum \""_L1 + qualifiedName + "\" is an alias to \""_L1
+ + enumItem->qualifiedNameString() + "\"."_L1;
+ ReportHandler::addGeneralMessage(message);
+ auto result = createMetaEnum(enumItem, qualifiedName, targetTypeEntry, enclosing);
+ if (result.has_value()) {
+ targetEnumTypeEntry->setAliasMode(EnumTypeEntry::AliasTarget);
+ targetEnumTypeEntry->setAliasTypeEntry(sourceEnumTypeEntry);
+ sourceEnumTypeEntry->setAliasMode(EnumTypeEntry::AliasSource);
+ sourceEnumTypeEntry->setAliasTypeEntry(targetEnumTypeEntry);
+ }
+ return result;
+}
+
AbstractMetaClassPtr
AbstractMetaBuilderPrivate::traverseTypeDef(const FileModelItem &dom,
const TypeDefModelItem &typeDef,
@@ -1177,7 +1238,7 @@ AbstractMetaClassPtr AbstractMetaBuilderPrivate::traverseClass(const FileModelIt
parseQ_Properties(metaClass, classItem->propertyDeclarations());
- traverseEnums(classItem, metaClass, classItem->enumsDeclarations());
+ traverseEnums(classItem, metaClass);
// Inner classes
{
@@ -1197,10 +1258,20 @@ AbstractMetaClassPtr AbstractMetaBuilderPrivate::traverseClass(const FileModelIt
// specific typedefs to be used as classes.
const TypeDefList typeDefs = classItem->typeDefs();
for (const TypeDefModelItem &typeDef : typeDefs) {
- const auto cls = traverseTypeDef(dom, typeDef, metaClass);
- if (cls) {
- cls->setEnclosingClass(metaClass);
- addAbstractMetaClass(cls, typeDef.get());
+ if (typeDef->accessPolicy() != Access::Private) {
+ switch (typeDef->underlyingTypeCategory()) {
+ case TypeCategory::Enum: {
+ const auto metaEnum = traverseTypedefedEnum(dom, typeDef, metaClass);
+ if (metaEnum.has_value())
+ metaClass->addEnum(metaEnum.value());
+ }
+ break;
+ default:
+ if (const auto cls = traverseTypeDef(dom, typeDef, metaClass)) {
+ cls->setEnclosingClass(metaClass);
+ addAbstractMetaClass(cls, typeDef.get());
+ }
+ }
}
}
@@ -1648,13 +1719,11 @@ bool AbstractMetaBuilderPrivate::setupInheritance(const AbstractMetaClassPtr &me
}
void AbstractMetaBuilderPrivate::traverseEnums(const ScopeModelItem &scopeItem,
- const AbstractMetaClassPtr &metaClass,
- const QStringList &enumsDeclarations)
+ const AbstractMetaClassPtr &metaClass)
{
const EnumList &enums = scopeItem->enums();
- const QSet<QString> enumsDeclarationSet(enumsDeclarations.cbegin(), enumsDeclarations.cend());
for (const EnumModelItem &enumItem : enums) {
- auto metaEnum = traverseEnum(enumItem, metaClass, enumsDeclarationSet);
+ auto metaEnum = traverseEnum(enumItem, metaClass);
if (metaEnum.has_value()) {
metaClass->addEnum(metaEnum.value());
}
@@ -1713,10 +1782,7 @@ AbstractMetaFunctionPtr
const auto &args = addedFunc->arguments();
- qsizetype argCount = args.size();
- // Check "foo(void)"
- if (argCount == 1 && args.constFirst().typeInfo.isVoid())
- argCount = 0;
+ const qsizetype argCount = args.size();
for (qsizetype i = 0; i < argCount; ++i) {
const AddedFunction::Argument &arg = args.at(i);
auto type = translateType(arg.typeInfo, metaClass, {}, errorMessage);