aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2019-05-24 09:47:11 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2019-05-24 09:47:11 +0200
commit235092d72f57d42de04501b04f6a3ff4d77adf74 (patch)
treef887244a022ea8508055412cb3e85ba8158cf509 /sources/shiboken2
parent6ba23a245449aaa9c1a7ab8e954d93f5f4366530 (diff)
parent8c772c12612b408b42e66ad0627d37477f42255a (diff)
Merge remote-tracking branch 'origin/5.13' into dev
Diffstat (limited to 'sources/shiboken2')
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp56
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h6
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.h8
-rw-r--r--sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp14
-rw-r--r--sources/shiboken2/ApiExtractor/messages.cpp29
-rw-r--r--sources/shiboken2/ApiExtractor/messages.h9
-rw-r--r--sources/shiboken2/ApiExtractor/parser/codemodel.cpp16
-rw-r--r--sources/shiboken2/ApiExtractor/parser/codemodel.h4
-rw-r--r--sources/shiboken2/ApiExtractor/typedatabase.cpp34
-rw-r--r--sources/shiboken2/ApiExtractor/typedatabase.h3
-rw-r--r--sources/shiboken2/ApiExtractor/typedatabase_typedefs.h2
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.cpp66
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.h20
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem_p.h6
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp12
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.cpp10
16 files changed, 255 insertions, 40 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
index cfe9d7d89..6cb0d1fe5 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
@@ -452,10 +452,8 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
const auto &namespaceTypeValues = dom->namespaces();
ReportHandler::startProgress("Generating namespace model ("
+ QByteArray::number(namespaceTypeValues.size()) + ")...");
- for (const NamespaceModelItem &item : namespaceTypeValues) {
- if (AbstractMetaClass *metaClass = traverseNamespace(dom, item))
- addAbstractMetaClass(metaClass, item.data());
- }
+ for (const NamespaceModelItem &item : namespaceTypeValues)
+ traverseNamespace(dom, item);
// Go through all typedefs to see if we have defined any
// specific typedefs to be used as classes.
@@ -742,23 +740,38 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel
if (!namespaceName.isEmpty())
namespaceName.append(colonColon());
namespaceName.append(namespaceItem->name());
- NamespaceTypeEntry *type = TypeDatabase::instance()->findNamespaceType(namespaceName);
if (TypeDatabase::instance()->isClassRejected(namespaceName)) {
m_rejectedClasses.insert(namespaceName, AbstractMetaBuilder::GenerationDisabled);
return 0;
}
+ auto type = TypeDatabase::instance()->findNamespaceType(namespaceName, namespaceItem->fileName());
if (!type) {
qCWarning(lcShiboken).noquote().nospace()
<< QStringLiteral("namespace '%1' does not have a type entry").arg(namespaceName);
return 0;
}
- AbstractMetaClass* metaClass = new AbstractMetaClass;
- metaClass->setTypeEntry(type);
-
- *metaClass += AbstractMetaAttributes::Public;
+ // Continue populating namespace?
+ AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_metaClasses, type);
+ if (!metaClass) {
+ metaClass = new AbstractMetaClass;
+ metaClass->setTypeEntry(type);
+ *metaClass += AbstractMetaAttributes::Public;
+ addAbstractMetaClass(metaClass, namespaceItem.data());
+ if (auto extendsType = type->extends()) {
+ AbstractMetaClass *extended = AbstractMetaClass::findClass(m_metaClasses, extendsType);
+ if (!extended) {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgNamespaceToBeExtendedNotFound(extendsType->name(), extendsType->targetLangPackage())));
+ return nullptr;
+ }
+ metaClass->setExtendedNamespace(extended);
+ }
+ } else {
+ m_itemToClass.insert(namespaceItem.data(), metaClass);
+ }
if (ReportHandler::isDebug(ReportHandler::SparseDebug)) {
qCDebug(lcShiboken)
@@ -797,7 +810,6 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel
if (mjc) {
metaClass->addInnerClass(mjc);
mjc->setEnclosingClass(metaClass);
- addAbstractMetaClass(mjc, ni.data());
}
}
@@ -3076,6 +3088,30 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const
return result;
}
+void AbstractMetaBuilderPrivate::pushScope(const NamespaceModelItem &item)
+{
+ // For purposes of type lookup, join all namespaces of the same name
+ // within the parent item.
+ QVector<NamespaceModelItem> candidates;
+ const QString name = item->name();
+ if (!m_scopes.isEmpty()) {
+ for (const auto &n : m_scopes.constLast()->namespaces()) {
+ if (n->name() == name)
+ candidates.append(n);
+ }
+ }
+ if (candidates.size() > 1) {
+ NamespaceModelItem joined(new _NamespaceModelItem(m_scopes.constLast()->model(),
+ name, _CodeModelItem::Kind_Namespace));
+ joined->setScope(item->scope());
+ for (const auto &n : candidates)
+ joined->appendNamespace(*n);
+ m_scopes << joined;
+ } else {
+ m_scopes << item;
+ }
+}
+
AbstractMetaClassList AbstractMetaBuilder::classesTopologicalSorted(const AbstractMetaClassList &classList,
const Dependencies &additionalDependencies) const
{
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
index 3c0039f0e..1fd5f3c34 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
@@ -56,9 +56,9 @@ public:
const Dependencies &additionalDependencies = Dependencies()) const;
ScopeModelItem popScope() { return m_scopes.takeLast(); }
- void pushScope(ScopeModelItem item) { m_scopes << item; }
+ void pushScope(const NamespaceModelItem &item);
- ScopeModelItem currentScope() const { return m_scopes.constLast(); }
+ NamespaceModelItem currentScope() const { return m_scopes.constLast(); }
AbstractMetaClass *argumentToClass(const ArgumentModelItem &,
AbstractMetaClass *currentClass);
@@ -182,7 +182,7 @@ public:
QHash<const TypeEntry *, AbstractMetaEnum *> m_enums;
- QList<ScopeModelItem> m_scopes;
+ QList<NamespaceModelItem> m_scopes;
QSet<AbstractMetaClass *> m_setupInheritanceDone;
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h
index ef4cef2b4..e8ec21f48 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h
@@ -1486,6 +1486,12 @@ public:
return m_enclosingClass;
}
+ /**
+ * \return the namespace from another package which this namespace extends.
+ */
+ AbstractMetaClass *extendedNamespace() const { return m_extendedNamespace; }
+ void setExtendedNamespace(AbstractMetaClass *e) { m_extendedNamespace = e; }
+
void setEnclosingClass(AbstractMetaClass *cl)
{
m_enclosingClass = cl;
@@ -1729,6 +1735,8 @@ private:
const AbstractMetaClass *m_enclosingClass = nullptr;
AbstractMetaClass *m_baseClass = nullptr;
+ AbstractMetaClass *m_extendedNamespace = nullptr;
+
const AbstractMetaClass *m_templateBaseClass = nullptr;
AbstractMetaFunctionList m_functions;
AbstractMetaFieldList m_fields;
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
index 40f915028..3ced0e06c 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
@@ -885,15 +885,13 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
appendDiagnostic(d);
return Error;
}
- // If possible, continue existing namespace (as otherwise, all headers
- // where a namespace is continued show up in the type database).
+ // Treat namespaces separately to allow for extending namespaces
+ // in subsequent modules.
NamespaceModelItem namespaceItem = parentNamespaceItem->findNamespace(name);
- if (namespaceItem.isNull()) {
- namespaceItem.reset(new _NamespaceModelItem(d->m_model, name));
- setFileName(cursor, namespaceItem.data());
- namespaceItem->setScope(d->m_scope);
- parentNamespaceItem->addNamespace(namespaceItem);
- }
+ namespaceItem.reset(new _NamespaceModelItem(d->m_model, name));
+ setFileName(cursor, namespaceItem.data());
+ namespaceItem->setScope(d->m_scope);
+ parentNamespaceItem->addNamespace(namespaceItem);
d->pushScope(namespaceItem);
}
break;
diff --git a/sources/shiboken2/ApiExtractor/messages.cpp b/sources/shiboken2/ApiExtractor/messages.cpp
index fdae2359b..a6e75aac3 100644
--- a/sources/shiboken2/ApiExtractor/messages.cpp
+++ b/sources/shiboken2/ApiExtractor/messages.cpp
@@ -206,8 +206,6 @@ QString msgCannotTranslateTemplateArgument(int i,
return result;
}
-// abstractmetalang.cpp
-
QString msgDisallowThread(const AbstractMetaFunction *f)
{
QString result;
@@ -219,6 +217,13 @@ QString msgDisallowThread(const AbstractMetaFunction *f)
return result;
}
+QString msgNamespaceToBeExtendedNotFound(const QString &namespaceName, const QString &packageName)
+{
+ return QLatin1String("The namespace '") + namespaceName
+ + QLatin1String("' to be extended cannot be found in package ")
+ + packageName + QLatin1Char('.');
+}
+
// docparser.cpp
QString msgCannotFindDocumentation(const QString &fileName,
@@ -421,6 +426,26 @@ QString msgRejectReason(const TypeRejection &r, const QString &needle)
return result;
}
+// typesystem.cpp
+
+QString msgCannotFindNamespaceToExtend(const QString &name,
+ const QStringRef &extendsPackage)
+{
+ return QLatin1String("Cannot find namespace ") + name
+ + QLatin1String(" in package ") + extendsPackage;
+}
+
+QString msgExtendingNamespaceRequiresPattern(const QString &name)
+{
+ return QLatin1String("Namespace ") + name
+ + QLatin1String(" requires a file pattern since it extends another namespace.");
+}
+
+QString msgInvalidRegularExpression(const QString &pattern, const QString &why)
+{
+ return QLatin1String("Invalid pattern \"") + pattern + QLatin1String("\": ") + why;
+}
+
// 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 30b13fbf8..ab2bf64b6 100644
--- a/sources/shiboken2/ApiExtractor/messages.h
+++ b/sources/shiboken2/ApiExtractor/messages.h
@@ -85,6 +85,8 @@ QString msgCannotTranslateTemplateArgument(int i,
QString msgDisallowThread(const AbstractMetaFunction *f);
+QString msgNamespaceToBeExtendedNotFound(const QString &namespaceName, const QString &packageName);
+
QString msgCannotFindDocumentation(const QString &fileName,
const char *what, const QString &name,
const QString &query);
@@ -117,6 +119,13 @@ QString msgLeftOverArguments(const QMap<QString, QString> &remainingArgs);
QString msgInvalidVersion(const QString &package, const QString &version);
+QString msgCannotFindNamespaceToExtend(const QString &name,
+ const QStringRef &extendsPackage);
+
+QString msgExtendingNamespaceRequiresPattern(const QString &name);
+
+QString msgInvalidRegularExpression(const QString &pattern, const QString &why);
+
QString msgCyclicDependency(const QString &funcName, const QString &graphName,
const QVector<const AbstractMetaFunction *> &involvedConversions);
diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.cpp b/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
index 9a845b04a..eb0f44689 100644
--- a/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
+++ b/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
@@ -773,6 +773,16 @@ void _ScopeModelItem::addEnum(EnumModelItem item)
m_enums.append(item);
}
+void _ScopeModelItem::appendScope(const _ScopeModelItem &other)
+{
+ m_classes += other.m_classes;
+ m_enums += other.m_enums;
+ m_typeDefs += other.m_typeDefs;
+ m_variables += other.m_variables;
+ m_functions += other.m_functions;
+ m_enumsDeclarations += other.m_enumsDeclarations;
+}
+
#ifndef QT_NO_DEBUG_STREAM
template <class Hash>
static void formatScopeHash(QDebug &d, const char *prefix, const Hash &h,
@@ -899,6 +909,12 @@ _FileModelItem::~_FileModelItem()
{
}
+void _NamespaceModelItem::appendNamespace(const _NamespaceModelItem &other)
+{
+ appendScope(other);
+ m_namespaces += other.m_namespaces;
+}
+
#ifndef QT_NO_DEBUG_STREAM
void _NamespaceModelItem::formatDebug(QDebug &d) const
{
diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.h b/sources/shiboken2/ApiExtractor/parser/codemodel.h
index 64415e07b..3bce5e216 100644
--- a/sources/shiboken2/ApiExtractor/parser/codemodel.h
+++ b/sources/shiboken2/ApiExtractor/parser/codemodel.h
@@ -360,6 +360,8 @@ protected:
explicit _ScopeModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
: _CodeModelItem(model, name, kind) {}
+ void appendScope(const _ScopeModelItem &other);
+
#ifndef QT_NO_DEBUG_STREAM
void formatScopeItemsDebug(QDebug &d) const;
#endif
@@ -440,6 +442,8 @@ public:
NamespaceModelItem findNamespace(const QString &name) const;
+ void appendNamespace(const _NamespaceModelItem &other);
+
#ifndef QT_NO_DEBUG_STREAM
void formatDebug(QDebug &d) const override;
#endif
diff --git a/sources/shiboken2/ApiExtractor/typedatabase.cpp b/sources/shiboken2/ApiExtractor/typedatabase.cpp
index a8c69d376..930f85d30 100644
--- a/sources/shiboken2/ApiExtractor/typedatabase.cpp
+++ b/sources/shiboken2/ApiExtractor/typedatabase.cpp
@@ -621,14 +621,33 @@ ObjectTypeEntry* TypeDatabase::findObjectType(const QString& name) const
return 0;
}
-NamespaceTypeEntry* TypeDatabase::findNamespaceType(const QString& name) const
+NamespaceTypeEntryList TypeDatabase::findNamespaceTypes(const QString& name) const
{
+ NamespaceTypeEntryList result;
const auto entries = findTypes(name);
for (TypeEntry *entry : entries) {
- if (entry->isNamespace() && useType(entry))
- return static_cast<NamespaceTypeEntry*>(entry);
+ if (entry->isNamespace())
+ result.append(static_cast<NamespaceTypeEntry*>(entry));
}
- return 0;
+ return result;
+}
+
+NamespaceTypeEntry *TypeDatabase::findNamespaceType(const QString& name,
+ const QString &fileName) const
+{
+ const auto entries = findNamespaceTypes(name);
+ // Preferably check on matching file name first, if a pattern was given.
+ if (!fileName.isEmpty()) {
+ for (NamespaceTypeEntry *entry : entries) {
+ if (entry->hasPattern() && entry->matchesFile(fileName))
+ return entry;
+ }
+ }
+ for (NamespaceTypeEntry *entry : entries) {
+ if (!entry->hasPattern())
+ return entry;
+ }
+ return nullptr;
}
bool TypeDatabase::shouldDropTypeEntry(const QString& fullTypeName) const
@@ -836,6 +855,13 @@ void EnumTypeEntry::formatDebug(QDebug &d) const
d << ", flags=(" << m_flags << ')';
}
+void NamespaceTypeEntry::formatDebug(QDebug &d) const
+{
+ ComplexTypeEntry::formatDebug(d);
+ auto pattern = m_filePattern.pattern();
+ FORMAT_NONEMPTY_STRING("pattern", pattern)
+}
+
void ContainerTypeEntry::formatDebug(QDebug &d) const
{
ComplexTypeEntry::formatDebug(d);
diff --git a/sources/shiboken2/ApiExtractor/typedatabase.h b/sources/shiboken2/ApiExtractor/typedatabase.h
index 0040364bf..7f1b2a3fc 100644
--- a/sources/shiboken2/ApiExtractor/typedatabase.h
+++ b/sources/shiboken2/ApiExtractor/typedatabase.h
@@ -87,7 +87,8 @@ public:
PrimitiveTypeEntry* findPrimitiveType(const QString& name) const;
ComplexTypeEntry* findComplexType(const QString& name) const;
ObjectTypeEntry* findObjectType(const QString& name) const;
- NamespaceTypeEntry* findNamespaceType(const QString& name) const;
+ NamespaceTypeEntryList findNamespaceTypes(const QString& name) const;
+ NamespaceTypeEntry *findNamespaceType(const QString& name, const QString &fileName = QString()) const;
ContainerTypeEntry* findContainerType(const QString& name) const;
FunctionTypeEntry* findFunctionType(const QString& name) const;
const TypeSystemTypeEntry *findTypeSystemType(const QString &name) const;
diff --git a/sources/shiboken2/ApiExtractor/typedatabase_typedefs.h b/sources/shiboken2/ApiExtractor/typedatabase_typedefs.h
index fbbbabe43..f9591609e 100644
--- a/sources/shiboken2/ApiExtractor/typedatabase_typedefs.h
+++ b/sources/shiboken2/ApiExtractor/typedatabase_typedefs.h
@@ -34,6 +34,7 @@
#include <QtCore/QVector>
class ContainerTypeEntry;
+class NamespaceTypeEntry;
class PrimitiveTypeEntry;
class TemplateEntry;
class TypeEntry;
@@ -61,6 +62,7 @@ typedef QMap<QString, TypeEntry *> TypeEntryMap;
typedef QMap<QString, TypedefEntry *> TypedefEntryMap;
typedef QVector<const ContainerTypeEntry *> ContainerTypeEntryList;
+using NamespaceTypeEntryList = QVector<NamespaceTypeEntry *>;
typedef QVector<const PrimitiveTypeEntry *> PrimitiveTypeEntryList;
#endif // TYPEDATABASE_TYPEDEFS_H
diff --git a/sources/shiboken2/ApiExtractor/typesystem.cpp b/sources/shiboken2/ApiExtractor/typesystem.cpp
index 318a52e2e..434134be9 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.cpp
+++ b/sources/shiboken2/ApiExtractor/typesystem.cpp
@@ -126,8 +126,7 @@ static bool setRejectionRegularExpression(const QString &patternIn,
pattern = QLatin1Char('^') + QRegularExpression::escape(patternIn) + QLatin1Char('$');
re->setPattern(pattern);
if (!re->isValid()) {
- *errorMessage = QLatin1String("Invalid pattern \"") + patternIn
- + QLatin1String("\": ") + re->errorString();
+ *errorMessage = msgInvalidRegularExpression(patternIn, re->errorString());
return false;
}
return true;
@@ -1286,6 +1285,47 @@ ObjectTypeEntry *
return otype;
}
+NamespaceTypeEntry *
+ Handler::parseNamespaceTypeEntry(const QXmlStreamReader &reader,
+ const QString &name, const QVersionNumber &since,
+ QXmlStreamAttributes *attributes)
+{
+ QScopedPointer<NamespaceTypeEntry> result(new NamespaceTypeEntry(name, since));
+ applyCommonAttributes(result.data(), attributes);
+ applyComplexTypeAttributes(reader, result.data(), attributes);
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const QStringRef attributeName = attributes->at(i).qualifiedName();
+ if (attributeName == QLatin1String("files")) {
+ const QString pattern = attributes->takeAt(i).value().toString();
+ QRegularExpression re(pattern);
+ if (!re.isValid()) {
+ m_error = msgInvalidRegularExpression(pattern, re.errorString());
+ return nullptr;
+ }
+ result->setFilePattern(re);
+ } else if (attributeName == QLatin1String("extends")) {
+ const auto extendsPackageName = attributes->takeAt(i).value();
+ auto allEntries = TypeDatabase::instance()->findNamespaceTypes(name);
+ auto extendsIt = std::find_if(allEntries.cbegin(), allEntries.cend(),
+ [extendsPackageName] (const NamespaceTypeEntry *e) {
+ return e->targetLangPackage() == extendsPackageName;
+ });
+ if (extendsIt == allEntries.cend()) {
+ m_error = msgCannotFindNamespaceToExtend(name, extendsPackageName);
+ return nullptr;
+ }
+ result->setExtends(*extendsIt);
+ }
+ }
+
+ if (result->extends() && !result->hasPattern()) {
+ m_error = msgExtendingNamespaceRequiresPattern(name);
+ return nullptr;
+ }
+
+ return result.take();
+}
+
ValueTypeEntry *
Handler::parseValueTypeEntry(const QXmlStreamReader &,
const QString &name, const QVersionNumber &since,
@@ -2631,7 +2671,7 @@ bool Handler::startElement(const QXmlStreamReader &reader)
if (element->type != StackElement::PrimitiveTypeEntry
&& element->type != StackElement::FunctionTypeEntry) {
TypeEntry *tmp = m_database->findType(name);
- if (tmp)
+ if (tmp && !tmp->isNamespace())
qCWarning(lcShiboken).noquote().nospace()
<< QStringLiteral("Duplicate type entry: '%1'").arg(name);
}
@@ -2710,9 +2750,10 @@ bool Handler::startElement(const QXmlStreamReader &reader)
}
break;
case StackElement::NamespaceTypeEntry:
- element->entry = new NamespaceTypeEntry(name, since);
- applyCommonAttributes(element->entry, &attributes);
- applyComplexTypeAttributes(reader, static_cast<ComplexTypeEntry *>(element->entry), &attributes);
+ if (auto entry = parseNamespaceTypeEntry(reader, name, since, &attributes))
+ element->entry = entry;
+ else
+ return false;
break;
case StackElement::ObjectTypeEntry:
element->entry = new ObjectTypeEntry(name, since);
@@ -3799,8 +3840,21 @@ TypeEntry *NamespaceTypeEntry::clone() const
return new NamespaceTypeEntry(*this);
}
+void NamespaceTypeEntry::setFilePattern(const QRegularExpression &r)
+{
+ m_filePattern = r;
+ m_hasPattern = !m_filePattern.pattern().isEmpty();
+ if (m_hasPattern)
+ m_filePattern.optimize();
+}
+
NamespaceTypeEntry::NamespaceTypeEntry(const NamespaceTypeEntry &) = default;
+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)
{
diff --git a/sources/shiboken2/ApiExtractor/typesystem.h b/sources/shiboken2/ApiExtractor/typesystem.h
index f089bb6e0..2e4578a1d 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.h
+++ b/sources/shiboken2/ApiExtractor/typesystem.h
@@ -1531,10 +1531,28 @@ public:
TypeEntry *clone() const override;
+ const NamespaceTypeEntry *extends() const { return m_extends; }
+ void setExtends(const NamespaceTypeEntry *e) { m_extends = e; }
+
+ const QRegularExpression &filePattern() const { return m_filePattern; } // restrict files
+ void setFilePattern(const QRegularExpression &r);
+
+ bool hasPattern() const { return m_hasPattern; }
+
+ bool matchesFile(const QString &needle) const;
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
+
protected:
NamespaceTypeEntry(const NamespaceTypeEntry &);
-};
+private:
+ QRegularExpression m_filePattern;
+ const NamespaceTypeEntry *m_extends = nullptr;
+ bool m_hasPattern = false;
+};
class ValueTypeEntry : public ComplexTypeEntry
{
diff --git a/sources/shiboken2/ApiExtractor/typesystem_p.h b/sources/shiboken2/ApiExtractor/typesystem_p.h
index f6b0717f4..8a8fcb359 100644
--- a/sources/shiboken2/ApiExtractor/typesystem_p.h
+++ b/sources/shiboken2/ApiExtractor/typesystem_p.h
@@ -175,6 +175,12 @@ private:
parseFlagsEntry(const QXmlStreamReader &, EnumTypeEntry *enumEntry,
const QString &name, QString flagName,
const QVersionNumber &since, QXmlStreamAttributes *);
+
+ NamespaceTypeEntry *
+ parseNamespaceTypeEntry(const QXmlStreamReader &,
+ const QString &name, const QVersionNumber &since,
+ QXmlStreamAttributes *attributes);
+
ObjectTypeEntry *
parseInterfaceTypeEntry(const QXmlStreamReader &, const QString &name,
const QVersionNumber &since, QXmlStreamAttributes *);
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index 32b219fa2..5fbc6ed3e 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -4892,7 +4892,11 @@ void CppGenerator::writeFlagsUnaryOperator(QTextStream& s, const AbstractMetaEnu
QString CppGenerator::getSimpleClassInitFunctionName(const AbstractMetaClass *metaClass) const
{
- QString initFunctionName = metaClass->qualifiedCppName();
+ QString initFunctionName;
+ // Disambiguate namespaces per module to allow for extending them.
+ if (metaClass->isNamespace())
+ initFunctionName += moduleName();
+ initFunctionName += metaClass->qualifiedCppName();
initFunctionName.replace(QLatin1String("::"), QLatin1String("_"));
return initFunctionName;
}
@@ -4996,9 +5000,11 @@ void CppGenerator::writeClassRegister(QTextStream &s,
}
// 7:baseType
- if (metaClass->baseClass()) {
+ const auto base = metaClass->isNamespace()
+ ? metaClass->extendedNamespace() : metaClass->baseClass();
+ if (base) {
s << INDENT << "reinterpret_cast<SbkObjectType *>("
- << cpythonTypeNameExt(metaClass->baseClass()->typeEntry()) << ")," << endl;
+ << cpythonTypeNameExt(base->typeEntry()) << ")," << endl;
} else {
s << INDENT << "0," << endl;
}
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
index 44405c700..2b3b20c75 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
@@ -2667,8 +2667,14 @@ QString ShibokenGenerator::getTypeIndexVariableName(const TypeEntry* type)
if (trueType->basicReferencedTypeEntry())
type = trueType->basicReferencedTypeEntry();
}
- QString result = QLatin1String("SBK_")
- + _fixedCppTypeName(type->qualifiedCppName()).toUpper();
+ QString result = QLatin1String("SBK_");
+ // Disambiguate namespaces per module to allow for extending them.
+ if (type->isNamespace()) {
+ QString package = type->targetLangPackage();
+ const int dot = package.lastIndexOf(QLatin1Char('.'));
+ result += package.rightRef(package.size() - (dot + 1));
+ }
+ result += _fixedCppTypeName(type->qualifiedCppName()).toUpper();
appendIndexSuffix(&result);
return result;
}