aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sources/pyside2/cmake/Macros/PySideModules.cmake5
-rw-r--r--sources/pyside2/pyside_version.py4
-rw-r--r--sources/pyside2/tests/registry/init_platform.py4
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp281
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h3
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.cpp291
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.h73
-rw-r--r--sources/shiboken2/ApiExtractor/apiextractor.cpp18
-rw-r--r--sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp27
-rw-r--r--sources/shiboken2/ApiExtractor/clangparser/clangbuilder.h2
-rw-r--r--sources/shiboken2/ApiExtractor/graph.cpp2
-rw-r--r--sources/shiboken2/ApiExtractor/include.cpp2
-rw-r--r--sources/shiboken2/ApiExtractor/messages.cpp40
-rw-r--r--sources/shiboken2/ApiExtractor/messages.h7
-rw-r--r--sources/shiboken2/ApiExtractor/parser/codemodel.cpp10
-rw-r--r--sources/shiboken2/ApiExtractor/parser/codemodel.h4
-rw-r--r--sources/shiboken2/ApiExtractor/parser/codemodel_enums.h7
-rw-r--r--sources/shiboken2/ApiExtractor/reporthandler.cpp2
-rw-r--r--sources/shiboken2/ApiExtractor/typedatabase.cpp127
-rw-r--r--sources/shiboken2/ApiExtractor/typedatabase.h14
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.cpp91
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.h123
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem_enums.h7
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem_typedefs.h2
-rw-r--r--sources/shiboken2/ApiExtractor/typesystemparser.cpp177
-rw-r--r--sources/shiboken2/ApiExtractor/typesystemparser.h9
-rw-r--r--sources/shiboken2/doc/typesystem_specifying_types.rst64
-rw-r--r--sources/shiboken2/generator/generator.cpp66
-rw-r--r--sources/shiboken2/generator/main.cpp8
-rw-r--r--sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp106
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp416
-rw-r--r--sources/shiboken2/generator/shiboken2/headergenerator.cpp41
-rw-r--r--sources/shiboken2/generator/shiboken2/overloaddata.cpp2
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.cpp35
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.h2
-rw-r--r--sources/shiboken2/libshiboken/basewrapper.cpp15
-rw-r--r--sources/shiboken2/libshiboken/helper.cpp87
-rw-r--r--sources/shiboken2/libshiboken/helper.h20
-rw-r--r--sources/shiboken2/shiboken_version.py4
-rw-r--r--sources/shiboken2/tests/helper.py38
-rw-r--r--sources/shiboken2/tests/libother/CMakeLists.txt3
-rw-r--r--sources/shiboken2/tests/libother/otherobjecttype.cpp10
-rw-r--r--sources/shiboken2/tests/libother/otherobjecttype.h7
-rw-r--r--sources/shiboken2/tests/libother/smartptrtester.cpp55
-rw-r--r--sources/shiboken2/tests/libother/smartptrtester.h49
-rw-r--r--sources/shiboken2/tests/libsample/CMakeLists.txt1
-rw-r--r--sources/shiboken2/tests/libsample/renaming.cpp46
-rw-r--r--sources/shiboken2/tests/libsample/renaming.h50
-rw-r--r--sources/shiboken2/tests/libsample/samplenamespace.h9
-rw-r--r--sources/shiboken2/tests/libsmart/smart.cpp25
-rw-r--r--sources/shiboken2/tests/libsmart/smart_integer.h8
-rw-r--r--sources/shiboken2/tests/libsmart/smart_obj.h6
-rw-r--r--sources/shiboken2/tests/otherbinding/CMakeLists.txt9
-rw-r--r--sources/shiboken2/tests/otherbinding/global.h1
-rw-r--r--sources/shiboken2/tests/otherbinding/other-binding.txt.in2
-rw-r--r--sources/shiboken2/tests/otherbinding/signature_test.py54
-rw-r--r--sources/shiboken2/tests/otherbinding/smartptr_test.py61
-rw-r--r--sources/shiboken2/tests/otherbinding/typesystem_other.xml5
-rw-r--r--sources/shiboken2/tests/samplebinding/CMakeLists.txt3
-rw-r--r--sources/shiboken2/tests/samplebinding/global.h1
-rw-r--r--sources/shiboken2/tests/samplebinding/namespace_test.py19
-rw-r--r--sources/shiboken2/tests/samplebinding/renaming_test.py63
-rw-r--r--sources/shiboken2/tests/samplebinding/typesystem_sample.xml6
-rw-r--r--sources/shiboken2/tests/smartbinding/smart_pointer_test.py16
-rw-r--r--sources/shiboken2/tests/smartbinding/typesystem_smart.xml3
65 files changed, 1739 insertions, 1009 deletions
diff --git a/sources/pyside2/cmake/Macros/PySideModules.cmake b/sources/pyside2/cmake/Macros/PySideModules.cmake
index dca00ec11..14707f964 100644
--- a/sources/pyside2/cmake/Macros/PySideModules.cmake
+++ b/sources/pyside2/cmake/Macros/PySideModules.cmake
@@ -91,7 +91,10 @@ macro(create_pyside_module)
list(REMOVE_DUPLICATES total_type_system_files)
# Contains include directories to pass to shiboken's preprocessor.
- set(shiboken_include_dirs ${pyside2_SOURCE_DIR}${PATH_SEP}${QT_INCLUDE_DIR})
+ # Workaround: Added ${QT_INCLUDE_DIR}/QtCore until
+ # qtdeclarative/8d560d1bf0a747bf62f73fad6b6774095442d9d2 has reached qt5.git
+ string(REPLACE ";" ${PATH_SEP} core_includes "${Qt5Core_INCLUDE_DIRS}")
+ set(shiboken_include_dirs ${pyside2_SOURCE_DIR}${PATH_SEP}${QT_INCLUDE_DIR}${PATH_SEP}${core_includes})
set(shiboken_framework_include_dirs_option "")
if(CMAKE_HOST_APPLE)
set(shiboken_framework_include_dirs "${QT_FRAMEWORK_INCLUDE_DIR}")
diff --git a/sources/pyside2/pyside_version.py b/sources/pyside2/pyside_version.py
index 0e0943143..c022fc803 100644
--- a/sources/pyside2/pyside_version.py
+++ b/sources/pyside2/pyside_version.py
@@ -38,8 +38,8 @@
#############################################################################
major_version = "5"
-minor_version = "14"
-patch_version = "2"
+minor_version = "15"
+patch_version = "0"
# For example: "a", "b", "rc"
# (which means "alpha", "beta", "release candidate").
diff --git a/sources/pyside2/tests/registry/init_platform.py b/sources/pyside2/tests/registry/init_platform.py
index a690a3120..e80c3b69f 100644
--- a/sources/pyside2/tests/registry/init_platform.py
+++ b/sources/pyside2/tests/registry/init_platform.py
@@ -141,8 +141,8 @@ Shiboken.__name__ = "Shiboken"
sys.modules["Shiboken"] = sys.modules.pop("shiboken2")
all_modules.append("Shiboken")
-# 'sample' seems to be needed by 'other', so import it first.
-for modname in "minimal sample other smart".split():
+# 'sample/smart' are needed by 'other', so import them first.
+for modname in "minimal sample smart other".split():
sys.path.insert(0, os.path.join(shiboken_build_dir, "tests", modname + "binding"))
__import__(modname)
all_modules.append(modname)
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
index 4566ed3bc..f0e5da8da 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
@@ -270,7 +270,7 @@ void AbstractMetaBuilderPrivate::registerToStringCapability(const FunctionModelI
const ArgumentModelItem &arg = arguments.at(1);
if (AbstractMetaClass *cls = argumentToClass(arg, currentClass)) {
if (arg->type().indirections() < 2)
- cls->setToStringCapability(true, arg->type().indirections());
+ cls->setToStringCapability(true, int(arg->type().indirections()));
}
}
}
@@ -410,6 +410,7 @@ FileModelItem AbstractMetaBuilderPrivate::buildDom(QByteArrayList arguments,
unsigned clangFlags)
{
clang::Builder builder;
+ builder.setSystemIncludes(TypeDatabase::instance()->systemIncludes());
if (level == LanguageLevel::Default)
level = clang::emulatedCompilerLanguageLevel();
arguments.prepend(QByteArrayLiteral("-std=")
@@ -512,7 +513,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
ReportHandler::startProgress("Fixing class inheritance...");
for (AbstractMetaClass *cls : qAsConst(m_metaClasses)) {
- if (!cls->isInterface() && !cls->isNamespace()) {
+ if (!cls->isNamespace()) {
setupInheritance(cls);
if (!cls->hasVirtualDestructor() && cls->baseClass()
&& cls->baseClass()->hasVirtualDestructor())
@@ -530,7 +531,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
.arg(cls->name());
} else {
const bool couldAddDefaultCtors = cls->isConstructible()
- && !cls->isInterface() && !cls->isNamespace()
+ && !cls->isNamespace()
&& (cls->attributes() & AbstractMetaAttributes::HasRejectedConstructor) == 0;
if (couldAddDefaultCtors) {
if (!cls->hasConstructors())
@@ -549,11 +550,8 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
if (!entry->isPrimitive()) {
if ((entry->isValue() || entry->isObject())
&& !types->shouldDropTypeEntry(entry->qualifiedCppName())
- && !entry->isString()
- && !entry->isChar()
&& !entry->isContainer()
&& !entry->isCustom()
- && !entry->isVariant()
&& (entry->generateCode() & TypeEntry::GenerateTargetLang)
&& !AbstractMetaClass::findClass(m_metaClasses, entry)) {
qCWarning(lcShiboken).noquote().nospace()
@@ -729,12 +727,6 @@ void AbstractMetaBuilderPrivate::addAbstractMetaClass(AbstractMetaClass *cls,
m_smartPointers << cls;
} else {
m_metaClasses << cls;
- if (cls->typeEntry()->designatedInterface()) {
- AbstractMetaClass *interface = cls->extractInterface();
- m_metaClasses << interface;
- if (ReportHandler::isDebug(ReportHandler::SparseDebug))
- qCDebug(lcShiboken) << QStringLiteral(" -> interface '%1'").arg(interface->name());
- }
}
}
@@ -758,6 +750,11 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel
return nullptr;
}
+ if (namespaceItem->type() == NamespaceType::Inline) {
+ type->setInlineNamespace(true);
+ TypeDatabase::instance()->addInlineNamespaceLookups(type);
+ }
+
// Continue populating namespace?
AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_metaClasses, type);
if (!metaClass) {
@@ -1215,7 +1212,7 @@ AbstractMetaField *AbstractMetaBuilderPrivate::traverseField(const VariableModel
metaField->setType(metaType);
- AbstractMetaAttributes::Attributes attr = nullptr;
+ AbstractMetaAttributes::Attributes attr;
if (field->isStatic())
attr |= AbstractMetaAttributes::Static;
@@ -1284,46 +1281,11 @@ void AbstractMetaBuilderPrivate::fixReturnTypeOfConversionOperator(AbstractMetaF
metaFunction->replaceType(metaType);
}
-static bool _compareAbstractMetaTypes(const AbstractMetaType *type,
- const AbstractMetaType *other,
- AbstractMetaType::ComparisonFlags flags = {})
-{
- return (type != nullptr) == (other != nullptr)
- && (type == nullptr || type->compare(*other, flags));
-}
-
-static bool _compareAbstractMetaFunctions(const AbstractMetaFunction *func,
- const AbstractMetaFunction *other,
- AbstractMetaType::ComparisonFlags argumentFlags = {})
-{
- if (!func && !other)
- return true;
- if (!func || !other)
- return false;
- if (func->name() != other->name())
- return false;
- const int argumentsCount = func->arguments().count();
- if (argumentsCount != other->arguments().count()
- || func->isConstant() != other->isConstant()
- || func->isStatic() != other->isStatic()
- || !_compareAbstractMetaTypes(func->type(), other->type())) {
- return false;
- }
- for (int i = 0; i < argumentsCount; ++i) {
- if (!_compareAbstractMetaTypes(func->arguments().at(i)->type(),
- other->arguments().at(i)->type(),
- argumentFlags)) {
- return false;
- }
- }
- return true;
-}
-
AbstractMetaFunctionList AbstractMetaBuilderPrivate::classFunctionList(const ScopeModelItem &scopeItem,
AbstractMetaClass::Attributes *constructorAttributes,
AbstractMetaClass *currentClass)
{
- *constructorAttributes = nullptr;
+ *constructorAttributes = {};
AbstractMetaFunctionList result;
const FunctionList &scopeFunctionList = scopeItem->functions();
result.reserve(scopeFunctionList.size());
@@ -1464,8 +1426,6 @@ void AbstractMetaBuilderPrivate::applyFunctionModifications(AbstractMetaFunction
bool AbstractMetaBuilderPrivate::setupInheritance(AbstractMetaClass *metaClass)
{
- Q_ASSERT(!metaClass->isInterface());
-
if (m_setupInheritanceDone.contains(metaClass))
return true;
@@ -1505,61 +1465,23 @@ bool AbstractMetaBuilderPrivate::setupInheritance(AbstractMetaClass *metaClass)
TypeDatabase* types = TypeDatabase::instance();
- int primary = -1;
- int primaries = 0;
- for (int i = 0; i < baseClasses.size(); ++i) {
-
- if (types->isClassRejected(baseClasses.at(i)))
- continue;
-
- TypeEntry* baseClassEntry = types->findType(baseClasses.at(i));
- if (!baseClassEntry) {
- qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("class '%1' inherits from unknown base class '%2'")
- .arg(metaClass->name(), baseClasses.at(i));
- } else if (!baseClassEntry->designatedInterface()) { // true for primary base class
- primaries++;
- primary = i;
- }
- }
-
- if (primary >= 0) {
- AbstractMetaClass *baseClass = AbstractMetaClass::findClass(m_metaClasses, baseClasses.at(primary));
- if (!baseClass) {
- qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("unknown baseclass for '%1': '%2'")
- .arg(metaClass->name(), baseClasses.at(primary));
- return false;
- }
- metaClass->setBaseClass(baseClass);
- }
-
- for (int i = 0; i < baseClasses.size(); ++i) {
- if (types->isClassRejected(baseClasses.at(i)))
- continue;
-
- if (i != primary) {
- AbstractMetaClass *baseClass = AbstractMetaClass::findClass(m_metaClasses, baseClasses.at(i));
- if (!baseClass) {
+ for (const auto &baseClassName : baseClasses) {
+ if (!types->isClassRejected(baseClassName)) {
+ if (!types->findType(baseClassName)) {
qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("class not found for setup inheritance '%1'").arg(baseClasses.at(i));
+ << QStringLiteral("class '%1' inherits from unknown base class '%2'")
+ .arg(metaClass->name(), baseClassName);
return false;
}
-
- setupInheritance(baseClass);
-
- QString interfaceName = baseClass->isInterface() ? InterfaceTypeEntry::interfaceName(baseClass->name()) : baseClass->name();
- AbstractMetaClass *iface = AbstractMetaClass::findClass(m_metaClasses, interfaceName);
- if (!iface) {
+ auto baseClass = AbstractMetaClass::findClass(m_metaClasses, baseClassName);
+ if (!baseClass) {
qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("unknown interface for '%1': '%2'").arg(metaClass->name(), interfaceName);
+ << QStringLiteral("class not found for setup inheritance '%1'").arg(baseClassName);
return false;
}
- metaClass->addInterface(iface);
+ metaClass->addBaseClass(baseClass);
- const AbstractMetaClassList &interfaces = iface->interfaces();
- for (AbstractMetaClass* iface : interfaces)
- metaClass->addInterface(iface);
+ setupInheritance(baseClass);
}
}
@@ -2092,6 +2014,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const AddedFunction:
qFatal("%s", qPrintable(msg));
}
+ // These are only implicit and should not appear in code...
auto *metaType = new AbstractMetaType;
metaType->setTypeEntry(type);
metaType->setIndirections(typeInfo.indirections);
@@ -2120,6 +2043,52 @@ static const TypeEntry* findTypeEntryUsingContext(const AbstractMetaClass* metaC
return type;
}
+// Helper for translateTypeStatic()
+TypeEntries AbstractMetaBuilderPrivate::findTypeEntries(const QString &qualifiedName,
+ const QString &name,
+ AbstractMetaClass *currentClass,
+ AbstractMetaBuilderPrivate *d)
+{
+ // 5.1 - Try first using the current scope
+ if (currentClass) {
+ if (auto type = findTypeEntryUsingContext(currentClass, qualifiedName))
+ return {type};
+
+ // 5.1.1 - Try using the class parents' scopes
+ if (d && !currentClass->baseClassNames().isEmpty()) {
+ const AbstractMetaClassList &baseClasses = d->getBaseClasses(currentClass);
+ for (const AbstractMetaClass *cls : baseClasses) {
+ if (auto type = findTypeEntryUsingContext(cls, qualifiedName))
+ return {type};
+ }
+ }
+ }
+
+ // 5.2 - Try without scope
+ auto types = TypeDatabase::instance()->findCppTypes(qualifiedName);
+ if (!types.isEmpty())
+ return types;
+
+ // 6. No? Try looking it up as a flags type
+ if (auto type = TypeDatabase::instance()->findFlagsType(qualifiedName))
+ return {type};
+
+ // 7. No? Try looking it up as a container type
+ if (auto type = TypeDatabase::instance()->findContainerType(name))
+ return {type};
+
+ // 8. No? Check if the current class is a template and this type is one
+ // of the parameters.
+ if (currentClass) {
+ const QVector<TypeEntry *> &template_args = currentClass->templateArguments();
+ for (TypeEntry *te : template_args) {
+ if (te->name() == qualifiedName)
+ return {te};
+ }
+ }
+ return {};
+}
+
AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typei,
AbstractMetaClass *currentClass,
TranslateTypeFlags flags,
@@ -2252,47 +2221,8 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo
typeInfo.clearInstantiations();
}
- const TypeEntry *type = nullptr;
- // 5. Try to find the type
-
- // 5.1 - Try first using the current scope
- if (currentClass) {
- type = findTypeEntryUsingContext(currentClass, qualifiedName);
-
- // 5.1.1 - Try using the class parents' scopes
- if (!type && d && !currentClass->baseClassNames().isEmpty()) {
- const AbstractMetaClassList &baseClasses = d->getBaseClasses(currentClass);
- for (const AbstractMetaClass *cls : baseClasses) {
- type = findTypeEntryUsingContext(cls, qualifiedName);
- if (type)
- break;
- }
- }
- }
-
- // 5.2 - Try without scope
- if (!type)
- type = TypeDatabase::instance()->findType(qualifiedName);
-
- // 6. No? Try looking it up as a flags type
- if (!type)
- type = TypeDatabase::instance()->findFlagsType(qualifiedName);
-
- // 7. No? Try looking it up as a container type
- if (!type)
- type = TypeDatabase::instance()->findContainerType(name);
-
- // 8. No? Check if the current class is a template and this type is one
- // of the parameters.
- if (!type && currentClass) {
- const QVector<TypeEntry *> &template_args = currentClass->templateArguments();
- for (TypeEntry *te : template_args) {
- if (te->name() == qualifiedName)
- type = te;
- }
- }
-
- if (!type) {
+ const TypeEntries types = findTypeEntries(qualifiedName, name, currentClass, d);
+ if (types.isEmpty()) {
if (errorMessageIn) {
*errorMessageIn =
msgUnableToTranslateType(_typei, msgCannotFindTypeEntry(qualifiedName));
@@ -2300,11 +2230,10 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo
return nullptr;
}
- // These are only implicit and should not appear in code...
- Q_ASSERT(!type->isInterface());
+ const TypeEntry *type = types.constFirst();
+ const TypeEntry::Type typeEntryType = type->type();
- auto *metaType = new AbstractMetaType;
- metaType->setTypeEntry(type);
+ QScopedPointer<AbstractMetaType> metaType(new AbstractMetaType);
metaType->setIndirectionsV(typeInfo.indirectionsV());
metaType->setReferenceType(typeInfo.referenceType());
metaType->setConstant(typeInfo.isConstant());
@@ -2318,20 +2247,66 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo
if (!targType) {
if (errorMessageIn)
*errorMessageIn = msgCannotTranslateTemplateArgument(t, ti, errorMessage);
- delete metaType;
return nullptr;
}
metaType->addInstantiation(targType, true);
}
+ if (types.size() > 1) {
+ const bool sameType = std::all_of(types.cbegin() + 1, types.cend(),
+ [typeEntryType](const TypeEntry *e) {
+ return e->type() == typeEntryType; });
+ if (!sameType) {
+ if (errorMessageIn)
+ *errorMessageIn = msgAmbiguousVaryingTypesFound(qualifiedName, types);
+ return nullptr;
+ }
+ // Ambiguous primitive/smart pointer types are possible (when
+ // including type systems).
+ if (typeEntryType != TypeEntry::PrimitiveType
+ && typeEntryType != TypeEntry::SmartPointerType) {
+ if (errorMessageIn)
+ *errorMessageIn = msgAmbiguousTypesFound(qualifiedName, types);
+ return nullptr;
+ }
+ }
+
+ if (typeEntryType == TypeEntry::SmartPointerType) {
+ // Find a matching instantiation
+ if (metaType->instantiations().size() != 1) {
+ if (errorMessageIn)
+ *errorMessageIn = msgInvalidSmartPointerType(_typei);
+ return nullptr;
+ }
+ auto instantiationType = metaType->instantiations().constFirst()->typeEntry();
+ if (instantiationType->type() == TypeEntry::TemplateArgumentType) {
+ // Member functions of the template itself, SharedPtr(const SharedPtr &)
+ type = instantiationType;
+ } else {
+ auto it = std::find_if(types.cbegin(), types.cend(),
+ [instantiationType](const TypeEntry *e) {
+ auto smartPtr = static_cast<const SmartPointerTypeEntry *>(e);
+ return smartPtr->matchesInstantiation(instantiationType);
+ });
+ if (it == types.cend()) {
+ if (errorMessageIn)
+ *errorMessageIn = msgCannotFindSmartPointerInstantion(_typei);
+ return nullptr;
+ }
+ type =*it;
+ }
+ }
+
+ metaType->setTypeEntry(type);
+
// The usage pattern *must* be decided *after* the possible template
// instantiations have been determined, or else the absence of
// such instantiations will break the caching scheme of
// AbstractMetaType::cppSignature().
metaType->decideUsagePattern();
- return metaType;
+ return metaType.take();
}
AbstractMetaType *AbstractMetaBuilder::translateType(const TypeInfo &_typei,
@@ -2786,7 +2761,6 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass,
subclass->setTemplateBaseClass(templateClass);
subclass->setTemplateBaseClassInstantiations(templateTypes);
- subclass->setInterfaces(templateClass->interfaces());
subclass->setBaseClass(templateClass->baseClass());
return true;
@@ -2864,11 +2838,9 @@ void AbstractMetaBuilderPrivate::setupClonable(AbstractMetaClass *cls)
QQueue<AbstractMetaClass*> baseClasses;
if (cls->baseClass())
baseClasses.enqueue(cls->baseClass());
- baseClasses << cls->interfaces().toList();
while (!baseClasses.isEmpty()) {
AbstractMetaClass* currentClass = baseClasses.dequeue();
- baseClasses << currentClass->interfaces().toList();
if (currentClass->baseClass())
baseClasses.enqueue(currentClass->baseClass());
@@ -2913,7 +2885,7 @@ static void writeRejectLogFile(const QString &name,
for (int reason = 0; reason < AbstractMetaBuilder::NoReason; ++reason) {
- s << QString(72, QLatin1Char('*')) << endl;
+ s << QString(72, QLatin1Char('*')) << Qt::endl;
switch (reason) {
case AbstractMetaBuilder::NotInTypeSystem:
s << "Not in type system";
@@ -2946,16 +2918,16 @@ static void writeRejectLogFile(const QString &name,
break;
}
- s << endl;
+ s << Qt::endl;
for (QMap<QString, AbstractMetaBuilder::RejectReason>::const_iterator it = rejects.constBegin();
it != rejects.constEnd(); ++it) {
if (it.value() != reason)
continue;
- s << " - " << it.key() << endl;
+ s << " - " << it.key() << Qt::endl;
}
- s << QString(72, QLatin1Char('*')) << endl << endl;
+ s << QString(72, QLatin1Char('*')) << Qt::endl << Qt::endl;
}
}
@@ -3064,8 +3036,7 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const
} else {
for (int i : qAsConst(unmappedResult)) {
Q_ASSERT(reverseMap.contains(i));
- if (!reverseMap[i]->isInterface())
- result << reverseMap[i];
+ result << reverseMap[i];
}
}
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
index b381a62cd..e3c9e1a72 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
@@ -146,6 +146,9 @@ public:
AbstractMetaBuilderPrivate *d = nullptr,
TranslateTypeFlags flags = {},
QString *errorMessageIn = nullptr);
+ static TypeEntries findTypeEntries(const QString &qualifiedName, const QString &name,
+ AbstractMetaClass *currentClass = nullptr,
+ AbstractMetaBuilderPrivate *d = nullptr);
qint64 findOutValueFromString(const QString &stringValue, bool &ok);
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
index 5ae671d87..e6590e2dc 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
@@ -80,15 +80,10 @@ const AbstractMetaClass *recurseClassHierarchy(const AbstractMetaClass *klass,
{
if (pred(klass))
return klass;
- if (auto base = klass->baseClass()) {
+ for (auto base : klass->baseClasses()) {
if (auto r = recurseClassHierarchy(base, pred))
return r;
}
- const auto interfaces = klass->interfaces();
- for (auto i : interfaces) {
- if (auto r = recurseClassHierarchy(i, pred))
- return r;
- }
return nullptr;
}
@@ -268,7 +263,7 @@ QString AbstractMetaType::pythonSignature() const
// PYSIDE-921: Handle container returntypes correctly.
// This is now a clean reimplementation.
if (m_cachedPythonSignature.isEmpty())
- m_cachedPythonSignature = formatPythonSignature(false);
+ m_cachedPythonSignature = formatPythonSignature();
return m_cachedPythonSignature;
}
@@ -531,7 +526,7 @@ bool AbstractMetaFunction::operator<(const AbstractMetaFunction &other) const
*/
AbstractMetaFunction::CompareResult AbstractMetaFunction::compareTo(const AbstractMetaFunction *other) const
{
- CompareResult result = nullptr;
+ CompareResult result;
// Enclosing class...
if (ownerClass() == other->ownerClass())
@@ -948,9 +943,6 @@ FunctionModificationList AbstractMetaFunction::modifications(const AbstractMetaC
(implementor == implementingClass() && !mods.isEmpty())) {
break;
}
- const AbstractMetaClassList &interfaces = implementor->interfaces();
- for (const AbstractMetaClass *interface : interfaces)
- mods += this->modifications(interface);
implementor = implementor->baseClass();
}
return mods;
@@ -1365,44 +1357,6 @@ bool AbstractMetaClass::inheritsFrom(const AbstractMetaClass *cls) const
}
/*******************************************************************************
- * Constructs an interface based on the functions and enums in this
- * class and returns it...
- */
-AbstractMetaClass *AbstractMetaClass::extractInterface()
-{
- Q_ASSERT(typeEntry()->designatedInterface());
-
- if (!m_extractedInterface) {
- auto *iface = new AbstractMetaClass;
- iface->setAttributes(attributes());
- iface->setBaseClass(nullptr);
-
- iface->setTypeEntry(typeEntry()->designatedInterface());
-
- for (AbstractMetaFunction *function : qAsConst(m_functions)) {
- if (!function->isConstructor())
- iface->addFunction(function->copy());
- }
-
-// iface->setEnums(enums());
-// setEnums(AbstractMetaEnumList());
-
- for (const AbstractMetaField *field : qAsConst(m_fields)) {
- if (field->isPublic()) {
- AbstractMetaField *new_field = field->copy();
- new_field->setEnclosingClass(iface);
- iface->addField(new_field);
- }
- }
-
- m_extractedInterface = iface;
- addInterface(iface);
- }
-
- return m_extractedInterface;
-}
-
-/*******************************************************************************
* Returns a list of all the functions with a given name
*/
AbstractMetaFunctionList AbstractMetaClass::queryFunctionsByName(const QString &name) const
@@ -1424,10 +1378,6 @@ AbstractMetaFunctionList AbstractMetaClass::functionsInTargetLang() const
{
FunctionQueryOptions default_flags = NormalFunctions | Visible | NotRemovedFromTargetLang;
- // Interfaces don't implement functions
- if (isInterface())
- default_flags |= ClassImplements;
-
// Only public functions in final classes
// default_flags |= isFinal() ? WasPublic : 0;
FunctionQueryOptions public_flags;
@@ -1604,11 +1554,19 @@ QString AbstractMetaClass::name() const
return m_typeEntry->targetLangEntryName();
}
+void AbstractMetaClass::addBaseClass(AbstractMetaClass *baseClass)
+{
+ Q_ASSERT(baseClass);
+ m_baseClasses.append(baseClass);
+ m_isPolymorphic |= baseClass->isPolymorphic();
+}
+
void AbstractMetaClass::setBaseClass(AbstractMetaClass *baseClass)
{
- m_baseClass = baseClass;
- if (baseClass)
+ if (baseClass) {
+ m_baseClasses.prepend(baseClass);
m_isPolymorphic |= baseClass->isPolymorphic();
+ }
}
QString AbstractMetaClass::package() const
@@ -1616,11 +1574,6 @@ QString AbstractMetaClass::package() const
return m_typeEntry->targetLangPackage();
}
-bool AbstractMetaClass::isInterface() const
-{
- return m_typeEntry->isInterface();
-}
-
bool AbstractMetaClass::isNamespace() const
{
return m_typeEntry->isNamespace();
@@ -1729,7 +1682,7 @@ void AbstractMetaClass::setTemplateBaseClassInstantiations(AbstractMetaTypeList
bool AbstractMetaClass::deleteInMainThread() const
{
return typeEntry()->deleteInMainThread()
- || (m_baseClass && m_baseClass->deleteInMainThread());
+ || (!m_baseClasses.isEmpty() && m_baseClasses.constFirst()->deleteInMainThread());
}
static bool functions_contains(const AbstractMetaFunctionList &l, const AbstractMetaFunction *func)
@@ -1858,6 +1811,14 @@ const AbstractMetaFunction *AbstractMetaField::setter() const
return m_setter;
}
+const AbstractMetaClass *EnclosingClassMixin::targetLangEnclosingClass() const
+{
+ auto result = m_enclosingClass;
+ while (result && !NamespaceTypeEntry::isVisibleScope(result->typeEntry()))
+ result = result->enclosingClass();
+ return result;
+}
+
const AbstractMetaFunction *AbstractMetaField::getter() const
{
if (!m_getter) {
@@ -2139,57 +2100,6 @@ AbstractMetaFunctionList AbstractMetaClass::cppSignalFunctions() const
return queryFunctions(Signals | Visible | NotRemovedFromTargetLang);
}
-/**
- * Adds the specified interface to this class by adding all the
- * functions in the interface to this class.
- */
-void AbstractMetaClass::addInterface(AbstractMetaClass *interface)
-{
- Q_ASSERT(!m_interfaces.contains(interface));
- m_interfaces << interface;
-
- m_isPolymorphic |= interface->isPolymorphic();
-
- if (m_extractedInterface && m_extractedInterface != interface)
- m_extractedInterface->addInterface(interface);
-
-
-#if 0
- const AbstractMetaFunctionList &funcs = interface->functions();
- for (AbstractMetaFunction *function : funcs)
- if (!hasFunction(function) && !function->isConstructor()) {
- AbstractMetaFunction *cpy = function->copy();
- cpy->setImplementingClass(this);
-
- // Setup that this function is an interface class.
- cpy->setInterfaceClass(interface);
- *cpy += AbstractMetaAttributes::InterfaceFunction;
-
- // Copy the modifications in interface into the implementing classes.
- const FunctionModificationList &mods = function->modifications(interface);
- for (const FunctionModification &mod : mods)
- m_typeEntry->addFunctionModification(mod);
-
- // It should be mostly safe to assume that when we implement an interface
- // we don't "pass on" pure virtual functions to our sublcasses...
-// *cpy -= AbstractMetaAttributes::Abstract;
-
- addFunction(cpy);
- }
-#endif
-
-}
-
-
-void AbstractMetaClass::setInterfaces(const AbstractMetaClassList &interfaces)
-{
- m_interfaces = interfaces;
- for (const AbstractMetaClass *interface : interfaces) {
- if (interface)
- m_isPolymorphic |= interface->isPolymorphic();
- }
-}
-
AbstractMetaField *AbstractMetaClass::findField(const QString &name) const
{
return AbstractMetaField::find(m_fields, name);
@@ -2199,10 +2109,6 @@ AbstractMetaEnum *AbstractMetaClass::findEnum(const QString &enumName)
{
if (AbstractMetaEnum *e = findByName(m_enums, enumName))
return e;
-
- if (typeEntry()->designatedInterface())
- return extractInterface()->findEnum(enumName);
-
return nullptr;
}
@@ -2215,10 +2121,6 @@ AbstractMetaEnumValue *AbstractMetaClass::findEnumValue(const QString &enumValue
if (AbstractMetaEnumValue *v = e->findEnumValue(enumValueName))
return v;
}
-
- if (typeEntry()->designatedInterface())
- return extractInterface()->findEnumValue(enumValueName);
-
if (baseClass())
return baseClass()->findEnumValue(enumValueName);
@@ -2265,32 +2167,23 @@ void AbstractMetaClass::fixFunctions()
m_functionsFixed = true;
- AbstractMetaClass *superClass = baseClass();
AbstractMetaFunctionList funcs = functions();
- if (superClass)
+ for (auto superClass : m_baseClasses) {
superClass->fixFunctions();
- int iface_idx = 0;
- while (superClass || iface_idx < interfaces().size()) {
// Since we always traverse the complete hierarchy we are only
// interrested in what each super class implements, not what
// we may have propagated from their base classes again.
AbstractMetaFunctionList superFuncs;
- if (superClass) {
- // Super classes can never be final
- if (superClass->isFinalInTargetLang()) {
- qCWarning(lcShiboken).noquote().nospace()
- << "Final class '" << superClass->name() << "' set to non-final, as it is extended by other classes";
- *superClass -= AbstractMetaAttributes::FinalInTargetLang;
- }
- superFuncs = superClass->queryFunctions(AbstractMetaClass::ClassImplements);
- AbstractMetaFunctionList virtuals = superClass->queryFunctions(AbstractMetaClass::VirtualInCppFunctions);
- superFuncs += virtuals;
- } else {
- superFuncs = interfaces().at(iface_idx)->queryFunctions(AbstractMetaClass::NormalFunctions);
- AbstractMetaFunctionList virtuals = interfaces().at(iface_idx)->queryFunctions(AbstractMetaClass::VirtualInCppFunctions);
- superFuncs += virtuals;
+ // Super classes can never be final
+ if (superClass->isFinalInTargetLang()) {
+ qCWarning(lcShiboken).noquote().nospace()
+ << "Final class '" << superClass->name() << "' set to non-final, as it is extended by other classes";
+ *superClass -= AbstractMetaAttributes::FinalInTargetLang;
}
+ superFuncs = superClass->queryFunctions(AbstractMetaClass::ClassImplements);
+ AbstractMetaFunctionList virtuals = superClass->queryFunctions(AbstractMetaClass::VirtualInCppFunctions);
+ superFuncs += virtuals;
QSet<AbstractMetaFunction *> funcsToAdd;
for (auto sf : qAsConst(superFuncs)) {
@@ -2419,11 +2312,6 @@ void AbstractMetaClass::fixFunctions()
(*copy) += AddedMethod;
funcs.append(copy);
}
-
- if (superClass)
- superClass = superClass->baseClass();
- else
- iface_idx++;
}
bool hasPrivateConstructors = false;
@@ -2522,7 +2410,7 @@ QString AbstractMetaType::formatSignature(bool minimal) const
return result;
}
-QString AbstractMetaType::formatPythonSignature(bool minimal) const
+QString AbstractMetaType::formatPythonSignature() const
{
/*
* This is a version of the above, more suitable for Python.
@@ -2545,7 +2433,7 @@ QString AbstractMetaType::formatPythonSignature(bool minimal) const
result += package() + QLatin1Char('.');
if (isArray()) {
// Build nested array dimensions a[2][3] in correct order
- result += m_arrayElementType->formatPythonSignature(true);
+ result += m_arrayElementType->formatPythonSignature();
const int arrayPos = result.indexOf(QLatin1Char('['));
if (arrayPos != -1)
result.insert(arrayPos, formatArraySize(m_arrayElementCount));
@@ -2559,7 +2447,7 @@ QString AbstractMetaType::formatPythonSignature(bool minimal) const
for (int i = 0, size = m_instantiations.size(); i < size; ++i) {
if (i > 0)
result += QLatin1String(", ");
- result += m_instantiations.at(i)->formatPythonSignature(true);
+ result += m_instantiations.at(i)->formatPythonSignature();
}
result += QLatin1Char(']');
}
@@ -2676,6 +2564,63 @@ AbstractMetaClass *AbstractMetaClass::findClass(const AbstractMetaClassList &cla
}
#ifndef QT_NO_DEBUG_STREAM
+
+void AbstractMetaClass::format(QDebug &d) const
+{
+ if (d.verbosity() > 2)
+ d << static_cast<const void *>(this) << ", ";
+ d << '"' << qualifiedCppName();
+ if (const int count = m_templateArgs.size()) {
+ for (int i = 0; i < count; ++i)
+ d << (i ? ',' : '<') << m_templateArgs.at(i)->qualifiedCppName();
+ d << '>';
+ }
+ d << '"';
+ if (isNamespace())
+ d << " [namespace]";
+ if (attributes() & AbstractMetaAttributes::FinalCppClass)
+ d << " [final]";
+ if (attributes().testFlag(AbstractMetaAttributes::Deprecated))
+ d << " [deprecated]";
+ if (!m_baseClasses.isEmpty()) {
+ d << ", inherits ";
+ for (auto b : m_baseClasses)
+ d << " \"" << b->name() << '"';
+ }
+ if (auto templateBase = templateBaseClass()) {
+ const auto instantiatedTypes = templateBaseClassInstantiations();
+ d << ", instantiates \"" << templateBase->name();
+ for (int i = 0, count = instantiatedTypes.size(); i < count; ++i)
+ d << (i ? ',' : '<') << instantiatedTypes.at(i)->name();
+ d << ">\"";
+ }
+}
+
+void AbstractMetaClass::formatMembers(QDebug &d) const
+{
+ if (!m_enums.isEmpty())
+ d << ", enums[" << m_enums.size() << "]=" << m_enums;
+ if (!m_functions.isEmpty()) {
+ const int count = m_functions.size();
+ d << ", functions=[" << count << "](";
+ for (int i = 0; i < count; ++i) {
+ if (i)
+ d << ", ";
+ formatMetaFunctionBrief(d, m_functions.at(i));
+ }
+ d << ')';
+ }
+ if (const int count = m_fields.size()) {
+ d << ", fields=[" << count << "](";
+ for (int i = 0; i < count; ++i) {
+ if (i)
+ d << ", ";
+ formatMetaField(d, m_fields.at(i));
+ }
+ d << ')';
+ }
+}
+
QDebug operator<<(QDebug d, const AbstractMetaClass *ac)
{
QDebugStateSaver saver(d);
@@ -2683,57 +2628,9 @@ QDebug operator<<(QDebug d, const AbstractMetaClass *ac)
d.nospace();
d << "AbstractMetaClass(";
if (ac) {
- d << '"' << ac->fullName() << '"';
- if (ac->attributes() & AbstractMetaAttributes::FinalCppClass)
- d << " [final]";
- if (ac->attributes().testFlag(AbstractMetaAttributes::Deprecated))
- d << " [deprecated]";
- if (ac->m_baseClass)
- d << ", inherits \"" << ac->m_baseClass->name() << '"';
- if (ac->m_templateBaseClass)
- d << ", inherits template \"" << ac->m_templateBaseClass->name() << '"';
- const AbstractMetaEnumList &enums = ac->enums();
- if (!enums.isEmpty())
- d << ", enums[" << enums.size() << "]=" << enums;
- const AbstractMetaFunctionList &functions = ac->functions();
- if (!functions.isEmpty()) {
- const int count = functions.size();
- d << ", functions=[" << count << "](";
- for (int i = 0; i < count; ++i) {
- if (i)
- d << ", ";
-#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
- if (d.verbosity() > 2)
- d << functions.at(i);
- else
-#endif
- formatMetaFunctionBrief(d, functions.at(i));
- }
- d << ')';
- }
- const AbstractMetaFieldList &fields = ac->fields();
- if (!fields.isEmpty()) {
- const int count = fields.size();
- d << ", fields=[" << count << "](";
- for (int i = 0; i < count; ++i) {
- if (i)
- d << ", ";
- formatMetaField(d, fields.at(i));
- }
- d << ')';
- }
- const auto &templateArguments = ac->templateArguments();
- if (const int count = templateArguments.size()) {
- d << ", templateArguments=[" << count << "](";
- for (int i = 0; i < count; ++i) {
- if (i)
- d << ", ";
- d << templateArguments.at(i);
- }
- d << ')';
- }
-
-
+ ac->format(d);
+ if (d.verbosity() > 2)
+ ac->formatMembers(d);
} else {
d << '0';
}
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h
index 2ae1b6d21..3e17a713b 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h
@@ -538,7 +538,7 @@ public:
private:
TypeUsagePattern determineUsagePattern() const;
QString formatSignature(bool minimal) const;
- QString formatPythonSignature(bool minimal) const;
+ QString formatPythonSignature() const;
const TypeEntry *m_typeEntry = nullptr;
AbstractMetaTypeList m_instantiations;
@@ -704,25 +704,26 @@ private:
friend class AbstractMetaClass;
};
+class EnclosingClassMixin {
+public:
+ const AbstractMetaClass *enclosingClass() const { return m_enclosingClass; }
+ void setEnclosingClass(const AbstractMetaClass *cls) { m_enclosingClass = cls; }
+ const AbstractMetaClass *targetLangEnclosingClass() const;
+
+private:
+ const AbstractMetaClass *m_enclosingClass = nullptr;
+};
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug d, const AbstractMetaArgument *aa);
#endif
-class AbstractMetaField : public AbstractMetaVariable, public AbstractMetaAttributes
+class AbstractMetaField : public AbstractMetaVariable, public AbstractMetaAttributes, public EnclosingClassMixin
{
public:
AbstractMetaField();
~AbstractMetaField();
- const AbstractMetaClass *enclosingClass() const
- {
- return m_class;
- }
- void setEnclosingClass(const AbstractMetaClass *cls)
- {
- m_class = cls;
- }
-
const AbstractMetaFunction *getter() const;
const AbstractMetaFunction *setter() const;
@@ -741,7 +742,6 @@ public:
private:
mutable AbstractMetaFunction *m_getter = nullptr;
mutable AbstractMetaFunction *m_setter = nullptr;
- const AbstractMetaClass *m_class = nullptr;
};
#ifndef QT_NO_DEBUG_STREAM
@@ -1179,7 +1179,7 @@ private:
Documentation m_doc;
};
-class AbstractMetaEnum : public AbstractMetaAttributes
+class AbstractMetaEnum : public AbstractMetaAttributes, public EnclosingClassMixin
{
public:
AbstractMetaEnum();
@@ -1234,23 +1234,12 @@ public:
m_typeEntry = entry;
}
- AbstractMetaClass *enclosingClass() const
- {
- return m_class;
- }
-
- void setEnclosingClass(AbstractMetaClass *c)
- {
- m_class = c;
- }
-
bool isSigned() const { return m_signed; }
void setSigned(bool s) { m_signed = s; }
private:
AbstractMetaEnumValueList m_enumValues;
EnumTypeEntry *m_typeEntry = nullptr;
- AbstractMetaClass *m_class = nullptr;
EnumKind m_enumKind = CEnum;
uint m_hasQenumsDeclaration : 1;
@@ -1261,7 +1250,7 @@ private:
QDebug operator<<(QDebug d, const AbstractMetaEnum *ae);
#endif
-class AbstractMetaClass : public AbstractMetaAttributes
+class AbstractMetaClass : public AbstractMetaAttributes, public EnclosingClassMixin
{
Q_GADGET
public:
@@ -1306,7 +1295,6 @@ public:
AbstractMetaClass();
~AbstractMetaClass();
- AbstractMetaClass *extractInterface();
void fixFunctions();
AbstractMetaFunctionList functions() const
@@ -1447,13 +1435,6 @@ public:
AbstractMetaEnum *findEnum(const QString &enumName);
AbstractMetaEnumValue *findEnumValue(const QString &enumName);
- AbstractMetaClassList interfaces() const
- {
- return m_interfaces;
- }
- void addInterface(AbstractMetaClass *interface);
- void setInterfaces(const AbstractMetaClassList &interface);
-
QString fullName() const
{
return package() + QLatin1Char('.') + name();
@@ -1467,32 +1448,24 @@ public:
QString baseClassName() const
{
- return m_baseClass ? m_baseClass->name() : QString();
+ return m_baseClasses.isEmpty() ? QString() : m_baseClasses.constFirst()->name();
}
AbstractMetaClass *baseClass() const
{
- return m_baseClass;
+ return m_baseClasses.value(0, nullptr);
}
+ const AbstractMetaClassList &baseClasses() const { return m_baseClasses; }
+ void addBaseClass(AbstractMetaClass *base_class);
void setBaseClass(AbstractMetaClass *base_class);
- const AbstractMetaClass *enclosingClass() const
- {
- 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;
- }
-
const AbstractMetaClassList& innerClasses() const
{
return m_innerClasses;
@@ -1510,8 +1483,6 @@ public:
QString package() const;
- bool isInterface() const;
-
bool isNamespace() const;
bool isQObject() const;
@@ -1712,6 +1683,8 @@ public:
private:
#ifndef QT_NO_DEBUG_STREAM
+ void format(QDebug &d) const;
+ void formatMembers(QDebug &d) const;
friend QDebug operator<<(QDebug d, const AbstractMetaClass *ac);
#endif
uint m_hasVirtuals : 1;
@@ -1730,21 +1703,19 @@ private:
uint m_hasToStringCapability : 1;
const AbstractMetaClass *m_enclosingClass = nullptr;
- AbstractMetaClass *m_baseClass = nullptr;
+ AbstractMetaClassList m_baseClasses; // Real base classes after setting up inheritance
AbstractMetaClass *m_extendedNamespace = nullptr;
const AbstractMetaClass *m_templateBaseClass = nullptr;
AbstractMetaFunctionList m_functions;
AbstractMetaFieldList m_fields;
AbstractMetaEnumList m_enums;
- AbstractMetaClassList m_interfaces;
- AbstractMetaClass *m_extractedInterface = nullptr;
QVector<QPropertySpec *> m_propertySpecs;
AbstractMetaClassList m_innerClasses;
AbstractMetaFunctionList m_externalConversionOperators;
- QStringList m_baseClassNames;
+ QStringList m_baseClassNames; // Base class names from C++, including rejected
QVector<TypeEntry *> m_templateArgs;
ComplexTypeEntry *m_typeEntry = nullptr;
// FunctionModelItem m_qDebugStreamFunction;
diff --git a/sources/shiboken2/ApiExtractor/apiextractor.cpp b/sources/shiboken2/ApiExtractor/apiextractor.cpp
index 78fa9e313..6d29ed1e0 100644
--- a/sources/shiboken2/ApiExtractor/apiextractor.cpp
+++ b/sources/shiboken2/ApiExtractor/apiextractor.cpp
@@ -166,24 +166,6 @@ ContainerTypeEntryList ApiExtractor::containerTypes() const
return TypeDatabase::instance()->containerTypes();
}
-static const AbstractMetaEnum* findEnumOnClasses(AbstractMetaClassList metaClasses, const EnumTypeEntry* typeEntry)
-{
- const AbstractMetaEnum *result = nullptr;
- for (const AbstractMetaClass* metaClass : qAsConst(metaClasses)) {
- const AbstractMetaEnumList &enums = metaClass->enums();
- for (const AbstractMetaEnum *metaEnum : enums) {
- if (metaEnum->typeEntry() == typeEntry) {
- result = metaEnum;
- break;
- }
- }
- if (result)
- break;
- result = findEnumOnClasses(metaClass->innerClasses(), typeEntry);
- }
- return result;
-}
-
const AbstractMetaEnum* ApiExtractor::findAbstractMetaEnum(const TypeEntry* typeEntry) const
{
return m_builder->findEnum(typeEntry);
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
index d52e4672b..7c188535f 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
@@ -222,6 +222,7 @@ public:
FunctionModelItem m_currentFunction;
ArgumentModelItem m_currentArgument;
VariableModelItem m_currentField;
+ QByteArrayList m_systemIncludes;
int m_anonymousEnumCount = 0;
CodeModel::FunctionType m_currentFunctionType = CodeModel::Normal;
@@ -721,6 +722,12 @@ bool BuilderPrivate::visitHeader(const char *cFileName) const
return true;
}
#endif // Q_OS_MACOS
+ if (baseName) {
+ for (const auto &systemInclude : m_systemIncludes) {
+ if (systemInclude == baseName)
+ return true;
+ }
+ }
return false;
}
@@ -743,6 +750,11 @@ bool Builder::visitLocation(const CXSourceLocation &location) const
return result;
}
+void Builder::setSystemIncludes(const QByteArrayList &systemIncludes)
+{
+ d->m_systemIncludes = systemIncludes;
+}
+
FileModelItem Builder::dom() const
{
Q_ASSERT(!d->m_scopeStack.isEmpty());
@@ -766,6 +778,17 @@ static CodeModel::ClassType codeModelClassTypeFromCursor(CXCursorKind kind)
return result;
}
+static NamespaceType namespaceType(const CXCursor &cursor)
+{
+ if (clang_Cursor_isAnonymous(cursor))
+ return NamespaceType::Anonymous;
+#if CINDEX_VERSION_MAJOR > 0 || CINDEX_VERSION_MINOR >= 59
+ if (clang_Cursor_isInlineNamespace(cursor))
+ return NamespaceType::Inline;
+#endif
+ return NamespaceType::Default;
+}
+
static QString enumType(const CXCursor &cursor)
{
QString name = getCursorSpelling(cursor); // "enum Foo { v1, v2 };"
@@ -904,6 +927,9 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
d->m_scopeStack.back()->addFunction(d->m_currentFunction);
break;
case CXCursor_Namespace: {
+ const auto type = namespaceType(cursor);
+ if (type == NamespaceType::Anonymous)
+ return Skip;
const QString name = getCursorSpelling(cursor);
const NamespaceModelItem parentNamespaceItem = qSharedPointerDynamicCast<_NamespaceModelItem>(d->m_scopeStack.back());
if (parentNamespaceItem.isNull()) {
@@ -920,6 +946,7 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
namespaceItem.reset(new _NamespaceModelItem(d->m_model, name));
setFileName(cursor, namespaceItem.data());
namespaceItem->setScope(d->m_scope);
+ namespaceItem->setType(type);
parentNamespaceItem->addNamespace(namespaceItem);
d->pushScope(namespaceItem);
}
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.h b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.h
index fa79acb2a..dc37dff0f 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.h
+++ b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.h
@@ -44,6 +44,8 @@ public:
Builder();
~Builder();
+ void setSystemIncludes(const QByteArrayList &systemIncludes);
+
bool visitLocation(const CXSourceLocation &location) const override;
StartTokenResult startToken(const CXCursor &cursor) override;
diff --git a/sources/shiboken2/ApiExtractor/graph.cpp b/sources/shiboken2/ApiExtractor/graph.cpp
index 95a80197e..53e20ebba 100644
--- a/sources/shiboken2/ApiExtractor/graph.cpp
+++ b/sources/shiboken2/ApiExtractor/graph.cpp
@@ -101,7 +101,7 @@ bool Graph::containsEdge(int from, int to)
void Graph::addEdge(int from, int to)
{
- Q_ASSERT(to < (int)m_d->edges.size());
+ Q_ASSERT(to < m_d->edges.size());
m_d->edges[from].insert(to);
}
diff --git a/sources/shiboken2/ApiExtractor/include.cpp b/sources/shiboken2/ApiExtractor/include.cpp
index d6a451992..82cb1d95b 100644
--- a/sources/shiboken2/ApiExtractor/include.cpp
+++ b/sources/shiboken2/ApiExtractor/include.cpp
@@ -49,7 +49,7 @@ uint qHash(const Include& inc)
QTextStream& operator<<(QTextStream& out, const Include& include)
{
if (include.isValid())
- out << include.toString() << endl;
+ out << include.toString() << Qt::endl;
return out;
}
diff --git a/sources/shiboken2/ApiExtractor/messages.cpp b/sources/shiboken2/ApiExtractor/messages.cpp
index 546e9c4ed..0c29249d3 100644
--- a/sources/shiboken2/ApiExtractor/messages.cpp
+++ b/sources/shiboken2/ApiExtractor/messages.cpp
@@ -28,6 +28,7 @@
#include "messages.h"
#include "abstractmetalang.h"
+#include "typedatabase.h"
#include "typesystem.h"
#include <codemodel.h>
@@ -130,6 +131,22 @@ QString msgNoEnumTypeConflict(const EnumModelItem &enumItem,
return result;
}
+QString msgAmbiguousVaryingTypesFound(const QString &qualifiedName, const TypeEntries &te)
+{
+ QString result = QLatin1String("Ambiguous types of varying types found for \"") + qualifiedName
+ + QLatin1String("\": ");
+ QDebug(&result) << te;
+ return result;
+}
+
+QString msgAmbiguousTypesFound(const QString &qualifiedName, const TypeEntries &te)
+{
+ QString result = QLatin1String("Ambiguous types found for \"") + qualifiedName
+ + QLatin1String("\": ");
+ QDebug(&result) << te;
+ return result;
+}
+
QString msgUnmatchedParameterType(const ArgumentModelItem &arg, int n,
const QString &why)
{
@@ -196,6 +213,23 @@ QString msgCannotFindTypeEntry(const QString &t)
return QLatin1String("Cannot find type entry for \"") + t + QLatin1String("\".");
}
+QString msgCannotFindTypeEntryForSmartPointer(const QString &t, const QString &smartPointerType)
+{
+ return QLatin1String("Cannot find type entry \"") + t
+ + QLatin1String("\" for instantiation of \"") + smartPointerType + QLatin1String("\".");
+}
+
+QString msgInvalidSmartPointerType(const TypeInfo &i)
+{
+ return QLatin1String("Invalid smart pointer type \"") + i.toString() + QLatin1String("\".");
+}
+
+QString msgCannotFindSmartPointerInstantion(const TypeInfo &i)
+{
+ return QLatin1String("Cannot find instantiation of smart pointer type for \"")
+ + i.toString() + QLatin1String("\".");
+}
+
QString msgCannotTranslateTemplateArgument(int i,
const TypeInfo &typeInfo,
const QString &why)
@@ -334,8 +368,10 @@ QString msgCannotFindSmartPointer(const QString &instantiationType,
QString result;
QTextStream str(&result);
str << "Unable to find smart pointer type for " << instantiationType << " (known types:";
- for (auto t : pointers)
- str << ' ' << t->fullName();
+ for (auto t : pointers) {
+ auto typeEntry = t->typeEntry();
+ str << ' ' << typeEntry->targetLangName() << '/' << typeEntry->qualifiedCppName();
+ }
str << ").";
return result;
}
diff --git a/sources/shiboken2/ApiExtractor/messages.h b/sources/shiboken2/ApiExtractor/messages.h
index 2b7b75ba0..321a4a538 100644
--- a/sources/shiboken2/ApiExtractor/messages.h
+++ b/sources/shiboken2/ApiExtractor/messages.h
@@ -59,6 +59,9 @@ QString msgNoEnumTypeConflict(const EnumModelItem &enumItem,
const QString &className,
const TypeEntry *t);
+QString msgAmbiguousVaryingTypesFound(const QString &qualifiedName, const TypeEntries &te);
+QString msgAmbiguousTypesFound(const QString &qualifiedName, const TypeEntries &te);
+
QString msgUnmatchedParameterType(const ArgumentModelItem &arg, int n,
const QString &why);
@@ -79,6 +82,10 @@ QString msgUnableToTranslateType(const TypeInfo &typeInfo,
QString msgCannotFindTypeEntry(const QString &t);
+QString msgCannotFindTypeEntryForSmartPointer(const QString &t, const QString &smartPointerType);
+QString msgInvalidSmartPointerType(const TypeInfo &i);
+QString msgCannotFindSmartPointerInstantion(const TypeInfo &i);
+
QString msgCannotTranslateTemplateArgument(int i,
const TypeInfo &typeInfo,
const QString &why);
diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.cpp b/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
index 099ab8860..892a20bb7 100644
--- a/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
+++ b/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
@@ -923,6 +923,16 @@ void _NamespaceModelItem::appendNamespace(const _NamespaceModelItem &other)
void _NamespaceModelItem::formatDebug(QDebug &d) const
{
_ScopeModelItem::formatDebug(d);
+ switch (m_type) {
+ case NamespaceType::Default:
+ break;
+ case NamespaceType::Anonymous:
+ d << ", anonymous";
+ break;
+ case NamespaceType::Inline:
+ d << ", inline";
+ break;
+ }
formatScopeList(d, ", namespaces=", m_namespaces);
}
#endif // !QT_NO_DEBUG_STREAM
diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.h b/sources/shiboken2/ApiExtractor/parser/codemodel.h
index 80db2cce5..2e33d6cd0 100644
--- a/sources/shiboken2/ApiExtractor/parser/codemodel.h
+++ b/sources/shiboken2/ApiExtractor/parser/codemodel.h
@@ -438,6 +438,9 @@ public:
const NamespaceList &namespaces() const { return m_namespaces; }
+ NamespaceType type() const { return m_type; }
+ void setType(NamespaceType t) { m_type = t; }
+
void addNamespace(NamespaceModelItem item);
NamespaceModelItem findNamespace(const QString &name) const;
@@ -450,6 +453,7 @@ public:
private:
NamespaceList m_namespaces;
+ NamespaceType m_type = NamespaceType::Default;
};
class _FileModelItem: public _NamespaceModelItem
diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel_enums.h b/sources/shiboken2/ApiExtractor/parser/codemodel_enums.h
index 1713ba42f..aebd59879 100644
--- a/sources/shiboken2/ApiExtractor/parser/codemodel_enums.h
+++ b/sources/shiboken2/ApiExtractor/parser/codemodel_enums.h
@@ -54,4 +54,11 @@ enum class ExceptionSpecification
Throws
};
+enum class NamespaceType
+{
+ Default,
+ Anonymous,
+ Inline
+};
+
#endif // CODEMODEL_ENUMS_H
diff --git a/sources/shiboken2/ApiExtractor/reporthandler.cpp b/sources/shiboken2/ApiExtractor/reporthandler.cpp
index ee70a8e9b..63091cb54 100644
--- a/sources/shiboken2/ApiExtractor/reporthandler.cpp
+++ b/sources/shiboken2/ApiExtractor/reporthandler.cpp
@@ -35,7 +35,7 @@
#include <cstdarg>
#include <cstdio>
-#if _WINDOWS || NOCOLOR
+#if defined(_WINDOWS) || defined(NOCOLOR)
#define COLOR_END ""
#define COLOR_WHITE ""
#define COLOR_YELLOW ""
diff --git a/sources/shiboken2/ApiExtractor/typedatabase.cpp b/sources/shiboken2/ApiExtractor/typedatabase.cpp
index f393bf3bf..775ed2f81 100644
--- a/sources/shiboken2/ApiExtractor/typedatabase.cpp
+++ b/sources/shiboken2/ApiExtractor/typedatabase.cpp
@@ -144,6 +144,25 @@ IncludeList TypeDatabase::extraIncludes(const QString& className) const
return typeEntry ? typeEntry->extraIncludes() : IncludeList();
}
+void TypeDatabase::addSystemInclude(const QString &name)
+{
+ m_systemIncludes.append(name.toUtf8());
+}
+
+// Add a lookup for the short name excluding inline namespaces
+// so that "std::shared_ptr" finds "std::__1::shared_ptr" as well.
+// Note: This inserts duplicate TypeEntry * into m_entries.
+void TypeDatabase::addInlineNamespaceLookups(const NamespaceTypeEntry *n)
+{
+ QVector<TypeEntry *> additionalEntries; // Store before modifying the hash
+ for (TypeEntry *entry : m_entries) {
+ if (entry->isChildOf(n))
+ additionalEntries.append(entry);
+ }
+ for (const auto &ae : additionalEntries)
+ m_entries.insert(ae->shortName(), ae);
+}
+
ContainerTypeEntry* TypeDatabase::findContainerType(const QString &name) const
{
QString template_name = name;
@@ -166,7 +185,7 @@ static bool inline useType(const TypeEntry *t)
FunctionTypeEntry* TypeDatabase::findFunctionType(const QString& name) const
{
- const auto entries = findTypes(name);
+ const auto entries = findTypeRange(name);
for (TypeEntry *entry : entries) {
if (entry->type() == TypeEntry::FunctionType && useType(entry))
return static_cast<FunctionTypeEntry*>(entry);
@@ -201,7 +220,7 @@ QString TypeDatabase::defaultPackageName() const
TypeEntry* TypeDatabase::findType(const QString& name) const
{
- const auto entries = findTypes(name);
+ const auto entries = findTypeRange(name);
for (TypeEntry *entry : entries) {
if (useType(entry))
return entry;
@@ -209,7 +228,53 @@ TypeEntry* TypeDatabase::findType(const QString& name) const
return nullptr;
}
-TypeEntryMultiMapConstIteratorRange TypeDatabase::findTypes(const QString &name) const
+template <class Predicate>
+TypeEntries TypeDatabase::findTypesHelper(const QString &name, Predicate pred) const
+{
+ TypeEntries result;
+ const auto entries = findTypeRange(name);
+ for (TypeEntry *entry : entries) {
+ if (pred(entry))
+ result.append(entry);
+ }
+ return result;
+}
+
+TypeEntries TypeDatabase::findTypes(const QString &name) const
+{
+ return findTypesHelper(name, useType);
+}
+
+static bool useCppType(const TypeEntry *t)
+{
+ bool result = false;
+ switch (t->type()) {
+ case TypeEntry::PrimitiveType:
+ case TypeEntry::VoidType:
+ case TypeEntry::FlagsType:
+ case TypeEntry::EnumType:
+ case TypeEntry::TemplateArgumentType:
+ case TypeEntry::BasicValueType:
+ case TypeEntry::ContainerType:
+ case TypeEntry::ObjectType:
+ case TypeEntry::ArrayType:
+ case TypeEntry::CustomType:
+ case TypeEntry::SmartPointerType:
+ case TypeEntry::TypedefType:
+ result = useType(t);
+ break;
+ default:
+ break;
+ }
+ return result;
+}
+
+TypeEntries TypeDatabase::findCppTypes(const QString &name) const
+{
+ return findTypesHelper(name, useCppType);
+}
+
+TypeEntryMultiMapConstIteratorRange TypeDatabase::findTypeRange(const QString &name) const
{
const auto range = m_entries.equal_range(name);
return {range.first, range.second};
@@ -322,11 +387,10 @@ TypeEntry *TypeDatabase::resolveTypeDefEntry(TypedefEntry *typedefEntry,
if (lessThanPos != -1)
sourceName.truncate(lessThanPos);
ComplexTypeEntry *source = nullptr;
- for (TypeEntry *e : findTypes(sourceName)) {
+ for (TypeEntry *e : findTypeRange(sourceName)) {
switch (e->type()) {
case TypeEntry::BasicValueType:
case TypeEntry::ContainerType:
- case TypeEntry::InterfaceType:
case TypeEntry::ObjectType:
case TypeEntry::SmartPointerType:
source = dynamic_cast<ComplexTypeEntry *>(e);
@@ -581,7 +645,7 @@ bool TypeDatabase::parseFile(QIODevice* device, bool generate)
PrimitiveTypeEntry *TypeDatabase::findPrimitiveType(const QString& name) const
{
- const auto entries = findTypes(name);
+ const auto entries = findTypeRange(name);
for (TypeEntry *entry : entries) {
if (entry->isPrimitive()) {
auto *pe = static_cast<PrimitiveTypeEntry *>(entry);
@@ -595,7 +659,7 @@ PrimitiveTypeEntry *TypeDatabase::findPrimitiveType(const QString& name) const
ComplexTypeEntry* TypeDatabase::findComplexType(const QString& name) const
{
- const auto entries = findTypes(name);
+ const auto entries = findTypeRange(name);
for (TypeEntry *entry : entries) {
if (entry->isComplex() && useType(entry))
return static_cast<ComplexTypeEntry*>(entry);
@@ -605,7 +669,7 @@ ComplexTypeEntry* TypeDatabase::findComplexType(const QString& name) const
ObjectTypeEntry* TypeDatabase::findObjectType(const QString& name) const
{
- const auto entries = findTypes(name);
+ const auto entries = findTypeRange(name);
for (TypeEntry *entry : entries) {
if (entry && entry->isObject() && useType(entry))
return static_cast<ObjectTypeEntry*>(entry);
@@ -616,7 +680,7 @@ ObjectTypeEntry* TypeDatabase::findObjectType(const QString& name) const
NamespaceTypeEntryList TypeDatabase::findNamespaceTypes(const QString& name) const
{
NamespaceTypeEntryList result;
- const auto entries = findTypes(name);
+ const auto entries = findTypeRange(name);
for (TypeEntry *entry : entries) {
if (entry->isNamespace())
result.append(static_cast<NamespaceTypeEntry*>(entry));
@@ -698,6 +762,35 @@ static void _computeTypeIndexes()
computeTypeIndexes = false;
}
+// Build the C++ name excluding any inline namespaces
+// ("std::__1::shared_ptr" -> "std::shared_ptr"
+QString TypeEntry::shortName() const
+{
+ if (m_cachedShortName.isEmpty()) {
+ QVarLengthArray<const TypeEntry *> parents;
+ bool foundInlineNamespace = false;
+ for (auto p = m_parent; p != nullptr && p->type() != TypeEntry::TypeSystemType; p = p->parent()) {
+ if (p->type() == TypeEntry::NamespaceType
+ && static_cast<const NamespaceTypeEntry *>(p)->isInlineNamespace()) {
+ foundInlineNamespace = true;
+ } else {
+ parents.append(p);
+ }
+ }
+ if (foundInlineNamespace) {
+ m_cachedShortName.reserve(m_name.size());
+ for (int i = parents.size() - 1; i >= 0; --i) {
+ m_cachedShortName.append(parents.at(i)->entryName());
+ m_cachedShortName.append(QLatin1String("::"));
+ }
+ m_cachedShortName.append(m_entryName);
+ } else {
+ m_cachedShortName = m_name;
+ }
+ }
+ return m_cachedShortName;
+}
+
void TypeEntry::setRevision(int r)
{
if (m_revision != r) {
@@ -794,7 +887,7 @@ void TypeEntry::formatDebug(QDebug &d) const
if (m_name != cppName)
d << "\", cppName=\"" << cppName << '"';
d << ", type=" << m_type << ", codeGeneration=0x"
- << hex << m_codeGeneration << dec
+ << Qt::hex << m_codeGeneration << Qt::dec
<< ", target=\"" << targetLangName() << '"';
FORMAT_NONEMPTY_STRING("package", m_targetLangPackage)
FORMAT_BOOL("stream", m_stream)
@@ -849,6 +942,9 @@ void NamespaceTypeEntry::formatDebug(QDebug &d) const
ComplexTypeEntry::formatDebug(d);
auto pattern = m_filePattern.pattern();
FORMAT_NONEMPTY_STRING("pattern", pattern)
+ d << ",visibility=" << m_visibility;
+ if (m_inlineNamespace)
+ d << "[inline]";
}
void ContainerTypeEntry::formatDebug(QDebug &d) const
@@ -857,6 +953,17 @@ void ContainerTypeEntry::formatDebug(QDebug &d) const
d << ", type=" << m_type << ",\"" << typeName() << '"';
}
+void SmartPointerTypeEntry::formatDebug(QDebug &d) const
+{
+ ComplexTypeEntry::formatDebug(d);
+ if (!m_instantiations.isEmpty()) {
+ d << ", instantiations[" << m_instantiations.size() << "]=(";
+ for (auto i : m_instantiations)
+ d << i->name() << ',';
+ d << ')';
+ }
+}
+
QDebug operator<<(QDebug d, const TypeEntry *te)
{
QDebugStateSaver saver(d);
diff --git a/sources/shiboken2/ApiExtractor/typedatabase.h b/sources/shiboken2/ApiExtractor/typedatabase.h
index f615b623d..0a0a4eed5 100644
--- a/sources/shiboken2/ApiExtractor/typedatabase.h
+++ b/sources/shiboken2/ApiExtractor/typedatabase.h
@@ -96,6 +96,11 @@ public:
IncludeList extraIncludes(const QString &className) const;
+ const QByteArrayList &systemIncludes() const { return m_systemIncludes; }
+ void addSystemInclude(const QString &name);
+
+ void addInlineNamespaceLookups(const NamespaceTypeEntry *n);
+
PrimitiveTypeEntry *findPrimitiveType(const QString &name) const;
ComplexTypeEntry *findComplexType(const QString &name) const;
ObjectTypeEntry *findObjectType(const QString &name) const;
@@ -108,6 +113,8 @@ public:
QString defaultPackageName() const;
TypeEntry *findType(const QString &name) const;
+ TypeEntries findTypes(const QString &name) const;
+ TypeEntries findCppTypes(const QString &name) const;
const TypeEntryMultiMap &entries() const { return m_entries; }
const TypedefEntryMap &typedefEntries() const { return m_typedefEntries; }
@@ -179,11 +186,13 @@ public:
void formatDebug(QDebug &d) const;
#endif
private:
- TypeEntryMultiMapConstIteratorRange findTypes(const QString &name) const;
+ TypeEntryMultiMapConstIteratorRange findTypeRange(const QString &name) const;
+ template <class Predicate>
+ TypeEntries findTypesHelper(const QString &name, Predicate pred) const;
TypeEntry *resolveTypeDefEntry(TypedefEntry *typedefEntry, QString *errorMessage);
bool m_suppressWarnings = true;
- TypeEntryMultiMap m_entries;
+ TypeEntryMultiMap m_entries; // Contains duplicate entries (cf addInlineNamespaceLookups).
TypeEntryMap m_flagsEntries;
TypedefEntryMap m_typedefEntries;
TemplateEntryMap m_templates;
@@ -201,6 +210,7 @@ private:
QVector<TypeRejection> m_rejections;
QStringList m_dropTypeEntries;
+ QByteArrayList m_systemIncludes;
};
#ifndef QT_NO_DEBUG_STREAM
diff --git a/sources/shiboken2/ApiExtractor/typesystem.cpp b/sources/shiboken2/ApiExtractor/typesystem.cpp
index abd2bfb07..0ec158ae1 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.cpp
+++ b/sources/shiboken2/ApiExtractor/typesystem.cpp
@@ -433,7 +433,7 @@ QDebug operator<<(QDebug d, const CodeSnip &s)
void Modification::formatDebug(QDebug &d) const
{
- d << "modifiers=" << hex << showbase << modifiers << noshowbase << dec;
+ d << "modifiers=" << Qt::hex << Qt::showbase << modifiers << Qt::noshowbase << Qt::dec;
if (removal)
d << ", removal";
if (!renamedToName.isEmpty())
@@ -684,6 +684,15 @@ TypeEntry::~TypeEntry()
delete m_customConversion;
}
+bool TypeEntry::isChildOf(const TypeEntry *p) const
+{
+ for (auto e = m_parent; e; e = e->parent()) {
+ if (e == p)
+ return true;
+ }
+ return false;
+}
+
const TypeSystemTypeEntry *TypeEntry::typeSystemTypeEntry() const
{
for (auto e = this; e; e = e->parent()) {
@@ -693,6 +702,16 @@ const TypeSystemTypeEntry *TypeEntry::typeSystemTypeEntry() const
return nullptr;
}
+const TypeEntry *TypeEntry::targetLangEnclosingEntry() const
+{
+ auto result = m_parent;
+ while (result && result->type() != TypeEntry::TypeSystemType
+ && !NamespaceTypeEntry::isVisibleScope(result)) {
+ result = result->parent();
+ }
+ return result;
+}
+
QString TypeEntry::targetLangName() const
{
if (m_cachedTargetLangName.isEmpty())
@@ -704,11 +723,13 @@ QString TypeEntry::buildTargetLangName() const
{
QString result = m_entryName;
for (auto p = parent(); p && p->type() != TypeEntry::TypeSystemType; p = p->parent()) {
- if (!result.isEmpty())
- result.prepend(QLatin1Char('.'));
- QString n = p->m_entryName;
- n.replace(QLatin1String("::"), QLatin1String(".")); // Primitive types may have "std::"
- result.prepend(n);
+ if (NamespaceTypeEntry::isVisibleScope(p)) {
+ if (!result.isEmpty())
+ result.prepend(QLatin1Char('.'));
+ QString n = p->m_entryName;
+ n.replace(QLatin1String("::"), QLatin1String(".")); // Primitive types may have "std::"
+ result.prepend(n);
+ }
}
return result;
}
@@ -752,6 +773,8 @@ TypeEntry *TypeEntry::clone() const
// Take over parameters relevant for typedefs
void TypeEntry::useAsTypedef(const TypeEntry *source)
{
+ // XML Typedefs are in the global namespace for now.
+ m_parent = source->typeSystemTypeEntry();
m_entryName = source->m_entryName;
m_name = source->m_name;
m_targetLangPackage = source->m_targetLangPackage;
@@ -933,6 +956,11 @@ TypeEntry *SmartPointerTypeEntry::clone() const
SmartPointerTypeEntry::SmartPointerTypeEntry(const SmartPointerTypeEntry &) = default;
+bool SmartPointerTypeEntry::matchesInstantiation(const TypeEntry *e) const
+{
+ return m_instantiations.isEmpty() || m_instantiations.contains(e);
+}
+
NamespaceTypeEntry::NamespaceTypeEntry(const QString &entryName, const QVersionNumber &vr,
const TypeEntry *parent) :
ComplexTypeEntry(entryName, NamespaceType, vr, parent)
@@ -959,6 +987,18 @@ bool NamespaceTypeEntry::matchesFile(const QString &needle) const
return m_filePattern.match(needle).hasMatch();
}
+bool NamespaceTypeEntry::isVisible() const
+{
+ return m_visibility == TypeSystem::Visibility::Visible
+ || (m_visibility == TypeSystem::Visibility::Auto && !m_inlineNamespace);
+}
+
+bool NamespaceTypeEntry::isVisibleScope(const TypeEntry *e)
+{
+ return e->type() != TypeEntry::NamespaceType
+ || static_cast<const NamespaceTypeEntry *>(e)->isVisible();
+}
+
ValueTypeEntry::ValueTypeEntry(const QString &entryName, const QVersionNumber &vr,
const TypeEntry *parent) :
ComplexTypeEntry(entryName, BasicValueType, vr, parent)
@@ -970,11 +1010,6 @@ bool ValueTypeEntry::isValue() const
return true;
}
-bool ValueTypeEntry::isNativeIdBased() const
-{
- return true;
-}
-
TypeEntry *ValueTypeEntry::clone() const
{
return new ValueTypeEntry(*this);
@@ -1122,30 +1157,6 @@ void CustomConversion::TargetToNativeConversion::setConversion(const QString& co
m_d->conversion = conversion;
}
-InterfaceTypeEntry::InterfaceTypeEntry(const QString &entryName, const QVersionNumber &vr,
- const TypeEntry *parent) :
- ComplexTypeEntry(entryName, InterfaceType, vr, parent)
-{
-}
-
-bool InterfaceTypeEntry::isNativeIdBased() const
-{
- return true;
-}
-
-QString InterfaceTypeEntry::qualifiedCppName() const
-{
- const int len = ComplexTypeEntry::qualifiedCppName().length() - interfaceName(QString()).length();
- return ComplexTypeEntry::qualifiedCppName().left(len);
-}
-
-TypeEntry *InterfaceTypeEntry::clone() const
-{
- return new InterfaceTypeEntry(*this);
-}
-
-InterfaceTypeEntry::InterfaceTypeEntry(const InterfaceTypeEntry &) = default;
-
FunctionTypeEntry::FunctionTypeEntry(const QString &entryName, const QString &signature,
const QVersionNumber &vr,
const TypeEntry *parent) :
@@ -1167,16 +1178,6 @@ ObjectTypeEntry::ObjectTypeEntry(const QString &entryName, const QVersionNumber
{
}
-InterfaceTypeEntry *ObjectTypeEntry::designatedInterface() const
-{
- return m_interface;
-}
-
-bool ObjectTypeEntry::isNativeIdBased() const
-{
- return true;
-}
-
TypeEntry *ObjectTypeEntry::clone() const
{
return new ObjectTypeEntry(*this);
diff --git a/sources/shiboken2/ApiExtractor/typesystem.h b/sources/shiboken2/ApiExtractor/typesystem.h
index 8d8d60f3f..2324e8b78 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.h
+++ b/sources/shiboken2/ApiExtractor/typesystem.h
@@ -228,7 +228,7 @@ struct ArgumentModification
struct Modification
{
- enum Modifiers {
+ enum Modifiers : uint {
InvalidModifier = 0x0000,
Private = 0x0001,
Protected = 0x0002,
@@ -499,7 +499,6 @@ QDebug operator<<(QDebug d, const AddedFunction::Argument &a);
QDebug operator<<(QDebug d, const AddedFunction &af);
#endif
-class InterfaceTypeEntry;
class ObjectTypeEntry;
class DocModification
@@ -562,20 +561,13 @@ public:
EnumValue,
ConstantValueType,
TemplateArgumentType,
- ThreadType,
BasicValueType,
- StringType,
ContainerType,
- InterfaceType,
ObjectType,
NamespaceType,
- VariantType,
- JObjectWrapperType,
- CharType,
ArrayType,
TypeSystemType,
CustomType,
- TargetLangType,
FunctionType,
SmartPointerType,
TypedefType
@@ -605,7 +597,10 @@ public:
const TypeEntry *parent() const { return m_parent; }
void setParent(const TypeEntry *p) { m_parent = p; }
+ bool isChildOf(const TypeEntry *p) const;
const TypeSystemTypeEntry *typeSystemTypeEntry() const;
+ // cf AbstractMetaClass::targetLangEnclosingClass()
+ const TypeEntry *targetLangEnclosingEntry() const;
bool isPrimitive() const
{
@@ -619,22 +614,10 @@ public:
{
return m_type == FlagsType;
}
- bool isInterface() const
- {
- return m_type == InterfaceType;
- }
bool isObject() const
{
return m_type == ObjectType;
}
- bool isString() const
- {
- return m_type == StringType;
- }
- bool isChar() const
- {
- return m_type == CharType;
- }
bool isNamespace() const
{
return m_type == NamespaceType;
@@ -647,14 +630,6 @@ public:
{
return m_type == SmartPointerType;
}
- bool isVariant() const
- {
- return m_type == VariantType;
- }
- bool isJObjectWrapper() const
- {
- return m_type == JObjectWrapperType;
- }
bool isArray() const
{
return m_type == ArrayType;
@@ -671,18 +646,10 @@ public:
{
return m_type == VarargsType;
}
- bool isThread() const
- {
- return m_type == ThreadType;
- }
bool isCustom() const
{
return m_type == CustomType;
}
- bool isBasicValue() const
- {
- return m_type == BasicValueType;
- }
bool isTypeSystem() const
{
return m_type == TypeSystemType;
@@ -708,6 +675,8 @@ public:
// The type's name in C++, fully qualified
QString name() const { return m_name; }
+ // C++ excluding inline namespaces
+ QString shortName() const;
// Name as specified in XML
QString entryName() const { return m_entryName; }
@@ -766,11 +735,6 @@ public:
QString qualifiedTargetLangName() const;
- virtual InterfaceTypeEntry *designatedInterface() const
- {
- return nullptr;
- }
-
void setCustomConstructor(const CustomFunction &func)
{
m_customConstructor = func;
@@ -798,11 +762,6 @@ public:
return false;
}
- virtual bool isNativeIdBased() const
- {
- return false;
- }
-
CodeSnipList codeSnips() const;
void setCodeSnips(const CodeSnipList &codeSnips)
{
@@ -896,7 +855,8 @@ protected:
private:
const TypeEntry *m_parent;
- QString m_name; // fully qualified
+ QString m_name; // C++ fully qualified
+ mutable QString m_cachedShortName; // C++ excluding inline namespaces
QString m_entryName;
QString m_targetLangPackage;
mutable QString m_cachedTargetLangName; // "Foo.Bar"
@@ -1490,6 +1450,8 @@ private:
class SmartPointerTypeEntry : public ComplexTypeEntry
{
public:
+ using Instantiations = QVector<const TypeEntry *>;
+
explicit SmartPointerTypeEntry(const QString &entryName,
const QString &getterName,
const QString &smartPointerType,
@@ -1509,6 +1471,13 @@ public:
TypeEntry *clone() const override;
+ Instantiations instantiations() const { return m_instantiations; }
+ void setInstantiations(const Instantiations &i) { m_instantiations = i; }
+ bool matchesInstantiation(const TypeEntry *e) const;
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
protected:
SmartPointerTypeEntry(const SmartPointerTypeEntry &);
@@ -1516,6 +1485,7 @@ private:
QString m_getterName;
QString m_smartPointerType;
QString m_refCountMethodName;
+ Instantiations m_instantiations;
};
class NamespaceTypeEntry : public ComplexTypeEntry
@@ -1536,6 +1506,15 @@ public:
bool matchesFile(const QString &needle) const;
+ bool isVisible() const;
+ void setVisibility(TypeSystem::Visibility v) { m_visibility = v; }
+
+ // C++ 11 inline namespace, from code model
+ bool isInlineNamespace() const { return m_inlineNamespace; }
+ void setInlineNamespace(bool i) { m_inlineNamespace = i; }
+
+ static bool isVisibleScope(const TypeEntry *e);
+
#ifndef QT_NO_DEBUG_STREAM
void formatDebug(QDebug &d) const override;
#endif
@@ -1546,7 +1525,9 @@ protected:
private:
QRegularExpression m_filePattern;
const NamespaceTypeEntry *m_extends = nullptr;
+ TypeSystem::Visibility m_visibility = TypeSystem::Visibility::Auto;
bool m_hasPattern = false;
+ bool m_inlineNamespace = false;
};
class ValueTypeEntry : public ComplexTypeEntry
@@ -1557,8 +1538,6 @@ public:
bool isValue() const override;
- bool isNativeIdBased() const override;
-
TypeEntry *clone() const override;
protected:
@@ -1567,39 +1546,6 @@ protected:
ValueTypeEntry(const ValueTypeEntry &);
};
-class InterfaceTypeEntry : public ComplexTypeEntry
-{
-public:
- explicit InterfaceTypeEntry(const QString &entryName, const QVersionNumber &vr,
- const TypeEntry *parent);
-
- static QString interfaceName(const QString &name)
- {
- return name + QLatin1String("Interface");
- }
-
- ObjectTypeEntry *origin() const
- {
- return m_origin;
- }
- void setOrigin(ObjectTypeEntry *origin)
- {
- m_origin = origin;
- }
-
- bool isNativeIdBased() const override;
- QString qualifiedCppName() const override;
-
- TypeEntry *clone() const override;
-
-protected:
- InterfaceTypeEntry(const InterfaceTypeEntry &);
-
-private:
- ObjectTypeEntry *m_origin = nullptr;
-};
-
-
class FunctionTypeEntry : public TypeEntry
{
public:
@@ -1636,21 +1582,10 @@ public:
explicit ObjectTypeEntry(const QString &entryName, const QVersionNumber &vr,
const TypeEntry *parent);
- InterfaceTypeEntry *designatedInterface() const override;
- void setDesignatedInterface(InterfaceTypeEntry *entry)
- {
- m_interface = entry;
- }
-
- bool isNativeIdBased() const override;
-
TypeEntry *clone() const override;
protected:
ObjectTypeEntry(const ObjectTypeEntry &);
-
-private:
- InterfaceTypeEntry *m_interface = nullptr;
};
struct TypeRejection
diff --git a/sources/shiboken2/ApiExtractor/typesystem_enums.h b/sources/shiboken2/ApiExtractor/typesystem_enums.h
index df83429d0..120c9417f 100644
--- a/sources/shiboken2/ApiExtractor/typesystem_enums.h
+++ b/sources/shiboken2/ApiExtractor/typesystem_enums.h
@@ -98,6 +98,13 @@ enum class ExceptionHandling {
On
};
+enum Visibility { // For namespaces
+ Unspecified,
+ Visible,
+ Invisible,
+ Auto
+};
+
} // namespace TypeSystem
#endif // TYPESYSTEM_ENUMS_H
diff --git a/sources/shiboken2/ApiExtractor/typesystem_typedefs.h b/sources/shiboken2/ApiExtractor/typesystem_typedefs.h
index fd702793e..73f92b294 100644
--- a/sources/shiboken2/ApiExtractor/typesystem_typedefs.h
+++ b/sources/shiboken2/ApiExtractor/typesystem_typedefs.h
@@ -40,6 +40,7 @@ class DocModification;
struct AddedFunction;
struct FieldModification;
struct FunctionModification;
+class TypeEntry;
using AddedFunctionPtr = QSharedPointer<AddedFunction>;
using AddedFunctionList = QVector<AddedFunctionPtr>;
@@ -47,5 +48,6 @@ using CodeSnipList = QVector<CodeSnip>;
using DocModificationList = QVector<DocModification>;
using FieldModificationList = QVector<FieldModification>;
using FunctionModificationList = QVector<FunctionModification>;
+using TypeEntries = QVector<const TypeEntry *>;
#endif // TYPESYSTEM_TYPEDEFS_H
diff --git a/sources/shiboken2/ApiExtractor/typesystemparser.cpp b/sources/shiboken2/ApiExtractor/typesystemparser.cpp
index 5252ac00a..efdab8be3 100644
--- a/sources/shiboken2/ApiExtractor/typesystemparser.cpp
+++ b/sources/shiboken2/ApiExtractor/typesystemparser.cpp
@@ -63,6 +63,7 @@ static inline QString deprecatedAttribute() { return QStringLiteral("deprecated"
static inline QString noOverrideCachingAttribute() { return QStringLiteral("no-override-caching"); }
static inline QString exceptionHandlingAttribute() { return QStringLiteral("exception-handling"); }
static inline QString extensibleAttribute() { return QStringLiteral("extensible"); }
+static inline QString fileNameAttribute() { return QStringLiteral("file-name"); }
static inline QString flagsAttribute() { return QStringLiteral("flags"); }
static inline QString forceAbstractAttribute() { return QStringLiteral("force-abstract"); }
static inline QString forceIntegerAttribute() { return QStringLiteral("force-integer"); }
@@ -95,6 +96,7 @@ static inline QString sourceAttribute() { return QStringLiteral("source"); }
static inline QString streamAttribute() { return QStringLiteral("stream"); }
static inline QString xPathAttribute() { return QStringLiteral("xpath"); }
static inline QString virtualSlotAttribute() { return QStringLiteral("virtual-slot"); }
+static inline QString visibleAttribute() { return QStringLiteral("visible"); }
static inline QString enumIdentifiedByValueAttribute() { return QStringLiteral("identified-by-value"); }
static inline QString noAttributeValue() { return QStringLiteral("no"); }
@@ -383,6 +385,7 @@ ENUM_LOOKUP_BEGIN(StackElement::ElementType, Qt::CaseInsensitive,
{u"replace-type", StackElement::ReplaceType},
{u"smart-pointer-type", StackElement::SmartPointerTypeEntry},
{u"suppress-warning", StackElement::SuppressedWarning},
+ {u"system-include", StackElement::SystemInclude},
{u"target-to-native", StackElement::TargetToNative},
{u"template", StackElement::Template},
{u"typedef-type", StackElement::TypedefTypeEntry},
@@ -391,6 +394,17 @@ ENUM_LOOKUP_BEGIN(StackElement::ElementType, Qt::CaseInsensitive,
};
ENUM_LOOKUP_BINARY_SEARCH()
+ENUM_LOOKUP_BEGIN(TypeSystem::Visibility, Qt::CaseSensitive,
+ visibilityFromAttribute, TypeSystem::Visibility::Unspecified)
+{
+ {u"no", TypeSystem::Visibility::Invisible},
+ {u"false", TypeSystem::Visibility::Invisible},
+ {u"auto", TypeSystem::Visibility::Auto},
+ {u"yes", TypeSystem::Visibility::Visible},
+ {u"true", TypeSystem::Visibility::Visible},
+};
+ENUM_LOOKUP_LINEAR_SEARCH()
+
static int indexOfAttribute(const QXmlStreamAttributes &atts,
QStringView name)
{
@@ -637,6 +651,14 @@ bool TypeSystemParser::parse(QXmlStreamReader &reader)
{
m_error.clear();
m_currentPath.clear();
+ m_smartPointerInstantiations.clear();
+ const bool result = parseXml(reader) && setupSmartPointerInstantiations();
+ m_smartPointerInstantiations.clear();
+ return result;
+}
+
+bool TypeSystemParser::parseXml(QXmlStreamReader &reader)
+{
const QString fileName = readerFileName(reader);
if (!fileName.isEmpty())
m_currentPath = QFileInfo(fileName).absolutePath();
@@ -680,6 +702,62 @@ bool TypeSystemParser::parse(QXmlStreamReader &reader)
return true;
}
+// Split a type list potentially with template types
+// "A<B,C>,D" -> ("A<B,C>", "D")
+static QStringList splitTypeList(const QString &s)
+{
+ QStringList result;
+ int templateDepth = 0;
+ int lastPos = 0;
+ const int size = s.size();
+ for (int i = 0; i < size; ++i) {
+ switch (s.at(i).toLatin1()) {
+ case '<':
+ ++templateDepth;
+ break;
+ case '>':
+ --templateDepth;
+ break;
+ case ',':
+ if (templateDepth == 0) {
+ result.append(s.mid(lastPos, i - lastPos).trimmed());
+ lastPos = i + 1;
+ }
+ break;
+ }
+ }
+ if (lastPos < size)
+ result.append(s.mid(lastPos, size - lastPos).trimmed());
+ return result;
+}
+
+bool TypeSystemParser::setupSmartPointerInstantiations()
+{
+ for (auto it = m_smartPointerInstantiations.cbegin(),
+ end = m_smartPointerInstantiations.cend(); it != end; ++it) {
+ auto smartPointerEntry = it.key();
+ const auto instantiationNames = splitTypeList(it.value());
+ SmartPointerTypeEntry::Instantiations instantiations;
+ instantiations.reserve(instantiationNames.size());
+ for (const auto &instantiationName : instantiationNames) {
+ const auto types = m_database->findCppTypes(instantiationName);
+ if (types.isEmpty()) {
+ m_error =
+ msgCannotFindTypeEntryForSmartPointer(instantiationName,
+ smartPointerEntry->name());
+ return false;
+ }
+ if (types.size() > 1) {
+ m_error = msgAmbiguousTypesFound(instantiationName, types);
+ return false;
+ }
+ instantiations.append(types.constFirst());
+ }
+ smartPointerEntry->setInstantiations(instantiations);
+ }
+ return true;
+}
+
bool TypeSystemParser::endElement(const QStringRef &localName)
{
if (m_ignoreDepth) {
@@ -727,11 +805,6 @@ bool TypeSystemParser::endElement(const QStringRef &localName)
centry->setFieldModifications(m_contextStack.top()->fieldMods);
centry->setCodeSnips(m_contextStack.top()->codeSnips);
centry->setDocModification(m_contextStack.top()->docModifications);
-
- if (centry->designatedInterface()) {
- centry->designatedInterface()->setCodeSnips(m_contextStack.top()->codeSnips);
- centry->designatedInterface()->setFunctionModifications(m_contextStack.top()->functionMods);
- }
}
break;
case StackElement::AddFunction: {
@@ -814,7 +887,7 @@ bool TypeSystemParser::endElement(const QStringRef &localName)
break;
default:
break; // nada
- };
+ }
break;
default:
break;
@@ -890,7 +963,7 @@ bool TypeSystemParser::characters(const String &ch)
break;
default:
Q_ASSERT(false);
- };
+ }
return true;
}
}
@@ -1122,6 +1195,7 @@ SmartPointerTypeEntry *
QString smartPointerType;
QString getter;
QString refCountMethodName;
+ QString instantiations;
for (int i = attributes->size() - 1; i >= 0; --i) {
const QStringRef name = attributes->at(i).qualifiedName();
if (name == QLatin1String("type")) {
@@ -1130,6 +1204,8 @@ SmartPointerTypeEntry *
getter = attributes->takeAt(i).value().toString();
} else if (name == QLatin1String("ref-count-method")) {
refCountMethodName = attributes->takeAt(i).value().toString();
+ } else if (name == QLatin1String("instantiations")) {
+ instantiations = attributes->takeAt(i).value().toString();
}
}
@@ -1164,6 +1240,7 @@ SmartPointerTypeEntry *
auto *type = new SmartPointerTypeEntry(name, getter, smartPointerType,
refCountMethodName, since, currentParentTypeEntry());
applyCommonAttributes(type, attributes);
+ m_smartPointerInstantiations.insert(type, instantiations);
return type;
}
@@ -1263,40 +1340,6 @@ EnumTypeEntry *
return entry;
}
-ObjectTypeEntry *
- TypeSystemParser::parseInterfaceTypeEntry(const QXmlStreamReader &,
- const QString &name, const QVersionNumber &since,
- QXmlStreamAttributes *attributes)
-{
- if (!checkRootElement())
- return nullptr;
- auto *otype = new ObjectTypeEntry(name, since, currentParentTypeEntry());
- applyCommonAttributes(otype, attributes);
- QString targetLangName = name;
- bool generate = true;
- for (int i = attributes->size() - 1; i >= 0; --i) {
- const QStringRef name = attributes->at(i).qualifiedName();
- if (name == targetLangNameAttribute()) {
- targetLangName = attributes->takeAt(i).value().toString();
- } else if (name == generateAttribute()) {
- generate = convertBoolean(attributes->takeAt(i).value(),
- generateAttribute(), true);
- }
- }
-
- auto itype = new InterfaceTypeEntry(InterfaceTypeEntry::interfaceName(targetLangName),
- since, currentParentTypeEntry());
- itype->setTargetLangName(targetLangName);
-
- if (generate)
- itype->setCodeGeneration(m_generate);
- else
- itype->setCodeGeneration(TypeEntry::GenerateForSubclass);
-
- otype->setDesignatedInterface(itype);
- itype->setOrigin(otype);
- return otype;
-}
NamespaceTypeEntry *
TypeSystemParser::parseNamespaceTypeEntry(const QXmlStreamReader &reader,
@@ -1306,8 +1349,8 @@ NamespaceTypeEntry *
if (!checkRootElement())
return nullptr;
QScopedPointer<NamespaceTypeEntry> result(new NamespaceTypeEntry(name, since, currentParentTypeEntry()));
+ auto visibility = TypeSystem::Visibility::Unspecified;
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")) {
@@ -1330,9 +1373,24 @@ NamespaceTypeEntry *
return nullptr;
}
result->setExtends(*extendsIt);
+ } else if (attributeName == visibleAttribute()) {
+ const auto attribute = attributes->takeAt(i);
+ visibility = visibilityFromAttribute(attribute.value());
+ if (visibility == TypeSystem::Visibility::Unspecified) {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgInvalidAttributeValue(attribute)));
+ }
+ } else if (attributeName == generateAttribute()) {
+ if (!convertBoolean(attributes->takeAt(i).value(), generateAttribute(), true))
+ visibility = TypeSystem::Visibility::Invisible;
}
}
+ if (visibility != TypeSystem::Visibility::Unspecified)
+ result->setVisibility(visibility);
+ // Handle legacy "generate" before the common handling
+ applyComplexTypeAttributes(reader, result.data(), attributes);
+
if (result->extends() && !result->hasPattern()) {
m_error = msgExtendingNamespaceRequiresPattern(name);
return nullptr;
@@ -1497,9 +1555,6 @@ void TypeSystemParser::applyComplexTypeAttributes(const QXmlStreamReader &reader
if (ctype->type() != TypeEntry::ContainerType)
ctype->setTargetLangPackage(package);
- if (InterfaceTypeEntry *di = ctype->designatedInterface())
- di->setTargetLangPackage(package);
-
if (generate)
ctype->setCodeGeneration(m_generate);
else
@@ -2514,7 +2569,7 @@ bool TypeSystemParser::parseInclude(const QXmlStreamReader &,
QString location;
for (int i = attributes->size() - 1; i >= 0; --i) {
const QStringRef name = attributes->at(i).qualifiedName();
- if (name == QLatin1String("file-name"))
+ if (name == fileNameAttribute())
fileName = attributes->takeAt(i).value().toString();
else if (name == locationAttribute())
location = attributes->takeAt(i).value().toString();
@@ -2535,10 +2590,18 @@ bool TypeSystemParser::parseInclude(const QXmlStreamReader &,
m_error = QLatin1String("Only supported parent tags are primitive-type, complex types or extra-includes");
return false;
}
- if (InterfaceTypeEntry *di = entry->designatedInterface()) {
- di->setInclude(entry->include());
- di->setExtraIncludes(entry->extraIncludes());
+ return true;
+}
+
+bool TypeSystemParser::parseSystemInclude(const QXmlStreamReader &,
+ QXmlStreamAttributes *attributes)
+{
+ const int index = indexOfAttribute(*attributes, fileNameAttribute());
+ if (index == -1) {
+ m_error = msgMissingAttribute(fileNameAttribute());
+ return false;
}
+ TypeDatabase::instance()->addSystemInclude(attributes->takeAt(index).value().toString());
return true;
}
@@ -2776,14 +2839,6 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
element->entry = m_currentEnum;
break;
- case StackElement::InterfaceTypeEntry:
- if (ObjectTypeEntry *oe = parseInterfaceTypeEntry(reader, name, versionRange.since, &attributes)) {
- applyComplexTypeAttributes(reader, oe, &attributes);
- element->entry = oe;
- } else {
- return false;
- }
- break;
case StackElement::ValueTypeEntry:
if (ValueTypeEntry *ve = parseValueTypeEntry(reader, name, versionRange.since, &attributes)) {
applyComplexTypeAttributes(reader, ve, &attributes);
@@ -2799,6 +2854,7 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
return false;
break;
case StackElement::ObjectTypeEntry:
+ case StackElement::InterfaceTypeEntry:
if (!checkRootElement())
return false;
element->entry = new ObjectTypeEntry(name, versionRange.since, currentParentTypeEntry());
@@ -2820,7 +2876,7 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
break;
default:
Q_ASSERT(false);
- };
+ }
if (element->entry) {
if (!m_database->addType(element->entry, &m_error))
@@ -2843,6 +2899,7 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
|| element->type == StackElement::LoadTypesystem
|| element->type == StackElement::InjectCode
|| element->type == StackElement::ExtraIncludes
+ || element->type == StackElement::SystemInclude
|| element->type == StackElement::ConversionRule
|| element->type == StackElement::AddFunction
|| element->type == StackElement::Template;
@@ -2995,6 +3052,10 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
if (!addRejection(m_database, &attributes, &m_error))
return false;
break;
+ case StackElement::SystemInclude:
+ if (!parseSystemInclude(reader, &attributes))
+ return false;
+ break;
case StackElement::Template: {
const int nameIndex = indexOfAttribute(attributes, nameAttribute());
if (nameIndex == -1) {
diff --git a/sources/shiboken2/ApiExtractor/typesystemparser.h b/sources/shiboken2/ApiExtractor/typesystemparser.h
index d3ea54fc6..b4be2765c 100644
--- a/sources/shiboken2/ApiExtractor/typesystemparser.h
+++ b/sources/shiboken2/ApiExtractor/typesystemparser.h
@@ -31,6 +31,7 @@
#include "typesystem.h"
#include <QtCore/QStack>
+#include <QtCore/QHash>
#include <QtCore/QScopedPointer>
QT_FORWARD_DECLARE_CLASS(QXmlStreamAttributes)
@@ -86,6 +87,7 @@ class StackElement
NativeToTarget = 0x1100,
TargetToNative = 0x1200,
AddConversion = 0x1300,
+ SystemInclude = 0x1400,
SimpleMask = 0x3f00,
// Code snip tags (0x1000, 0x2000, ... , 0xf000)
@@ -151,6 +153,8 @@ public:
QString errorString() const { return m_error; }
private:
+ bool parseXml(QXmlStreamReader &reader);
+ bool setupSmartPointerInstantiations();
bool startElement(const QXmlStreamReader &reader);
SmartPointerTypeEntry *parseSmartPointerEntry(const QXmlStreamReader &,
const QString &name,
@@ -184,9 +188,6 @@ private:
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes);
- ObjectTypeEntry *
- parseInterfaceTypeEntry(const QXmlStreamReader &, const QString &name,
- const QVersionNumber &since, QXmlStreamAttributes *);
ValueTypeEntry *
parseValueTypeEntry(const QXmlStreamReader &, const QString &name,
const QVersionNumber &since, QXmlStreamAttributes *);
@@ -247,6 +248,7 @@ private:
StackElement* element, QXmlStreamAttributes *);
bool parseInclude(const QXmlStreamReader &, const StackElement &topElement,
TypeEntry *entry, QXmlStreamAttributes *);
+ bool parseSystemInclude(const QXmlStreamReader &, QXmlStreamAttributes *);
TemplateInstance
*parseTemplateInstanceEnum(const QXmlStreamReader &, const StackElement &topElement,
QXmlStreamAttributes *);
@@ -271,6 +273,7 @@ private:
QString m_currentSignature;
QString m_currentPath;
QScopedPointer<TypeSystemEntityResolver> m_entityResolver;
+ QHash<SmartPointerTypeEntry *, QString> m_smartPointerInstantiations;
};
#endif // TYPESYSTEMPARSER_H
diff --git a/sources/shiboken2/doc/typesystem_specifying_types.rst b/sources/shiboken2/doc/typesystem_specifying_types.rst
index 3ab6adbd6..d296ccc80 100644
--- a/sources/shiboken2/doc/typesystem_specifying_types.rst
+++ b/sources/shiboken2/doc/typesystem_specifying_types.rst
@@ -153,6 +153,7 @@ namespace-type
<typesystem>
<namespace-type name="..."
+ visible="true | auto | false"
generate="yes | no"
package="..."
since="..."
@@ -161,8 +162,16 @@ namespace-type
The **name** attribute is the name of the namespace, e.g., "Qt".
- The *optional* **generate** attribute is used to inform if you need to prepend
- the given namespace into each generated class. Its default value is **yes**.
+ The *optional* **visible** attribute is used specify whether the
+ namespace is visible in the target language name. Its default value is
+ **auto**. It means that normal namespaces are visible, but inline namespaces
+ (as introduced in C++ 11) will not be visible.
+
+ The detection of inline namespaces requires shiboken to be built
+ using LLVM 9.0.
+
+ The *optional* **generate** is a legacy attribute. Specifying
+ **no** is equivalent to **visible="false"**.
The **package** attribute can be used to override the package of the type system.
@@ -331,30 +340,7 @@ object-type
interface-type
^^^^^^^^^^^^^^
- The interface-type node indicates that the given class is replaced by an
- interface pattern when mapping from C++ to the target language. Using the
- interface-type node implicitly makes the given type an :ref:`object-type`.
-
- .. code-block:: xml
-
- <typesystem>
- <interface-type name="..."
- since="..."
- package ="..."
- default-superclass ="..."
- revision="..." />
- </typesystem>
-
- The **name** attribute is the fully qualified C++ class name. The *optional*
- **package** attribute can be used to override the package of the type system.
- If there is no C++ base class, the *optional* **default-superclass** attribute
- can be used to specify a superclass in the generated target language API, for
- the given class.
-
- The *optional* **since** value is used to specify the API version of this interface.
-
- The **revision** attribute can be used to specify a revision for each type, easing the
- production of ABI compatible bindings.
+ This type is deprecated and no longer has any effect. Use object-type instead.
.. _container-type:
@@ -441,6 +427,14 @@ smart-pointer-type
to function return values.
**ref-count-method** specifies the name of the method used to do reference counting.
+ The *optional* attribute **instantiations** specifies for which instantiations
+ of the smart pointer wrappers will be generated (comma-separated list).
+ By default, this will happen for all instantiations found by code parsing.
+ This might be a problem when linking different modules, since wrappers for the
+ same instantiation might be generated into different modules, which then clash.
+ Providing an instantiations list makes it possible to specify which wrappers
+ will be generated into specific modules.
+
.. code-block:: xml
<typesystem>
@@ -448,7 +442,8 @@ smart-pointer-type
since="..."
type="..."
getter="..."
- ref-count-method="..."/>
+ ref-count-method="..."
+ instantiations="..."/>
</typesystem>
.. _function:
@@ -472,3 +467,18 @@ function
The function tag has two *optional* attributes: **since**, whose value is used to specify
the API version of this function, and **rename**, to modify the function name.
+.. _system_include:
+
+system-include
+^^^^^^^^^^^^^^
+
+ The optional **system-include** specifies the name of a system include
+ file to be parsed. Normally, include files considered to be system
+ include files are skipped by the C++ code parser. Its primary use case
+ is exposing classes from the STL library.
+
+ .. code-block:: xml
+
+ <typesystem>
+ <system-include file-name="memory"/>
+ </typesystem>
diff --git a/sources/shiboken2/generator/generator.cpp b/sources/shiboken2/generator/generator.cpp
index 484b1f641..3cc625488 100644
--- a/sources/shiboken2/generator/generator.cpp
+++ b/sources/shiboken2/generator/generator.cpp
@@ -159,7 +159,6 @@ struct Generator::GeneratorPrivate
QString licenseComment;
QString moduleName;
QStringList instantiatedContainersNames;
- QStringList instantiatedSmartPointerNames;
QVector<const AbstractMetaType *> instantiatedContainers;
QVector<const AbstractMetaType *> instantiatedSmartPointers;
@@ -211,6 +210,31 @@ QString Generator::getSimplifiedContainerTypeName(const AbstractMetaType *type)
return typeName;
}
+// Strip a "const QSharedPtr<const Foo> &" or similar to "QSharedPtr<Foo>" (PYSIDE-1016/454)
+const AbstractMetaType *canonicalSmartPtrInstantiation(const AbstractMetaType *type)
+{
+ AbstractMetaTypeList instantiations = type->instantiations();
+ Q_ASSERT(instantiations.size() == 1);
+ const bool needsFix = type->isConstant() || type->referenceType() != NoReference;
+ const bool pointeeNeedsFix = instantiations.constFirst()->isConstant();
+ if (!needsFix && !pointeeNeedsFix)
+ return type;
+ auto fixedType = type->copy();
+ fixedType->setReferenceType(NoReference);
+ fixedType->setConstant(false);
+ if (pointeeNeedsFix) {
+ auto fixedPointeeType = instantiations.constFirst()->copy();
+ fixedPointeeType->setConstant(false);
+ fixedType->setInstantiations(AbstractMetaTypeList(1, fixedPointeeType));
+ }
+ return fixedType;
+}
+
+static inline const TypeEntry *pointeeTypeEntry(const AbstractMetaType *smartPtrType)
+{
+ return smartPtrType->instantiations().constFirst()->typeEntry();
+}
+
void Generator::addInstantiatedContainersAndSmartPointers(const AbstractMetaType *type,
const QString &context)
{
@@ -244,18 +268,15 @@ void Generator::addInstantiatedContainersAndSmartPointers(const AbstractMetaType
m_d->instantiatedContainers.append(type);
}
} else {
- // Is smart pointer.
- if (!m_d->instantiatedSmartPointerNames.contains(typeName)) {
- m_d->instantiatedSmartPointerNames.append(typeName);
- if (type->isConstant() || type->referenceType() != NoReference) {
- // Strip a "const QSharedPtr<Foo> &" or similar to "QSharedPtr<Foo>" (PYSIDE-1016)
- auto fixedType = type->copy();
- fixedType->setReferenceType(NoReference);
- fixedType->setConstant(false);
- type = fixedType;
- }
- m_d->instantiatedSmartPointers.append(type);
- }
+ // Is smart pointer. Check if the (const?) pointee is already known
+ auto pt = pointeeTypeEntry(type);
+ const bool present =
+ std::any_of(m_d->instantiatedSmartPointers.cbegin(), m_d->instantiatedSmartPointers.cend(),
+ [pt] (const AbstractMetaType *t) {
+ return pointeeTypeEntry(t) == pt;
+ });
+ if (!present)
+ m_d->instantiatedSmartPointers.append(canonicalSmartPtrInstantiation(type));
}
}
@@ -449,7 +470,8 @@ bool Generator::generate()
bool Generator::shouldGenerateTypeEntry(const TypeEntry *type) const
{
- return type->codeGeneration() & TypeEntry::GenerateTargetLang;
+ return (type->codeGeneration() & TypeEntry::GenerateTargetLang)
+ && NamespaceTypeEntry::isVisibleScope(type);
}
bool Generator::shouldGenerate(const AbstractMetaClass *metaClass) const
@@ -529,7 +551,7 @@ QTextStream &formatCode(QTextStream &s, const QString &code, Indentor &indentor)
s << indentor << line.remove(0, limit);
}
- s << endl;
+ s << Qt::endl;
}
return s;
}
@@ -670,6 +692,9 @@ DefaultValue Generator::minimalConstructor(const AbstractMetaType *type) const
if (Generator::isPointer(type))
return DefaultValue(DefaultValue::Pointer, QLatin1String("::") + type->typeEntry()->qualifiedCppName());
+ if (type->typeEntry()->isSmartPointer())
+ return minimalConstructor(type->typeEntry());
+
if (type->typeEntry()->isComplex()) {
auto cType = static_cast<const ComplexTypeEntry *>(type->typeEntry());
if (cType->hasDefaultConstructor())
@@ -724,6 +749,9 @@ DefaultValue Generator::minimalConstructor(const TypeEntry *type) const
: DefaultValue(DefaultValue::Custom, ctor);
}
+ if (type->isSmartPointer())
+ return DefaultValue(DefaultValue::DefaultConstructor, type->qualifiedCppName());
+
if (type->isComplex())
return minimalConstructor(AbstractMetaClass::findClass(classes(), type));
@@ -893,8 +921,12 @@ static QString getClassTargetFullName_(const T *t, bool includePackageName)
QString name = t->name();
const AbstractMetaClass *context = t->enclosingClass();
while (context) {
- name.prepend(QLatin1Char('.'));
- name.prepend(context->name());
+ // If the type was marked as 'visible=false' we should not use it in
+ // the type name
+ if (NamespaceTypeEntry::isVisibleScope(context->typeEntry())) {
+ name.prepend(QLatin1Char('.'));
+ name.prepend(context->name());
+ }
context = context->enclosingClass();
}
if (includePackageName) {
diff --git a/sources/shiboken2/generator/main.cpp b/sources/shiboken2/generator/main.cpp
index 700dc00bb..e4d86f489 100644
--- a/sources/shiboken2/generator/main.cpp
+++ b/sources/shiboken2/generator/main.cpp
@@ -73,11 +73,11 @@ static void printOptions(QTextStream &s, const OptionDescriptions &options)
if (od.second.isEmpty()) {
s << ", ";
} else {
- s << endl;
+ s << Qt::endl;
const auto lines = od.second.splitRef(QLatin1Char('\n'));
for (const auto &line : lines)
- s << " " << line << endl;
- s << endl;
+ s << " " << line << Qt::endl;
+ s << Qt::endl;
}
}
}
@@ -343,7 +343,7 @@ void printUsage()
for (const GeneratorPtr &generator : generators) {
const OptionDescriptions options = generator->options();
if (!options.isEmpty()) {
- s << endl << generator->name() << " options:\n\n";
+ s << Qt::endl << generator->name() << " options:\n\n";
printOptions(s, generator->options());
}
}
diff --git a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
index f4efc293f..40cc255f0 100644
--- a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
+++ b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
@@ -172,7 +172,7 @@ static QChar lastChar(const QTextStream &str)
static QTextStream &ensureEndl(QTextStream &s)
{
if (lastChar(s) != QLatin1Char('\n'))
- s << endl;
+ s << Qt::endl;
return s;
}
@@ -502,10 +502,10 @@ QString QtXmlToSphinx::transform(const QString& doc)
if (!m_inlineImages.isEmpty()) {
// Write out inline image definitions stored in handleInlineImageTag().
- m_output << endl;
+ m_output << Qt::endl;
for (const InlineImage &img : qAsConst(m_inlineImages))
- m_output << ".. |" << img.tag << "| image:: " << img.href << endl;
- m_output << endl;
+ m_output << ".. |" << img.tag << "| image:: " << img.href << Qt::endl;
+ m_output << Qt::endl;
m_inlineImages.clear();
}
@@ -608,11 +608,11 @@ void QtXmlToSphinx::handleHeadingTag(QXmlStreamReader& reader)
else
type = types[typeIdx];
} else if (token == QXmlStreamReader::EndElement) {
- m_output << Pad(type, headingSize) << endl << endl;
+ m_output << Pad(type, headingSize) << Qt::endl << Qt::endl;
} else if (token == QXmlStreamReader::Characters) {
- m_output << endl << endl;
+ m_output << Qt::endl << Qt::endl;
headingSize = writeEscapedRstText(m_output, reader.text().trimmed());
- m_output << endl;
+ m_output << Qt::endl;
}
}
@@ -628,7 +628,7 @@ void QtXmlToSphinx::handleParaTag(QXmlStreamReader& reader)
else if (result.startsWith(QLatin1String("**Note:**")))
result.replace(0, 9, QLatin1String(".. note:: "));
- m_output << INDENT << result << endl << endl;
+ m_output << INDENT << result << Qt::endl << Qt::endl;
} else if (token == QXmlStreamReader::Characters) {
const QStringRef text = reader.text();
const QChar end = lastChar(m_output);
@@ -726,7 +726,7 @@ void QtXmlToSphinx::handleSeeAlsoTag(QXmlStreamReader& reader)
handleLinkEnd(m_seeAlsoContext.data());
m_seeAlsoContext.reset();
}
- m_output << endl << endl;
+ m_output << Qt::endl << Qt::endl;
break;
default:
break;
@@ -747,7 +747,7 @@ void formatSnippet(QTextStream &str, Indent indent, const QString &snippet)
for (const QStringRef &line : lines) {
if (!line.trimmed().isEmpty())
str << indent << line;
- str << endl;
+ str << Qt::endl;
}
}
@@ -811,7 +811,7 @@ void QtXmlToSphinx::handleSnippetTag(QXmlStreamReader& reader)
m_output << INDENT << "<Code snippet \"" << location << ':' << identifier << "\" not found>\n";
else
formatSnippet(m_output, INDENT, code);
- m_output << endl;
+ m_output << Qt::endl;
}
}
void QtXmlToSphinx::handleDotsTag(QXmlStreamReader& reader)
@@ -930,16 +930,16 @@ void QtXmlToSphinx::handleListTag(QXmlStreamReader& reader)
switch (listType) {
case BulletList:
case OrderedList: {
- m_output << endl;
+ m_output << Qt::endl;
const char *separator = listType == BulletList ? "* " : "#. ";
const char *indent = listType == BulletList ? " " : " ";
for (const TableCell &cell : m_currentTable.constFirst()) {
const QVector<QStringRef> itemLines = cell.data.splitRef(QLatin1Char('\n'));
- m_output << INDENT << separator << itemLines.constFirst() << endl;
+ m_output << INDENT << separator << itemLines.constFirst() << Qt::endl;
for (int i = 1, max = itemLines.count(); i < max; ++i)
- m_output << INDENT << indent << itemLines[i] << endl;
+ m_output << INDENT << indent << itemLines[i] << Qt::endl;
}
- m_output << endl;
+ m_output << Qt::endl;
}
break;
case EnumeratedList:
@@ -1144,7 +1144,7 @@ void QtXmlToSphinx::handleImageTag(QXmlStreamReader& reader)
return;
const QString href = reader.attributes().value(QLatin1String("href")).toString();
if (copyImage(href))
- m_output << INDENT << ".. image:: " << href << endl << endl;
+ m_output << INDENT << ".. image:: " << href << Qt::endl << Qt::endl;
}
void QtXmlToSphinx::handleInlineImageTag(QXmlStreamReader& reader)
@@ -1174,13 +1174,13 @@ void QtXmlToSphinx::handleRawTag(QXmlStreamReader& reader)
QXmlStreamReader::TokenType token = reader.tokenType();
if (token == QXmlStreamReader::StartElement) {
QString format = reader.attributes().value(QLatin1String("format")).toString();
- m_output << INDENT << ".. raw:: " << format.toLower() << endl << endl;
+ m_output << INDENT << ".. raw:: " << format.toLower() << Qt::endl << Qt::endl;
} else if (token == QXmlStreamReader::Characters) {
const QVector<QStringRef> lst(reader.text().split(QLatin1Char('\n')));
for (const QStringRef &row : lst)
- m_output << INDENT << INDENT << row << endl;
+ m_output << INDENT << INDENT << row << Qt::endl;
} else if (token == QXmlStreamReader::EndElement) {
- m_output << endl << endl;
+ m_output << Qt::endl << Qt::endl;
}
}
@@ -1193,9 +1193,9 @@ void QtXmlToSphinx::handleCodeTag(QXmlStreamReader& reader)
} else if (token == QXmlStreamReader::Characters) {
const QVector<QStringRef> lst(reader.text().split(QLatin1Char('\n')));
for (const QStringRef &row : lst)
- m_output << INDENT << INDENT << row << endl;
+ m_output << INDENT << INDENT << row << Qt::endl;
} else if (token == QXmlStreamReader::EndElement) {
- m_output << endl << endl;
+ m_output << Qt::endl << Qt::endl;
INDENT.indent--;
}
}
@@ -1235,7 +1235,7 @@ void QtXmlToSphinx::handlePageTag(QXmlStreamReader &reader)
? writeEscapedRstText(m_output, title)
: writeEscapedRstText(m_output, fullTitle);
- m_output << endl << Pad('*', size) << endl << endl;
+ m_output << Qt::endl << Pad('*', size) << Qt::endl << Qt::endl;
}
void QtXmlToSphinx::handleTargetTag(QXmlStreamReader &reader)
@@ -1299,7 +1299,7 @@ void QtXmlToSphinx::handleQuoteFileTag(QXmlStreamReader& reader)
m_output << INDENT << "<Code snippet \"" << location << "\" not found>\n";
else
formatCode(m_output, code, INDENT);
- m_output << endl;
+ m_output << Qt::endl;
}
}
@@ -1435,7 +1435,7 @@ void QtXmlToSphinx::Table::format (QTextStream& s) const
c = '-';
s << Pad(c, colWidths.at(col)) << '+';
}
- s << endl;
+ s << Qt::endl;
// Print the table cells
@@ -1452,7 +1452,7 @@ void QtXmlToSphinx::Table::format (QTextStream& s) const
else
s << ' ';
if (rowLine < rowLines.count())
- s << qSetFieldWidth(colWidths[j]) << left << rowLines.at(rowLine) << qSetFieldWidth(0);
+ s << qSetFieldWidth(colWidths[j]) << Qt::left << rowLines.at(rowLine) << qSetFieldWidth(0);
else
s << Pad(' ', colWidths.at(j));
}
@@ -1461,7 +1461,7 @@ void QtXmlToSphinx::Table::format (QTextStream& s) const
s << "|\n";
}
}
- s << INDENT << horizontalLine << endl << endl;
+ s << INDENT << horizontalLine << Qt::endl << Qt::endl;
}
static QString getFuncName(const AbstractMetaFunction* cppFunc) {
@@ -1562,11 +1562,11 @@ void QtDocGenerator::writeFormattedText(QTextStream &s, const Documentation &doc
s << INDENT
<< (typesystemIndentation > 0 && typesystemIndentation < line.size()
? line.right(line.size() - typesystemIndentation) : line)
- << endl;
+ << Qt::endl;
}
}
- s << endl;
+ s << Qt::endl;
}
static void writeInheritedByList(QTextStream& s, const AbstractMetaClass* metaClass, const AbstractMetaClassList& allClasses)
@@ -1584,7 +1584,7 @@ static void writeInheritedByList(QTextStream& s, const AbstractMetaClass* metaCl
QStringList classes;
for (AbstractMetaClass *c : qAsConst(res))
classes << QLatin1String(":ref:`") + getClassTargetFullName(c, false) + QLatin1Char('`');
- s << classes.join(QLatin1String(", ")) << endl << endl;
+ s << classes.join(QLatin1String(", ")) << Qt::endl << Qt::endl;
}
// Extract the <brief> section from a WebXML (class) documentation and remove it
@@ -1625,15 +1625,15 @@ void QtDocGenerator::generateClass(QTextStream &s, GeneratorContext &classContex
s << ".. _" << className << ":" << "\n\n";
s << ".. currentmodule:: " << metaClass->package() << "\n\n\n";
- s << className << endl;
- s << Pad('*', className.count()) << endl << endl;
+ s << className << Qt::endl;
+ s << Pad('*', className.count()) << Qt::endl << Qt::endl;
auto documentation = metaClass->documentation();
Documentation brief;
if (extractBrief(&documentation, &brief))
writeFormattedText(s, brief, metaClass);
- s << ".. inheritance-diagram:: " << getClassTargetFullName(metaClass, true) << endl
+ s << ".. inheritance-diagram:: " << getClassTargetFullName(metaClass, true) << Qt::endl
<< " :parts: 2\n\n"; // TODO: This would be a parameter in the future...
@@ -1740,17 +1740,17 @@ void QtDocGenerator::writeFunctionList(QTextStream& s, const AbstractMetaClass*
void QtDocGenerator::writeFunctionBlock(QTextStream& s, const QString& title, QStringList& functions)
{
if (!functions.isEmpty()) {
- s << title << endl
- << QString(title.size(), QLatin1Char('^')) << endl;
+ s << title << Qt::endl
+ << QString(title.size(), QLatin1Char('^')) << Qt::endl;
std::sort(functions.begin(), functions.end());
s << ".. container:: function_list\n\n";
Indentation indentation(INDENT);
for (const QString &func : qAsConst(functions))
- s << INDENT << '*' << ' ' << func << endl;
+ s << INDENT << '*' << ' ' << func << Qt::endl;
- s << endl << endl;
+ s << Qt::endl << Qt::endl;
}
}
@@ -1760,7 +1760,7 @@ void QtDocGenerator::writeEnums(QTextStream& s, const AbstractMetaClass* cppClas
const AbstractMetaEnumList &enums = cppClass->enums();
for (AbstractMetaEnum *en : enums) {
- s << section_title << getClassTargetFullName(cppClass) << '.' << en->name() << endl << endl;
+ s << section_title << getClassTargetFullName(cppClass) << '.' << en->name() << Qt::endl << Qt::endl;
writeFormattedText(s, en->documentation(), cppClass);
const auto version = versionOf(en->typeEntry());
if (!version.isNull())
@@ -1775,7 +1775,7 @@ void QtDocGenerator::writeFields(QTextStream& s, const AbstractMetaClass* cppCla
const AbstractMetaFieldList &fields = cppClass->fields();
for (AbstractMetaField *field : fields) {
- s << section_title << getClassTargetFullName(cppClass) << "." << field->name() << endl << endl;
+ s << section_title << getClassTargetFullName(cppClass) << "." << field->name() << Qt::endl << Qt::endl;
//TODO: request for member ‘documentation’ is ambiguous
writeFormattedText(s, field->AbstractMetaAttributes::documentation(), cppClass);
}
@@ -1819,14 +1819,14 @@ void QtDocGenerator::writeConstructors(QTextStream& s, const AbstractMetaClass*
}
}
- s << endl;
+ s << Qt::endl;
for (QHash<QString, AbstractMetaArgument*>::const_iterator it = arg_map.cbegin(), end = arg_map.cend(); it != end; ++it) {
Indentation indentation(INDENT, 2);
writeParameterType(s, cppClass, it.value());
}
- s << endl;
+ s << Qt::endl;
for (AbstractMetaFunction *func : qAsConst(lst))
writeFormattedText(s, func->documentation(), cppClass);
@@ -1917,7 +1917,7 @@ void QtDocGenerator::writeDocSnips(QTextStream &s,
if (row.trimmed().size() == 0) {
if (currentRow == 0)
continue;
- s << endl;
+ s << Qt::endl;
}
if (currentRow == 0) {
@@ -1931,7 +1931,7 @@ void QtDocGenerator::writeDocSnips(QTextStream &s,
break;
}
}
- s << row.midRef(offset) << endl;
+ s << row.midRef(offset) << Qt::endl;
currentRow++;
}
@@ -1971,7 +1971,7 @@ bool QtDocGenerator::writeInjectDocumentation(QTextStream& s,
}
}
- s << endl;
+ s << Qt::endl;
// TODO: Deprecate the use of doc string on glue code.
// This is pre "add-function" and "inject-documentation" tags.
@@ -2046,13 +2046,13 @@ QString QtDocGenerator::translateToPythonType(const AbstractMetaType* type, cons
void QtDocGenerator::writeParameterType(QTextStream& s, const AbstractMetaClass* cppClass, const AbstractMetaArgument* arg)
{
s << INDENT << ":param " << arg->name() << ": "
- << translateToPythonType(arg->type(), cppClass) << endl;
+ << translateToPythonType(arg->type(), cppClass) << Qt::endl;
}
void QtDocGenerator::writeFunctionParametersType(QTextStream &s, const AbstractMetaClass *cppClass,
const AbstractMetaFunction *func)
{
- s << endl;
+ s << Qt::endl;
const AbstractMetaArgumentList &funcArgs = func->arguments();
for (AbstractMetaArgument *arg : funcArgs) {
@@ -2078,9 +2078,9 @@ void QtDocGenerator::writeFunctionParametersType(QTextStream &s, const AbstractM
if (retType.isEmpty())
retType = translateToPythonType(func->type(), cppClass);
- s << INDENT << ":rtype: " << retType << endl;
+ s << INDENT << ":rtype: " << retType << Qt::endl;
}
- s << endl;
+ s << Qt::endl;
}
void QtDocGenerator::writeFunction(QTextStream& s, const AbstractMetaClass* cppClass,
@@ -2134,7 +2134,7 @@ static void writeFancyToc(QTextStream& s, const QStringList& items, int cols = 4
std::sort(it.value().begin(), it.value().end());
if (i)
- ss << endl;
+ ss << Qt::endl;
ss << "**" << it.key() << "**\n\n";
i += 2; // a letter title is equivalent to two entries in space
@@ -2184,11 +2184,11 @@ void QtDocGenerator::writeModuleDocumentation()
FileOut output(outputDir + QLatin1String("/index.rst"));
QTextStream& s = output.stream;
- s << ".. module:: " << it.key() << endl << endl;
+ s << ".. module:: " << it.key() << Qt::endl << Qt::endl;
const QString &title = it.key();
- s << title << endl;
- s << Pad('*', title.length()) << endl << endl;
+ s << title << Qt::endl;
+ s << Pad('*', title.length()) << Qt::endl << Qt::endl;
/* Avoid showing "Detailed Description for *every* class in toc tree */
Indentation indentation(INDENT);
@@ -2230,8 +2230,8 @@ void QtDocGenerator::writeModuleDocumentation()
Indentation deeperIndentation(INDENT);
s << INDENT << ":maxdepth: 1\n\n";
for (const QString &className : qAsConst(it.value()))
- s << INDENT << className << endl;
- s << endl << endl;
+ s << INDENT << className << Qt::endl;
+ s << Qt::endl << Qt::endl;
}
s << "Detailed Description\n--------------------\n\n";
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index 6b29272e0..9e7b96c7f 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -44,8 +44,7 @@
#include <QMetaType>
#include <algorithm>
-
-#include <algorithm>
+#include <cstring>
static const char CPP_ARG0[] = "cppArg0";
@@ -300,7 +299,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
qCDebug(lcShiboken) << "Generating wrapper implementation for " << metaClass->fullName();
// write license comment
- s << licenseComment() << endl;
+ s << licenseComment() << Qt::endl;
if (!avoidProtectedHack() && !metaClass->isNamespace() && !metaClass->hasPrivateDestructor()) {
s << "//workaround to access protected functions\n";
@@ -339,11 +338,11 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
headerfile.replace(QLatin1String(".cpp"), QLatin1String(".h"));
s << "\n// main header\n" << "#include \"" << headerfile << "\"\n";
- s << endl << "// inner classes\n";
+ s << Qt::endl << "// inner classes\n";
const AbstractMetaClassList &innerClasses = metaClass->innerClasses();
for (AbstractMetaClass *innerClass : innerClasses) {
GeneratorContext innerClassContext(innerClass);
- if (shouldGenerate(innerClass)) {
+ if (shouldGenerate(innerClass) && !innerClass->typeEntry()->isSmartPointer()) {
QString headerfile = fileNameForContext(innerClassContext);
headerfile.replace(QLatin1String(".cpp"), QLatin1String(".h"));
s << "#include \"" << headerfile << "\"\n";
@@ -361,8 +360,8 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
includes.append(cppEnum->typeEntry()->extraIncludes());
std::sort(includes.begin(), includes.end());
for (const Include &inc : qAsConst(includes))
- s << inc.toString() << endl;
- s << endl;
+ s << inc.toString() << Qt::endl;
+ s << Qt::endl;
s << "\n#include <cctype>\n#include <cstring>\n";
@@ -381,7 +380,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
}
}
- s << endl << endl << typeNameFunc << endl;
+ s << Qt::endl << Qt::endl << typeNameFunc << Qt::endl;
// Create string literal for smart pointer getter method.
if (classContext.forSmartPointer()) {
@@ -395,13 +394,13 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
// class inject-code native/beginning
if (!metaClass->typeEntry()->codeSnips().isEmpty()) {
writeCodeSnips(s, metaClass->typeEntry()->codeSnips(), TypeSystem::CodeSnipPositionBeginning, TypeSystem::NativeCode, metaClass);
- s << endl;
+ s << Qt::endl;
}
// python conversion rules
if (metaClass->typeEntry()->hasTargetConversionRule()) {
s << "// Python Conversion\n";
- s << metaClass->typeEntry()->conversionRule() << endl;
+ s << metaClass->typeEntry()->conversionRule() << Qt::endl;
}
if (shouldGenerateCppWrapper(metaClass)) {
@@ -553,7 +552,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
// Write methods definition
s << "static PyMethodDef " << className << "_methods[] = {\n";
- s << methodsDefinitions << endl;
+ s << methodsDefinitions << Qt::endl;
if (metaClass->typeEntry()->isValue() || metaClass->typeEntry()->isSmartPointer()) {
s << INDENT << "{\"__copy__\", reinterpret_cast<PyCFunction>(" << className << "___copy__)"
<< ", METH_NOARGS},\n";
@@ -580,9 +579,9 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
writeCppSelfDefinition(s, classContext);
if (f->allowThread()) {
s << INDENT << "int result;\n";
- s << INDENT << BEGIN_ALLOW_THREADS << endl;
+ s << INDENT << BEGIN_ALLOW_THREADS << Qt::endl;
s << INDENT << "result = !" << CPP_SELF_VAR << "->isNull();\n";
- s << INDENT << END_ALLOW_THREADS << endl;
+ s << INDENT << END_ALLOW_THREADS << Qt::endl;
s << INDENT << "return result;\n";
} else {
s << INDENT << "return !" << CPP_SELF_VAR << "->isNull();\n";
@@ -635,10 +634,10 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
writeGetterFunction(s, metaField, classContext);
if (canGenerateFieldSetter(metaField))
writeSetterFunction(s, metaField, classContext);
- s << endl;
+ s << Qt::endl;
}
- s << "// Getters and Setters for " << metaClass->name() << endl;
+ s << "// Getters and Setters for " << metaClass->name() << Qt::endl;
s << "static PyGetSetDef " << cpythonGettersSettersDefinitionName(metaClass) << "[] = {\n";
for (const AbstractMetaField *metaField : fields) {
if (metaField->isStatic())
@@ -666,7 +665,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
writeTpClearFunction(s, metaClass);
writeClassDefinition(s, metaClass, classContext);
- s << endl;
+ s << Qt::endl;
if (metaClass->isPolymorphic() && metaClass->baseClass())
writeTypeDiscoveryFunction(s, metaClass);
@@ -680,10 +679,10 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
if (hasFlags) {
writeFlagsMethods(s, cppEnum);
writeFlagsNumberMethodsDefinition(s, cppEnum);
- s << endl;
+ s << Qt::endl;
}
}
- s << endl;
+ s << Qt::endl;
writeConverterFunctions(s, metaClass, classContext);
writeClassRegister(s, metaClass, classContext, signatureStream);
@@ -691,7 +690,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
// class inject-code native/end
if (!metaClass->typeEntry()->codeSnips().isEmpty()) {
writeCodeSnips(s, metaClass->typeEntry()->codeSnips(), TypeSystem::CodeSnipPositionEnd, TypeSystem::NativeCode, metaClass);
- s << endl;
+ s << Qt::endl;
}
}
@@ -750,11 +749,14 @@ QString CppGenerator::getVirtualFunctionReturnTypeName(const AbstractMetaFunctio
return QLatin1Char('"') + func->typeReplaced(0) + QLatin1Char('"');
// SbkType would return null when the type is a container.
- if (func->type()->typeEntry()->isContainer()) {
+ auto typeEntry = func->type()->typeEntry();
+ if (typeEntry->isContainer()) {
return QLatin1Char('"')
- + reinterpret_cast<const ContainerTypeEntry *>(func->type()->typeEntry())->typeName()
+ + reinterpret_cast<const ContainerTypeEntry *>(typeEntry)->typeName()
+ QLatin1Char('"');
}
+ if (typeEntry->isSmartPointer())
+ return QLatin1Char('"') + typeEntry->qualifiedCppName() + QLatin1Char('"');
if (avoidProtectedHack()) {
const AbstractMetaEnum *metaEnum = findAbstractMetaEnum(func->type());
@@ -765,7 +767,8 @@ QString CppGenerator::getVirtualFunctionReturnTypeName(const AbstractMetaFunctio
if (func->type()->isPrimitive())
return QLatin1Char('"') + func->type()->name() + QLatin1Char('"');
- return QString::fromLatin1("reinterpret_cast<PyTypeObject *>(Shiboken::SbkType< %1 >())->tp_name").arg(func->type()->typeEntry()->qualifiedCppName());
+ return QLatin1String("reinterpret_cast<PyTypeObject *>(Shiboken::SbkType< ")
+ + typeEntry->qualifiedCppName() + QLatin1String(" >())->tp_name");
}
void CppGenerator::writeVirtualMethodNative(QTextStream &s,
@@ -821,7 +824,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
errorMsg += func->signature();
errorMsg = msgCouldNotFindMinimalConstructor(errorMsg, func->type()->cppSignature());
qCWarning(lcShiboken).noquote().nospace() << errorMsg;
- s << endl << INDENT << "#error " << errorMsg << endl;
+ s << Qt::endl << INDENT << "#error " << errorMsg << Qt::endl;
}
} else {
defaultReturnExpr.setType(DefaultValue::Void);
@@ -832,7 +835,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
<< QString::fromLatin1("Pure virtual method '%1::%2' must be implement but was "\
"completely removed on type system.")
.arg(func->ownerClass()->name(), func->minimalSignature());
- s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << endl;
+ s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << Qt::endl;
s << "}\n\n";
return;
}
@@ -842,7 +845,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
CodeSnipList snips = func->injectedCodeSnips();
const AbstractMetaArgument *lastArg = func->arguments().isEmpty() ? nullptr : func->arguments().constLast();
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionDeclaration, TypeSystem::NativeCode, func, lastArg);
- s << endl;
+ s << Qt::endl;
}
// PYSIDE-803: Build a boolean cache for unused overrides.
@@ -873,7 +876,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
s << INDENT << "if (PyErr_Occurred())\n";
{
Indentation indentation(INDENT);
- s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << endl;
+ s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << Qt::endl;
}
s << INDENT << "Shiboken::AutoDecRef " << PYTHON_OVERRIDE_VAR << "(Shiboken::BindingManager::instance().getOverride(this, \"";
@@ -887,7 +890,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
snips = func->injectedCodeSnips();
const AbstractMetaArgument *lastArg = func->arguments().isEmpty() ? nullptr : func->arguments().constLast();
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, TypeSystem::ShellCode, func, lastArg);
- s << endl;
+ s << Qt::endl;
}
if (func->isAbstract()) {
@@ -962,7 +965,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
}
s << "Py_BuildValue(\"(" << getFormatUnitString(func, false) << ")\",\n";
- s << argConversions.join(QLatin1String(",\n")) << endl;
+ s << argConversions.join(QLatin1String(",\n")) << Qt::endl;
s << INDENT << "));\n";
}
@@ -980,7 +983,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
}
}
}
- s << endl;
+ s << Qt::endl;
CodeSnipList snips;
if (func->hasInjectedCode()) {
@@ -991,7 +994,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
const AbstractMetaArgument *lastArg = func->arguments().isEmpty() ? nullptr : func->arguments().constLast();
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, TypeSystem::NativeCode, func, lastArg);
- s << endl;
+ s << Qt::endl;
}
if (!injectedCodeCallsPythonOverride(func)) {
@@ -1004,7 +1007,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
{
Indentation indent(INDENT);
s << INDENT << "PyErr_Print();\n";
- s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << endl;
+ s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << Qt::endl;
}
s << INDENT << "}\n";
@@ -1026,7 +1029,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
"\"Invalid return value in function %s, expected %s, got %s.\", \"";
s << func->ownerClass()->name() << '.' << funcName << "\", " << getVirtualFunctionReturnTypeName(func);
s << ", Py_TYPE(" << PYTHON_RETURN_VAR << ")->tp_name);\n";
- s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << endl;
+ s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << Qt::endl;
}
s << INDENT << "}\n";
@@ -1047,7 +1050,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
"\"Invalid return value in function %s, expected %s, got %s.\", \"";
s << func->ownerClass()->name() << '.' << funcName << "\", " << getVirtualFunctionReturnTypeName(func);
s << ", Py_TYPE(" << PYTHON_RETURN_VAR << ")->tp_name);\n";
- s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << endl;
+ s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << Qt::endl;
}
s << INDENT << "}\n";
@@ -1090,7 +1093,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
}
if (func->hasInjectedCode()) {
- s << endl;
+ s << Qt::endl;
const AbstractMetaArgument *lastArg = func->arguments().isEmpty() ? nullptr : func->arguments().constLast();
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionEnd, TypeSystem::NativeCode, func, lastArg);
}
@@ -1215,7 +1218,7 @@ void CppGenerator::writeEnumConverterFunctions(QTextStream &s, const TypeEntry *
}
c << ";\n";
writeCppToPythonFunction(s, code, typeName, typeName);
- s << endl;
+ s << Qt::endl;
if (enumType->isFlags())
return;
@@ -1295,7 +1298,7 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla
const QString pyTypeCheck = QLatin1String("PyObject_TypeCheck(pyIn, reinterpret_cast<PyTypeObject *>(")
+ cpythonType + QLatin1String("))");
writeIsPythonConvertibleToCppFunction(s, sourceTypeName, targetTypeName, pyTypeCheck, QString(), true);
- s << endl;
+ s << Qt::endl;
// C++ pointer to a Python wrapper, keeping identity.
s << "// C++ to Python pointer conversion - tries to find the Python wrapper for the C++ object (keeps object identity).\n";
@@ -1332,12 +1335,12 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla
// The conversions for an Object Type end here.
if (!metaClass->typeEntry()->isValue() && !metaClass->typeEntry()->isSmartPointer()) {
- s << endl;
+ s << Qt::endl;
return;
}
// Always copies C++ value (not pointer, and not reference) to a new Python wrapper.
- s << endl << "// C++ to Python copy conversion.\n";
+ s << Qt::endl << "// C++ to Python copy conversion.\n";
if (!classContext.forSmartPointer())
targetTypeName = metaClass->name();
else
@@ -1357,7 +1360,7 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla
<< ", new ::" << computedWrapperName << "(*reinterpret_cast<const "
<< typeName << " *>(cppIn)), true, true);";
writeCppToPythonFunction(s, code, sourceTypeName, targetTypeName);
- s << endl;
+ s << Qt::endl;
// Python to C++ copy conversion.
s << "// Python to C++ copy conversion.\n";
@@ -1382,7 +1385,7 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla
// "Is convertible" function for the Python object to C++ value copy conversion.
writeIsPythonConvertibleToCppFunction(s, sourceTypeName, targetTypeName, pyTypeCheck);
- s << endl;
+ s << Qt::endl;
// User provided implicit conversions.
CustomConversion *customConversion = metaClass->typeEntry()->customConversion();
@@ -1477,7 +1480,7 @@ void CppGenerator::writeCustomConverterFunctions(QTextStream &s, const CustomCon
s << "// Python to C++ conversions for type '" << customConversion->ownerType()->qualifiedCppName() << "'.\n";
for (CustomConversion::TargetToNativeConversion *toNative : toCppConversions)
writePythonToCppConversionFunctions(s, toNative, customConversion->ownerType());
- s << endl;
+ s << Qt::endl;
}
void CppGenerator::writeConverterRegister(QTextStream &s, const AbstractMetaClass *metaClass,
@@ -1487,24 +1490,24 @@ void CppGenerator::writeConverterRegister(QTextStream &s, const AbstractMetaClas
return;
s << INDENT << "// Register Converter\n";
s << INDENT << "SbkConverter *converter = Shiboken::Conversions::createConverter(";
- s << cpythonTypeName(metaClass) << ',' << endl;
+ s << cpythonTypeName(metaClass) << ',' << Qt::endl;
{
Indentation indent(INDENT);
QString sourceTypeName = metaClass->name();
QString targetTypeName = sourceTypeName + QLatin1String("_PTR");
- s << INDENT << pythonToCppFunctionName(sourceTypeName, targetTypeName) << ',' << endl;
- s << INDENT << convertibleToCppFunctionName(sourceTypeName, targetTypeName) << ',' << endl;
+ s << INDENT << pythonToCppFunctionName(sourceTypeName, targetTypeName) << ',' << Qt::endl;
+ s << INDENT << convertibleToCppFunctionName(sourceTypeName, targetTypeName) << ',' << Qt::endl;
std::swap(targetTypeName, sourceTypeName);
s << INDENT << cppToPythonFunctionName(sourceTypeName, targetTypeName);
if (metaClass->typeEntry()->isValue() || metaClass->typeEntry()->isSmartPointer()) {
- s << ',' << endl;
+ s << ',' << Qt::endl;
sourceTypeName = metaClass->name() + QLatin1String("_COPY");
s << INDENT << cppToPythonFunctionName(sourceTypeName, targetTypeName);
}
}
s << ");\n";
- s << endl;
+ s << Qt::endl;
QStringList cppSignature;
if (!classContext.forSmartPointer()) {
@@ -1536,7 +1539,7 @@ void CppGenerator::writeConverterRegister(QTextStream &s, const AbstractMetaClas
s << wrapperName(metaClass) << ").name());\n";
}
- s << endl;
+ s << Qt::endl;
if (!metaClass->typeEntry()->isValue() && !metaClass->typeEntry()->isSmartPointer())
return;
@@ -1631,7 +1634,7 @@ void CppGenerator::writeMethodWrapperPreamble(QTextStream &s, OverloadData &over
s << qualifiedCppName << " >()))\n";
Indentation indent(INDENT);
- s << INDENT << returnStatement(m_currentErrorCode) << endl << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl << Qt::endl;
}
// Declare pointer for the underlying C++ object.
s << INDENT << "::";
@@ -1736,7 +1739,7 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
s << INDENT << "\"'" << metaClass->qualifiedCppName();
}
s << "' represents a C++ abstract class and cannot be instantiated\");\n";
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
s << INDENT<< "}\n\n";
}
@@ -1755,24 +1758,24 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
writeMethodWrapperPreamble(s, overloadData, classContext);
- s << endl;
+ s << Qt::endl;
if (overloadData.maxArgs() > 0)
writeOverloadedFunctionDecisor(s, overloadData);
writeFunctionCalls(s, overloadData, classContext);
- s << endl;
+ s << Qt::endl;
s << INDENT << "if (PyErr_Occurred() || !Shiboken::Object::setCppPointer(sbkSelf, Shiboken::SbkType< ::" << metaClass->qualifiedCppName() << " >(), cptr)) {\n";
{
Indentation indent(INDENT);
s << INDENT << "delete cptr;\n";
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
s << INDENT << "}\n";
if (overloadData.maxArgs() > 0) {
s << INDENT << "if (!cptr) goto " << cpythonFunctionName(rfunc) << "_TypeError;\n";
- s << endl;
+ s << Qt::endl;
}
s << INDENT << "Shiboken::Object::setValidCpp(sbkSelf, true);\n";
@@ -1794,13 +1797,13 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
// Create metaObject and register signal/slot
if (metaClass->isQObject() && usePySideExtensions()) {
- s << endl << INDENT << "// QObject setup\n";
+ s << Qt::endl << INDENT << "// QObject setup\n";
s << INDENT << "PySide::Signal::updateSourceObject(self);\n";
s << INDENT << "metaObject = cptr->metaObject(); // <- init python qt properties\n";
s << INDENT << "if (kwds && !PySide::fillQtProperties(self, metaObject, kwds, argNames, " << argNamesSet.count() << "))\n";
{
Indentation indentation(INDENT);
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
}
@@ -1823,7 +1826,7 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
const CodeSnipList &injectedCodeSnips = func->injectedCodeSnips();
for (const CodeSnip &cs : injectedCodeSnips) {
if (cs.position == TypeSystem::CodeSnipPositionEnd) {
- s << INDENT << "case " << metaClass->functions().indexOf(func) << ':' << endl;
+ s << INDENT << "case " << metaClass->functions().indexOf(func) << ':' << Qt::endl;
s << INDENT << "{\n";
{
Indentation indent(INDENT);
@@ -1837,8 +1840,8 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
s << "}\n";
}
- s << endl;
- s << endl << INDENT << "return 1;\n";
+ s << Qt::endl;
+ s << Qt::endl << INDENT << "return 1;\n";
if (overloadData.maxArgs() > 0)
writeErrorSection(s, overloadData);
s<< "}\n\n";
@@ -1863,7 +1866,7 @@ void CppGenerator::writeMethodWrapper(QTextStream &s, const AbstractMetaFunction
writeMethodWrapperPreamble(s, overloadData, classContext);
- s << endl;
+ s << Qt::endl;
/*
* This code is intended for shift operations only:
@@ -1926,9 +1929,9 @@ void CppGenerator::writeMethodWrapper(QTextStream &s, const AbstractMetaFunction
writeFunctionCalls(s, overloadData, classContext);
if (callExtendedReverseOperator)
- s << endl << INDENT << "} // End of \"if (!" << PYTHON_RETURN_VAR << ")\"\n";
+ s << Qt::endl << INDENT << "} // End of \"if (!" << PYTHON_RETURN_VAR << ")\"\n";
- s << endl;
+ s << Qt::endl;
writeFunctionReturnErrorCheckSection(s, hasReturnValue && !rfunc->isInplaceOperator());
@@ -1962,7 +1965,7 @@ void CppGenerator::writeArgumentsInitializer(QTextStream &s, OverloadData &overl
s << PYTHON_ARGS << "[] = {"
<< QString(maxArgs, QLatin1Char('0')).split(QLatin1String(""), Qt::SkipEmptyParts).join(QLatin1String(", "))
<< "};\n";
- s << endl;
+ s << Qt::endl;
if (overloadData.hasVarargs()) {
maxArgs--;
@@ -1973,7 +1976,7 @@ void CppGenerator::writeArgumentsInitializer(QTextStream &s, OverloadData &overl
s << INDENT << "Shiboken::AutoDecRef auto_nonvarargs(nonvarargs);\n";
s << INDENT << PYTHON_ARGS << '[' << maxArgs << "] = PyTuple_GetSlice(args, " << maxArgs << ", numArgs);\n";
s << INDENT << "Shiboken::AutoDecRef auto_varargs(" << PYTHON_ARGS << "[" << maxArgs << "]);\n";
- s << endl;
+ s << Qt::endl;
}
bool usesNamedArguments = overloadData.hasArgumentWithDefaultValue();
@@ -1986,7 +1989,7 @@ void CppGenerator::writeArgumentsInitializer(QTextStream &s, OverloadData &overl
{
Indentation indent(INDENT);
s << INDENT << "PyErr_SetString(PyExc_TypeError, \"" << fullPythonFunctionName(rfunc) << "(): too many arguments\");\n";
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
s << INDENT << '}';
}
@@ -1999,7 +2002,7 @@ void CppGenerator::writeArgumentsInitializer(QTextStream &s, OverloadData &overl
{
Indentation indent(INDENT);
s << INDENT << "PyErr_SetString(PyExc_TypeError, \"" << fullPythonFunctionName(rfunc) << "(): not enough arguments\");\n";
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
s << INDENT << '}';
}
@@ -2017,7 +2020,7 @@ void CppGenerator::writeArgumentsInitializer(QTextStream &s, OverloadData &overl
Indentation indent(INDENT);
s << INDENT << "goto " << cpythonFunctionName(rfunc) << "_TypeError;";
}
- s << endl << endl;
+ s << Qt::endl << Qt::endl;
QString funcName;
if (rfunc->isOperatorOverload())
@@ -2036,9 +2039,9 @@ void CppGenerator::writeArgumentsInitializer(QTextStream &s, OverloadData &overl
s << "))\n";
{
Indentation indent(INDENT);
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
- s << endl;
+ s << Qt::endl;
}
void CppGenerator::writeCppSelfAssigment(QTextStream &s, const GeneratorContext &context,
@@ -2128,7 +2131,7 @@ void CppGenerator::writeCppSelfDefinition(QTextStream &s,
void CppGenerator::writeErrorSection(QTextStream &s, OverloadData &overloadData)
{
const AbstractMetaFunction *rfunc = overloadData.referenceFunction();
- s << endl << INDENT << cpythonFunctionName(rfunc) << "_TypeError:\n";
+ s << Qt::endl << INDENT << cpythonFunctionName(rfunc) << "_TypeError:\n";
Indentation indentation(INDENT);
QString funcName = fullPythonFunctionName(rfunc);
@@ -2148,7 +2151,7 @@ void CppGenerator::writeFunctionReturnErrorCheckSection(QTextStream &s, bool has
Indentation indent(INDENT);
if (hasReturnValue)
s << INDENT << "Py_XDECREF(" << PYTHON_RETURN_VAR << ");\n";
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
s << INDENT << "}\n";
}
@@ -2157,7 +2160,7 @@ void CppGenerator::writeInvalidPyObjectCheck(QTextStream &s, const QString &pyOb
{
s << INDENT << "if (!Shiboken::Object::isValid(" << pyObj << "))\n";
Indentation indent(INDENT);
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
static QString pythonToCppConverterForArgumentName(const QString &argumentName)
@@ -2423,7 +2426,7 @@ void CppGenerator::writePythonToCppTypeConversion(QTextStream &s,
if (!defaultValue.isEmpty())
s << INDENT << '}';
- s << endl;
+ s << Qt::endl;
}
static void addConversionRuleCodeSnippet(CodeSnipList &snippetList, QString &rule,
@@ -2486,10 +2489,10 @@ void CppGenerator::writeOverloadedFunctionDecisor(QTextStream &s, const Overload
s << "static ";
if (const auto *decl = func->declaringClass())
s << decl->name() << "::";
- s << func->minimalSignature() << endl;
+ s << func->minimalSignature() << Qt::endl;
}
writeOverloadedFunctionDecisorEngine(s, &overloadData);
- s << endl;
+ s << Qt::endl;
// Ensure that the direct overload that called this reverse
// is called.
@@ -2505,7 +2508,7 @@ void CppGenerator::writeOverloadedFunctionDecisor(QTextStream &s, const Overload
s << INDENT << "// Function signature not found.\n";
s << INDENT << "if (overloadId == -1) goto " << cpythonFunctionName(overloadData.referenceFunction()) << "_TypeError;\n";
- s << endl;
+ s << Qt::endl;
}
void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream &s, const OverloadData *parentOverloadData)
@@ -2536,7 +2539,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream &s, const Ov
// Functions without arguments are identified right away.
if (maxArgs == 0) {
s << INDENT << "overloadId = " << parentOverloadData->headOverloadData()->overloads().indexOf(referenceFunction);
- s << "; // " << referenceFunction->minimalSignature() << endl;
+ s << "; // " << referenceFunction->minimalSignature() << Qt::endl;
return;
}
@@ -2552,7 +2555,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream &s, const Ov
if (isLastArgument || (signatureFound && !hasDefaultCall)) {
const AbstractMetaFunction *func = parentOverloadData->referenceFunction();
s << INDENT << "overloadId = " << parentOverloadData->headOverloadData()->overloads().indexOf(func);
- s << "; // " << func->minimalSignature() << endl;
+ s << "; // " << func->minimalSignature() << Qt::endl;
return;
}
}
@@ -2578,7 +2581,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream &s, const Ov
}
}
s << INDENT << "overloadId = " << parentOverloadData->headOverloadData()->overloads().indexOf(func);
- s << "; // " << func->minimalSignature() << endl;
+ s << "; // " << func->minimalSignature() << Qt::endl;
}
s << INDENT << '}';
}
@@ -2635,9 +2638,11 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream &s, const Ov
if (usePyArgs && signatureFound) {
AbstractMetaArgumentList args = refFunc->arguments();
- int lastArgIsVarargs = (int) (args.size() > 1 && args.constLast()->type()->isVarargs());
- int numArgs = args.size() - OverloadData::numberOfRemovedArguments(refFunc) - lastArgIsVarargs;
- typeChecks.prepend(QString::fromLatin1("numArgs %1 %2").arg(lastArgIsVarargs ? QLatin1String(">=") : QLatin1String("==")).arg(numArgs));
+ const bool isVarargs = args.size() > 1 && args.constLast()->type()->isVarargs();
+ int numArgs = args.size() - OverloadData::numberOfRemovedArguments(refFunc);
+ if (isVarargs)
+ --numArgs;
+ typeChecks.prepend(QString::fromLatin1("numArgs %1 %2").arg(isVarargs ? QLatin1String(">=") : QLatin1String("==")).arg(numArgs));
} else if (sequenceArgCount > 1) {
typeChecks.prepend(QString::fromLatin1("numArgs >= %1").arg(startArg + sequenceArgCount));
} else if (refFunc->isOperatorOverload() && !refFunc->isCallOperator()) {
@@ -2657,7 +2662,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream &s, const Ov
Indentation indent(INDENT);
QString separator;
QTextStream sep(&separator);
- sep << endl << INDENT << "&& ";
+ sep << Qt::endl << INDENT << "&& ";
s << typeChecks.join(separator);
}
s << ") {\n";
@@ -2667,7 +2672,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream &s, const Ov
}
s << INDENT << "}";
}
- s << endl;
+ s << Qt::endl;
}
void CppGenerator::writeFunctionCalls(QTextStream &s, const OverloadData &overloadData,
@@ -2683,7 +2688,7 @@ void CppGenerator::writeFunctionCalls(QTextStream &s, const OverloadData &overlo
} else {
for (int i = 0; i < overloads.count(); i++) {
const AbstractMetaFunction *func = overloads.at(i);
- s << INDENT << "case " << i << ": // " << func->signature() << endl;
+ s << INDENT << "case " << i << ": // " << func->signature() << Qt::endl;
s << INDENT << "{\n";
{
Indentation indent(INDENT);
@@ -2718,7 +2723,7 @@ void CppGenerator::writeSingleFunctionCall(QTextStream &s,
s << INDENT << "PyErr_Format(PyExc_TypeError, \"%s is a private method.\", \""
<< func->signature().replace(QLatin1String("::"), QLatin1String("."))
<< "\");\n";
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
return;
}
@@ -2761,7 +2766,7 @@ void CppGenerator::writeSingleFunctionCall(QTextStream &s,
writeArgumentConversion(s, argType, argName, pyArgName, func->implementingClass(), defaultValue, func->isUserAdded());
}
- s << endl;
+ s << Qt::endl;
int numRemovedArgs = OverloadData::numberOfRemovedArguments(func);
@@ -2916,7 +2921,7 @@ void CppGenerator::writePythonToCppConversionFunctions(QTextStream &s,
if (conversion.isEmpty())
conversion = QLatin1Char('*') + cpythonWrapperCPtr(sourceType->typeEntry(), QLatin1String("pyIn"));
if (!preConversion.isEmpty())
- c << INDENT << preConversion << endl;
+ c << INDENT << preConversion << Qt::endl;
const QString fullTypeName = getFullTypeName(targetType->typeEntry());
c << INDENT << "*reinterpret_cast<" << fullTypeName << " *>(cppOut) = "
<< fullTypeName << '(' << conversion << ");";
@@ -2928,7 +2933,7 @@ void CppGenerator::writePythonToCppConversionFunctions(QTextStream &s,
if (typeCheck.isEmpty())
typeCheck = QString::fromLatin1("PyObject_TypeCheck(pyIn, %1)").arg(sourcePyType);
writeIsPythonConvertibleToCppFunction(s, sourceTypeName, targetTypeName, typeCheck);
- s << endl;
+ s << Qt::endl;
}
void CppGenerator::writePythonToCppConversionFunctions(QTextStream &s,
@@ -3036,15 +3041,15 @@ void CppGenerator::writePythonToCppConversionFunctions(QTextStream &s, const Abs
else
typeCheck = QString::fromLatin1("%1pyIn)").arg(typeCheck);
writeIsPythonConvertibleToCppFunction(s, typeName, typeName, typeCheck);
- s << endl;
+ s << Qt::endl;
}
void CppGenerator::writeAddPythonToCppConversion(QTextStream &s, const QString &converterVar, const QString &pythonToCppFunc, const QString &isConvertibleFunc)
{
- s << INDENT << "Shiboken::Conversions::addPythonToCppValueConversion(" << converterVar << ',' << endl;
+ s << INDENT << "Shiboken::Conversions::addPythonToCppValueConversion(" << converterVar << ',' << Qt::endl;
{
Indentation indent(INDENT);
- s << INDENT << pythonToCppFunc << ',' << endl;
+ s << INDENT << pythonToCppFunc << ',' << Qt::endl;
s << INDENT << isConvertibleFunc;
}
s << ");\n";
@@ -3075,8 +3080,8 @@ void CppGenerator::writeNamedArgumentResolution(QTextStream &s, const AbstractMe
s << INDENT << "if (value && " << pyArgName << ") {\n";
{
Indentation indent(INDENT);
- s << INDENT << pyErrString.arg(arg->name()) << endl;
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << pyErrString.arg(arg->name()) << Qt::endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
s << INDENT << "}\n";
s << INDENT << "if (value) {\n";
@@ -3151,7 +3156,7 @@ static QStringList defaultExceptionHandling()
void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *func,
GeneratorContext &context, int maxArgs)
{
- s << INDENT << "// " << func->minimalSignature() << (func->isReverseOperator() ? " [reverse operator]": "") << endl;
+ s << INDENT << "// " << func->minimalSignature() << (func->isReverseOperator() ? " [reverse operator]": "") << Qt::endl;
if (func->isConstructor()) {
const CodeSnipList &snips = func->injectedCodeSnips();
for (const CodeSnip &cs : snips) {
@@ -3168,7 +3173,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
Indentation indent(INDENT);
s << INDENT << "PyErr_SetString(PyExc_NotImplementedError, \"pure virtual method '";
s << func->ownerClass()->name() << '.' << func->name() << "()' not implemented.\");\n";
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
s << INDENT << "}\n";
}
@@ -3195,7 +3200,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
}
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, TypeSystem::TargetLangCode, func, lastArg);
- s << endl;
+ s << Qt::endl;
}
writeConversionRule(s, func, TypeSystem::NativeCode);
@@ -3280,14 +3285,14 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
std::swap(firstArg, secondArg);
QString op = func->originalName();
- op = op.right(op.size() - (sizeof("operator")/sizeof(char)-1));
+ op.remove(0, int(std::strlen("operator")));
if (func->isBinaryOperator()) {
if (func->isReverseOperator())
std::swap(firstArg, secondArg);
if (((op == QLatin1String("++")) || (op == QLatin1String("--"))) && !func->isReverseOperator()) {
- s << endl << INDENT << "for (int i=0; i < " << secondArg << "; i++, " << firstArg << op << ");\n";
+ s << Qt::endl << INDENT << "for (int i=0; i < " << secondArg << "; i++, " << firstArg << op << ");\n";
mc << firstArg;
} else {
mc << firstArg << ' ' << op << ' ' << secondArg;
@@ -3314,7 +3319,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
<< ctorCall << ";\n"
<< INDENT
<< "PySide::setNextQObjectMemoryAddr(0);"
- << endl;
+ << Qt::endl;
}
uva << INDENT << "} else {\n";
{
@@ -3418,12 +3423,12 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
<< INDENT << "threadSaver.save();\n";
}
} else if (allowThread) {
- s << INDENT << BEGIN_ALLOW_THREADS << endl;
+ s << INDENT << BEGIN_ALLOW_THREADS << Qt::endl;
}
s << INDENT;
if (isCtor) {
s << (useVAddr.isEmpty() ?
- QString::fromLatin1("cptr = %1;").arg(methodCall) : useVAddr) << endl;
+ QString::fromLatin1("cptr = %1;").arg(methodCall) : useVAddr) << Qt::endl;
} else if (func->type() && !func->isInplaceOperator()) {
bool writeReturnType = true;
if (avoidProtectedHack()) {
@@ -3484,7 +3489,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
}
if (func->hasInjectedCode() && !func->isConstructor()) {
- s << endl;
+ s << Qt::endl;
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionEnd, TypeSystem::TargetLangCode, func, lastArg);
}
@@ -3509,12 +3514,12 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
hasReturnPolicy = true;
if (!ownership_mods.isEmpty()) {
- s << endl << INDENT << "// Ownership transferences.\n";
+ s << Qt::endl << INDENT << "// Ownership transferences.\n";
for (const ArgumentModification &arg_mod : qAsConst(ownership_mods)) {
const AbstractMetaClass *wrappedClass = nullptr;
QString pyArgName = argumentNameFromIndex(func, arg_mod.index, &wrappedClass);
if (!wrappedClass) {
- s << "#error Invalid ownership modification for argument " << arg_mod.index << '(' << pyArgName << ")\n" << endl;
+ s << "#error Invalid ownership modification for argument " << arg_mod.index << '(' << pyArgName << ")\n" << Qt::endl;
break;
}
@@ -3537,7 +3542,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
} else {
s << "invalidate(" << pyArgName << ");";
}
- s << endl;
+ s << Qt::endl;
}
} else if (!refcount_mods.isEmpty()) {
@@ -3557,7 +3562,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
} else {
pyArgName = argumentNameFromIndex(func, arg_mod.index, &wrappedClass);
if (pyArgName.isEmpty()) {
- s << "#error Invalid reference count modification for argument " << arg_mod.index << endl << endl;
+ s << "#error Invalid reference count modification for argument " << arg_mod.index << Qt::endl << Qt::endl;
break;
}
}
@@ -3628,9 +3633,9 @@ void CppGenerator::writeMultipleInheritanceInitializerFunction(QTextStream &s, c
for (const QString &ancestor : ancestors)
s << INDENT << "offsets.insert(int(" << ancestor << "));\n";
- s << endl;
+ s << Qt::endl;
s << INDENT << "offsets.erase(0);\n";
- s << endl;
+ s << Qt::endl;
s << INDENT << "std::copy(offsets.cbegin(), offsets.cend(), mi_offsets);\n";
}
@@ -3698,7 +3703,7 @@ void CppGenerator::writeEnumConverterInitialization(QTextStream &s, const TypeEn
{
Indentation indent(INDENT);
QString typeName = fixedCppTypeName(enumType);
- s << INDENT << "SbkConverter *converter = Shiboken::Conversions::createConverter(" << enumPythonType << ',' << endl;
+ s << INDENT << "SbkConverter *converter = Shiboken::Conversions::createConverter(" << enumPythonType << ',' << Qt::endl;
{
Indentation indent(INDENT);
s << INDENT << cppToPythonFunctionName(typeName, typeName) << ");\n";
@@ -3783,7 +3788,7 @@ void CppGenerator::writeContainerConverterInitialization(QTextStream &s, const A
void CppGenerator::writeExtendedConverterInitialization(QTextStream &s, const TypeEntry *externalType,
const QVector<const AbstractMetaClass *>& conversions)
{
- s << INDENT << "// Extended implicit conversions for " << externalType->qualifiedTargetLangName() << '.' << endl;
+ s << INDENT << "// Extended implicit conversions for " << externalType->qualifiedTargetLangName() << '.' << Qt::endl;
for (const AbstractMetaClass *sourceClass : conversions) {
const QString converterVar = QLatin1String("reinterpret_cast<SbkObjectType *>(")
+ cppApiVariableName(externalType->targetLangPackage()) + QLatin1Char('[')
@@ -3971,7 +3976,7 @@ void CppGenerator::writeClassDefinition(QTextStream &s,
if (metaClass == miClass)
writeMultipleInheritanceInitializerFunction(s, metaClass);
writeSpecialCastFunction(s, metaClass);
- s << endl;
+ s << Qt::endl;
}
s << "// Class Definition -----------------------------------------------\n";
@@ -4000,7 +4005,7 @@ void CppGenerator::writeClassDefinition(QTextStream &s,
s << "{\n";
s << INDENT << "return " << typePtr << ";\n";
s << "}\n";
- s << endl;
+ s << Qt::endl;
s << "static PyType_Slot " << className << "_slots[] = {\n";
s << INDENT << "{Py_tp_base, nullptr}, // inserted by introduceWrapperType\n";
s << INDENT << pyTypeSlotEntry("Py_tp_dealloc", tp_dealloc)
@@ -4041,8 +4046,8 @@ void CppGenerator::writeClassDefinition(QTextStream &s,
s << INDENT << tp_flags << ",\n";
s << INDENT << className << "_slots\n";
s << "};\n";
- s << endl;
- s << "} //extern \"C\"" << endl;
+ s << Qt::endl;
+ s << "} //extern \"C\"" << Qt::endl;
}
void CppGenerator::writeMappingMethods(QTextStream &s,
@@ -4090,7 +4095,7 @@ void CppGenerator::writeSequenceMethods(QTextStream &s,
writeCppSelfDefinition(s, func, context);
- const AbstractMetaArgument *lastArg = func->arguments().isEmpty() ? 0 : func->arguments().constLast();
+ const AbstractMetaArgument *lastArg = func->arguments().isEmpty() ? nullptr : func->arguments().constLast();
writeCodeSnips(s, snips,TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode, func, lastArg);
s<< "}\n\n";
}
@@ -4275,7 +4280,7 @@ void CppGenerator::writeCopyFunction(QTextStream &s, GeneratorContext &context)
writeFunctionReturnErrorCheckSection(s);
s << INDENT << "return " << PYTHON_RETURN_VAR << ";\n";
s << "}\n";
- s << endl;
+ s << Qt::endl;
}
void CppGenerator::writeGetterFunction(QTextStream &s,
@@ -4414,7 +4419,7 @@ void CppGenerator::writeSetterFunction(QTextStream &s,
s << cppField << ";\n";
s << INDENT << PYTHON_TO_CPP_VAR << "(pyIn, &cppOut_ptr)";
}
- s << ";\n" << endl;
+ s << ";\n" << Qt::endl;
if (isPointerToWrapperType(fieldType)) {
s << INDENT << "Shiboken::Object::keepReference(reinterpret_cast<SbkObject *>(self), \"";
@@ -4437,7 +4442,7 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, GeneratorContext &co
s << INDENT << "PyObject *" << PYTHON_RETURN_VAR << "{};\n";
s << INDENT << "PythonToCppFunc " << PYTHON_TO_CPP_VAR << ";\n";
writeUnusedVariableCast(s, QLatin1String(PYTHON_TO_CPP_VAR));
- s << endl;
+ s << Qt::endl;
s << INDENT << "switch (op) {\n";
{
@@ -4447,7 +4452,7 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, GeneratorContext &co
const AbstractMetaFunction *rfunc = overloads[0];
QString operatorId = ShibokenGenerator::pythonRichCompareOperatorId(rfunc);
- s << INDENT << "case " << operatorId << ':' << endl;
+ s << INDENT << "case " << operatorId << ':' << Qt::endl;
Indentation indent(INDENT);
@@ -4482,7 +4487,7 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, GeneratorContext &co
s << ") {\n";
{
Indentation indent(INDENT);
- s << INDENT << "// " << func->signature() << endl;
+ s << INDENT << "// " << func->signature() << Qt::endl;
writeArgumentConversion(s, argType, QLatin1String(CPP_ARG0),
QLatin1String(PYTHON_ARG), metaClass,
QString(), func->isUserAdded());
@@ -4542,7 +4547,7 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, GeneratorContext &co
}
s << INDENT << baseName << "_RichComparison_TypeError:\n";
s << INDENT << "PyErr_SetString(PyExc_NotImplementedError, \"operator not implemented.\");\n";
- s << INDENT << returnStatement(m_currentErrorCode) << endl << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl << Qt::endl;
s<< "}\n\n";
}
@@ -4586,7 +4591,7 @@ void CppGenerator::writeMethodDefinition(QTextStream &s, const AbstractMetaFunct
writeMethodDefinitionEntry(s, overloads);
s << '}';
}
- s << ',' << endl;
+ s << ',' << Qt::endl;
}
void CppGenerator::writeSignatureInfo(QTextStream &s, const AbstractMetaFunctionList &overloads)
@@ -4619,7 +4624,7 @@ void CppGenerator::writeSignatureInfo(QTextStream &s, const AbstractMetaFunction
s << funcName << '(' << args.join(QLatin1Char(',')) << ')';
if (f->type())
s << "->" << f->type()->pythonSignature();
- s << endl;
+ s << Qt::endl;
}
}
@@ -4646,9 +4651,8 @@ static QString mangleName(QString name)
void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnum *cppEnum)
{
- const AbstractMetaClass *enclosingClass = getProperEnclosingClassForEnum(cppEnum);
- const AbstractMetaClass *upper = enclosingClass ? enclosingClass->enclosingClass() : nullptr;
- bool hasUpperEnclosingClass = upper && upper->typeEntry()->codeGeneration() != TypeEntry::GenerateForSubclass;
+ const AbstractMetaClass *enclosingClass = cppEnum->targetLangEnclosingClass();
+ bool hasUpperEnclosingClass = enclosingClass && enclosingClass->targetLangEnclosingClass() != nullptr;
const EnumTypeEntry *enumTypeEntry = cppEnum->typeEntry();
QString enclosingObjectVariable;
if (enclosingClass)
@@ -4679,7 +4683,7 @@ void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnu
s << INDENT << enumVarTypeObj << " = Shiboken::Enum::";
s << ((enclosingClass || hasUpperEnclosingClass) ? "createScopedEnum" : "createGlobalEnum");
- s << '(' << enclosingObjectVariable << ',' << endl;
+ s << '(' << enclosingObjectVariable << ',' << Qt::endl;
{
Indentation indent(INDENT);
s << INDENT << '"' << cppEnum->name() << "\",\n";
@@ -4687,13 +4691,13 @@ void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnu
s << INDENT << '"' << (cppEnum->enclosingClass() ? (cppEnum->enclosingClass()->qualifiedCppName() + QLatin1String("::")) : QString());
s << cppEnum->name() << '"';
if (flags)
- s << ',' << endl << INDENT << cpythonTypeNameExt(flags);
+ s << ',' << Qt::endl << INDENT << cpythonTypeNameExt(flags);
s << ");\n";
}
s << INDENT << "if (!" << cpythonTypeNameExt(cppEnum->typeEntry()) << ")\n";
{
Indentation indent(INDENT);
- s << INDENT << returnStatement(m_currentErrorCode) << endl << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl << Qt::endl;
}
}
@@ -4726,7 +4730,7 @@ void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnu
<< "))->tp_dict, \"" << mangleName(enumValue->name()) << "\", anonEnumItem) < 0)\n";
{
Indentation indent(INDENT);
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
s << INDENT << "Py_DECREF(anonEnumItem);\n";
}
@@ -4736,27 +4740,27 @@ void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnu
s << enumValueText << ") < 0)\n";
{
Indentation indent(INDENT);
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
}
break;
case CEnum: {
s << INDENT << "if (!Shiboken::Enum::";
s << ((enclosingClass || hasUpperEnclosingClass) ? "createScopedEnumItem" : "createGlobalEnumItem");
- s << '(' << enumVarTypeObj << ',' << endl;
+ s << '(' << enumVarTypeObj << ',' << Qt::endl;
Indentation indent(INDENT);
s << INDENT << enclosingObjectVariable << ", \"" << mangleName(enumValue->name()) << "\", ";
s << enumValueText << "))\n";
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
break;
case EnumClass: {
s << INDENT << "if (!Shiboken::Enum::createScopedEnumItem("
- << enumVarTypeObj << ',' << endl;
+ << enumVarTypeObj << ',' << Qt::endl;
Indentation indent(INDENT);
s << INDENT << enumVarTypeObj<< ", \"" << mangleName(enumValue->name()) << "\", "
<< enumValueText << "))\n"
- << INDENT << returnStatement(m_currentErrorCode) << endl;
+ << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
break;
}
@@ -4767,7 +4771,7 @@ void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnu
s << INDENT << "// End of '" << cppEnum->name() << "' enum";
if (cppEnum->typeEntry()->flags())
s << "/flags";
- s << '.' << endl << endl;
+ s << '.' << Qt::endl << Qt::endl;
}
void CppGenerator::writeSignalInitialization(QTextStream &s, const AbstractMetaClass *metaClass)
@@ -4835,7 +4839,7 @@ void CppGenerator::writeFlagsMethods(QTextStream &s, const AbstractMetaEnum *cpp
writeFlagsToLong(s, cppEnum);
writeFlagsNonZero(s, cppEnum);
- s << endl;
+ s << Qt::endl;
}
void CppGenerator::writeFlagsNumberMethodsDefinition(QTextStream &s, const AbstractMetaEnum *cppEnum)
@@ -4859,7 +4863,7 @@ void CppGenerator::writeFlagsNumberMethodsDefinition(QTextStream &s, const Abstr
s << INDENT << "{Py_nb_long, (void *)" << cpythonName << "_long},\n";
s << "#endif\n";
s << INDENT << "{0, " << NULL_PTR << "} // sentinel\n";
- s << "};" << endl << endl;
+ s << "};\n\n";
}
void CppGenerator::writeFlagsBinaryOperator(QTextStream &s, const AbstractMetaEnum *cppEnum,
@@ -4944,9 +4948,8 @@ void CppGenerator::writeClassRegister(QTextStream &s,
{
const ComplexTypeEntry *classTypeEntry = metaClass->typeEntry();
- const AbstractMetaClass *enc = metaClass->enclosingClass();
- bool hasEnclosingClass = enc && enc->typeEntry()->codeGeneration() != TypeEntry::GenerateForSubclass;
- QString enclosingObjectVariable = hasEnclosingClass ? QLatin1String("enclosingClass") : QLatin1String("module");
+ const AbstractMetaClass *enc = metaClass->targetLangEnclosingClass();
+ QString enclosingObjectVariable = enc ? QLatin1String("enclosingClass") : QLatin1String("module");
QString pyTypeName = cpythonTypeName(metaClass);
QString initFunctionName = getInitFunctionName(classContext);
@@ -4967,7 +4970,7 @@ void CppGenerator::writeClassRegister(QTextStream &s,
const AbstractMetaClassList baseClasses = getBaseClasses(metaClass);
if (metaClass->baseClassNames().size() > 1) {
s << INDENT << "PyObject *" << pyTypeBasesVariable
- << " = PyTuple_Pack(" << baseClasses.size() << ',' << endl;
+ << " = PyTuple_Pack(" << baseClasses.size() << ',' << Qt::endl;
Indentation indent(INDENT);
for (int i = 0, size = baseClasses.size(); i < size; ++i) {
if (i)
@@ -5039,13 +5042,13 @@ void CppGenerator::writeClassRegister(QTextStream &s,
// 8:baseTypes
if (metaClass->baseClassNames().size() > 1)
- s << INDENT << pyTypeBasesVariable << ',' << endl;
+ s << INDENT << pyTypeBasesVariable << ',' << Qt::endl;
else
s << INDENT << "0,\n";
// 9:wrapperflags
QByteArrayList wrapperFlags;
- if (hasEnclosingClass)
+ if (enc)
wrapperFlags.append(QByteArrayLiteral("Shiboken::ObjectType::WrapperFlags::InnerClass"));
if (metaClass->deleteInMainThread())
wrapperFlags.append(QByteArrayLiteral("Shiboken::ObjectType::WrapperFlags::DeleteInMainThread"));
@@ -5055,23 +5058,23 @@ void CppGenerator::writeClassRegister(QTextStream &s,
s << INDENT << wrapperFlags.join(" | ");
}
s << INDENT << ");\n";
- s << INDENT << endl;
+ s << INDENT << Qt::endl;
if (!classContext.forSmartPointer())
- s << INDENT << cpythonTypeNameExt(classTypeEntry) << endl;
+ s << INDENT << cpythonTypeNameExt(classTypeEntry) << Qt::endl;
else
- s << INDENT << cpythonTypeNameExt(classContext.preciseType()) << endl;
+ s << INDENT << cpythonTypeNameExt(classContext.preciseType()) << Qt::endl;
s << INDENT << " = reinterpret_cast<PyTypeObject *>(" << pyTypeName << ");\n";
- s << endl;
+ s << Qt::endl;
// Register conversions for the type.
writeConverterRegister(s, metaClass, classContext);
- s << endl;
+ s << Qt::endl;
// class inject-code target/beginning
if (!classTypeEntry->codeSnips().isEmpty()) {
writeCodeSnips(s, classTypeEntry->codeSnips(), TypeSystem::CodeSnipPositionBeginning, TypeSystem::TargetLangCode, metaClass);
- s << endl;
+ s << Qt::endl;
}
// Fill multiple inheritance data, if needed.
@@ -5117,11 +5120,11 @@ void CppGenerator::writeClassRegister(QTextStream &s,
writeToPythonConversion(s, field->type(), metaClass, metaClass->qualifiedCppName() + QLatin1String("::") + field->name());
s << ");\n";
}
- s << endl;
+ s << Qt::endl;
// class inject-code target/end
if (!classTypeEntry->codeSnips().isEmpty()) {
- s << endl;
+ s << Qt::endl;
writeCodeSnips(s, classTypeEntry->codeSnips(), TypeSystem::CodeSnipPositionEnd, TypeSystem::TargetLangCode, metaClass);
}
@@ -5439,6 +5442,25 @@ void CppGenerator::writeSmartPointerGetattroFunction(QTextStream &s, GeneratorCo
s << INDENT << "return tmp;\n}\n\n";
}
+// Write declaration and invocation of the init function for the module init
+// function.
+void CppGenerator::writeInitFunc(QTextStream &declStr, QTextStream &callStr,
+ const Indentor &indent, const QString &initFunctionName,
+ const TypeEntry *enclosingEntry)
+{
+ const bool hasParent =
+ enclosingEntry && enclosingEntry->type() != TypeEntry::TypeSystemType;
+ declStr << "void init_" << initFunctionName << "(PyObject *"
+ << (hasParent ? "enclosingClass" : "module") << ");\n";
+ callStr << indent << "init_" << initFunctionName;
+ if (hasParent) {
+ callStr << "(reinterpret_cast<PyTypeObject *>("
+ << cpythonTypeNameExt(enclosingEntry) << ")->tp_dict);\n";
+ } else {
+ callStr << "(module);\n";
+ }
+}
+
bool CppGenerator::finishGeneration()
{
//Generate CPython wrapper file
@@ -5493,33 +5515,20 @@ bool CppGenerator::finishGeneration()
const AbstractMetaClassList lst = classesTopologicalSorted(additionalDependencies);
for (const AbstractMetaClass *cls : lst){
- if (!shouldGenerate(cls))
- continue;
-
- const QString initFunctionName = QLatin1String("init_") + getSimpleClassInitFunctionName(cls);
-
- s_classInitDecl << "void " << initFunctionName << "(PyObject *module);" << endl;
-
- s_classPythonDefines << INDENT << initFunctionName;
- if (cls->enclosingClass()
- && (cls->enclosingClass()->typeEntry()->codeGeneration() != TypeEntry::GenerateForSubclass)) {
- s_classPythonDefines << "(reinterpret_cast<PyTypeObject *>("
- << cpythonTypeNameExt(cls->enclosingClass()->typeEntry()) << ")->tp_dict);";
- } else {
- s_classPythonDefines << "(module);";
+ if (shouldGenerate(cls)) {
+ writeInitFunc(s_classInitDecl, s_classPythonDefines, INDENT,
+ getSimpleClassInitFunctionName(cls),
+ cls->typeEntry()->targetLangEnclosingEntry());
}
- s_classPythonDefines << endl;
}
// Initialize smart pointer types.
const QVector<const AbstractMetaType *> &smartPtrs = instantiatedSmartPointers();
for (const AbstractMetaType *metaType : smartPtrs) {
GeneratorContext context(nullptr, metaType, true);
- QString initFunctionName = getInitFunctionName(context);
- s_classInitDecl << "void init_" << initFunctionName << "(PyObject *module);" << endl;
- QString defineStr = QLatin1String("init_") + initFunctionName;
- defineStr += QLatin1String("(module);");
- s_classPythonDefines << INDENT << defineStr << endl;
+ writeInitFunc(s_classInitDecl, s_classPythonDefines, INDENT,
+ getInitFunctionName(context),
+ metaType->typeEntry()->targetLangEnclosingEntry());
}
QString moduleFileName(outputDirectory() + QLatin1Char('/') + subDirectoryForPackage(packageName()));
@@ -5532,7 +5541,7 @@ bool CppGenerator::finishGeneration()
QTextStream &s = file.stream;
// write license comment
- s << licenseComment() << endl;
+ s << licenseComment() << Qt::endl;
s << "#include <sbkpython.h>\n";
s << "#include <shiboken.h>\n";
@@ -5544,19 +5553,18 @@ bool CppGenerator::finishGeneration()
s << "#include <qapp_macro.h>\n";
}
- s << "#include \"" << getModuleHeaderFileName() << '"' << endl << endl;
+ s << "#include \"" << getModuleHeaderFileName() << '"' << Qt::endl << Qt::endl;
for (const Include &include : qAsConst(includes))
s << include;
- s << endl;
+ s << Qt::endl;
// Global enums
AbstractMetaEnumList globalEnums = this->globalEnums();
const AbstractMetaClassList &classList = classes();
for (const AbstractMetaClass *metaClass : classList) {
const AbstractMetaClass *encClass = metaClass->enclosingClass();
- if (encClass && encClass->typeEntry()->codeGeneration() != TypeEntry::GenerateForSubclass)
- continue;
- lookForEnumsInClassesNotToBeGenerated(globalEnums, metaClass);
+ if (!encClass || !NamespaceTypeEntry::isVisibleScope(encClass->typeEntry()))
+ lookForEnumsInClassesNotToBeGenerated(globalEnums, metaClass);
}
TypeDatabase *typeDb = TypeDatabase::instance();
@@ -5564,14 +5572,14 @@ bool CppGenerator::finishGeneration()
Q_ASSERT(moduleEntry);
//Extra includes
- s << endl << "// Extra includes\n";
+ s << Qt::endl << "// Extra includes\n";
QVector<Include> extraIncludes = moduleEntry->extraIncludes();
for (AbstractMetaEnum *cppEnum : qAsConst(globalEnums))
extraIncludes.append(cppEnum->typeEntry()->extraIncludes());
std::sort(extraIncludes.begin(), extraIncludes.end());
for (const Include &inc : qAsConst(extraIncludes))
s << inc;
- s << endl;
+ s << Qt::endl;
s << "// Current module's type array.\n";
s << "PyTypeObject **" << cppApiVariableName() << " = nullptr;\n";
@@ -5587,7 +5595,7 @@ bool CppGenerator::finishGeneration()
// module inject-code native/beginning
if (!snips.isEmpty()) {
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, TypeSystem::NativeCode);
- s << endl;
+ s << Qt::endl;
}
// cleanup staticMetaObject attribute
@@ -5612,7 +5620,7 @@ bool CppGenerator::finishGeneration()
s << "// Global functions ";
s << "------------------------------------------------------------\n";
- s << globalFunctionImpl << endl;
+ s << globalFunctionImpl << Qt::endl;
s << "static PyMethodDef " << moduleName() << "_methods[] = {\n";
s << globalFunctionDecl;
@@ -5620,7 +5628,7 @@ bool CppGenerator::finishGeneration()
s << "// Classes initialization functions ";
s << "------------------------------------------------------------\n";
- s << classInitDecl << endl;
+ s << classInitDecl << Qt::endl;
if (!globalEnums.isEmpty()) {
QString converterImpl;
@@ -5632,14 +5640,14 @@ bool CppGenerator::finishGeneration()
if (cppEnum->isAnonymous() || cppEnum->isPrivate())
continue;
writeEnumConverterFunctions(s, cppEnum);
- s << endl;
+ s << Qt::endl;
}
if (!converterImpl.isEmpty()) {
s << "// Enum converters ";
s << "------------------------------------------------------------\n";
s << "namespace Shiboken\n{\n";
- s << converterImpl << endl;
+ s << converterImpl << Qt::endl;
s << "} // namespace Shiboken\n\n";
}
}
@@ -5651,16 +5659,16 @@ bool CppGenerator::finishGeneration()
s << "PyTypeObject **" << cppApiVariableName(requiredModule) << ";\n";
s << "SbkConverter **" << convertersVariableName(requiredModule) << ";\n";
}
- s << endl;
+ s << Qt::endl;
s << "// Module initialization ";
s << "------------------------------------------------------------\n";
ExtendedConverterData extendedConverters = getExtendedConverters();
if (!extendedConverters.isEmpty()) {
- s << endl << "// Extended Converters.\n\n";
+ s << Qt::endl << "// Extended Converters.\n\n";
for (ExtendedConverterData::const_iterator it = extendedConverters.cbegin(), end = extendedConverters.cend(); it != end; ++it) {
const TypeEntry *externalType = it.key();
- s << "// Extended implicit conversions for " << externalType->qualifiedTargetLangName() << '.' << endl;
+ s << "// Extended implicit conversions for " << externalType->qualifiedTargetLangName() << '.' << Qt::endl;
for (const AbstractMetaClass *sourceClass : it.value()) {
AbstractMetaType *sourceType = buildAbstractMetaTypeFromAbstractMetaClass(sourceClass);
AbstractMetaType *targetType = buildAbstractMetaTypeFromTypeEntry(externalType);
@@ -5671,13 +5679,13 @@ bool CppGenerator::finishGeneration()
const QVector<const CustomConversion *> &typeConversions = getPrimitiveCustomConversions();
if (!typeConversions.isEmpty()) {
- s << endl << "// Primitive Type converters.\n\n";
+ s << Qt::endl << "// Primitive Type converters.\n\n";
for (const CustomConversion *conversion : typeConversions) {
s << "// C++ to Python conversion for type '" << conversion->ownerType()->qualifiedCppName() << "'.\n";
writeCppToPythonFunction(s, conversion);
writeCustomConverterFunctions(s, conversion);
}
- s << endl;
+ s << Qt::endl;
}
const QVector<const AbstractMetaType *> &containers = instantiatedContainers();
@@ -5687,7 +5695,7 @@ bool CppGenerator::finishGeneration()
s << "// C++ to Python conversion for type '" << container->cppSignature() << "'.\n";
writeContainerConverterFunctions(s, container);
}
- s << endl;
+ s << Qt::endl;
}
s << "#if defined _WIN32 || defined __CYGWIN__\n";
@@ -5727,7 +5735,7 @@ bool CppGenerator::finishGeneration()
// module inject-code target/beginning
if (!snips.isEmpty()) {
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, TypeSystem::TargetLangCode);
- s << endl;
+ s << Qt::endl;
}
for (const QString &requiredModule : requiredModules) {
@@ -5774,26 +5782,26 @@ bool CppGenerator::finishGeneration()
s << classPythonDefines;
if (!typeConversions.isEmpty()) {
- s << endl;
+ s << Qt::endl;
for (const CustomConversion *conversion : typeConversions) {
writePrimitiveConverterInitialization(s, conversion);
- s << endl;
+ s << Qt::endl;
}
}
if (!containers.isEmpty()) {
- s << endl;
+ s << Qt::endl;
for (const AbstractMetaType *container : containers) {
writeContainerConverterInitialization(s, container);
- s << endl;
+ s << Qt::endl;
}
}
if (!extendedConverters.isEmpty()) {
- s << endl;
+ s << Qt::endl;
for (ExtendedConverterData::const_iterator it = extendedConverters.cbegin(), end = extendedConverters.cend(); it != end; ++it) {
writeExtendedConverterInitialization(s, it.key(), it.value());
- s << endl;
+ s << Qt::endl;
}
}
@@ -5816,12 +5824,12 @@ bool CppGenerator::finishGeneration()
}
}
- s << endl;
+ s << Qt::endl;
if (maxTypeIndex)
s << INDENT << "Shiboken::Module::registerTypes(module, " << cppApiVariableName() << ");\n";
s << INDENT << "Shiboken::Module::registerTypeConverters(module, " << convertersVariableName() << ");\n";
- s << endl << INDENT << "if (PyErr_Occurred()) {\n";
+ s << Qt::endl << INDENT << "if (PyErr_Occurred()) {\n";
{
Indentation indentation(INDENT);
s << INDENT << "PyErr_Print();\n";
@@ -5832,13 +5840,13 @@ bool CppGenerator::finishGeneration()
// module inject-code target/end
if (!snips.isEmpty()) {
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionEnd, TypeSystem::TargetLangCode);
- s << endl;
+ s << Qt::endl;
}
// module inject-code native/end
if (!snips.isEmpty()) {
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionEnd, TypeSystem::NativeCode);
- s << endl;
+ s << Qt::endl;
}
if (usePySideExtensions()) {
@@ -5855,7 +5863,7 @@ bool CppGenerator::finishGeneration()
s << INDENT << "FinishSignatureInitialization(module, " << moduleName()
<< "_SignatureStrings);\n";
- s << endl;
+ s << Qt::endl;
s << "SBK_MODULE_INIT_FUNCTION_END\n";
return file.done() != FileOut::Failure;
@@ -6031,7 +6039,7 @@ void CppGenerator::writeIndexError(QTextStream &s, const QString &errorMsg)
{
Indentation indent(INDENT);
s << INDENT << "PyErr_SetString(PyExc_IndexError, \"" << errorMsg << "\");\n";
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
s << INDENT << "}\n";
}
diff --git a/sources/shiboken2/generator/shiboken2/headergenerator.cpp b/sources/shiboken2/generator/shiboken2/headergenerator.cpp
index 34bba408a..af56d944a 100644
--- a/sources/shiboken2/generator/shiboken2/headergenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/headergenerator.cpp
@@ -119,7 +119,7 @@ void HeaderGenerator::generateClass(QTextStream &s, GeneratorContext &classConte
s << "#define protected public\n\n";
//Includes
- s << metaClass->typeEntry()->include() << endl;
+ s << metaClass->typeEntry()->include() << Qt::endl;
if (shouldGenerateCppWrapper(metaClass) &&
usePySideExtensions() && metaClass->isQObject())
@@ -337,7 +337,8 @@ void HeaderGenerator::writeTypeIndexValueLine(QTextStream &s, const TypeEntry *t
void HeaderGenerator::writeTypeIndexValueLines(QTextStream &s, const AbstractMetaClass *metaClass)
{
- if (!metaClass->typeEntry()->generateCode())
+ auto typeEntry = metaClass->typeEntry();
+ if (!typeEntry->generateCode() || !NamespaceTypeEntry::isVisibleScope(typeEntry))
return;
writeTypeIndexValueLine(s, metaClass->typeEntry());
const AbstractMetaEnumList &enums = metaClass->enums();
@@ -411,9 +412,17 @@ bool HeaderGenerator::finishGeneration()
int smartPointerCount = 0;
const QVector<const AbstractMetaType *> &instantiatedSmartPtrs = instantiatedSmartPointers();
for (const AbstractMetaType *metaType : instantiatedSmartPtrs) {
- _writeTypeIndexValue(macrosStream, getTypeIndexVariableName(metaType),
- smartPointerCountIndex);
- macrosStream << ", // " << metaType->cppSignature() << endl;
+ QString indexName = getTypeIndexVariableName(metaType);
+ _writeTypeIndexValue(macrosStream, indexName, smartPointerCountIndex);
+ macrosStream << ", // " << metaType->cppSignature() << Qt::endl;
+ // Add a the same value for const pointees (shared_ptr<const Foo>).
+ const auto ptrName = metaType->typeEntry()->entryName();
+ int pos = indexName.indexOf(ptrName, 0, Qt::CaseInsensitive);
+ if (pos >= 0) {
+ indexName.insert(pos + ptrName.size() + 1, QLatin1String("CONST"));
+ _writeTypeIndexValue(macrosStream, indexName, smartPointerCountIndex);
+ macrosStream << ", // (const)\n";
+ }
++smartPointerCountIndex;
++smartPointerCount;
}
@@ -449,7 +458,7 @@ bool HeaderGenerator::finishGeneration()
const QVector<const AbstractMetaType *> &containers = instantiatedContainers();
for (const AbstractMetaType *container : containers) {
_writeTypeIndexValue(macrosStream, getTypeIndexVariableName(container), pCount);
- macrosStream << ", // " << container->cppSignature() << endl;
+ macrosStream << ", // " << container->cppSignature() << Qt::endl;
pCount++;
}
@@ -517,10 +526,10 @@ bool HeaderGenerator::finishGeneration()
FileOut file(moduleHeaderFileName);
QTextStream &s = file.stream;
// write license comment
- s << licenseComment() << endl << endl;
+ s << licenseComment() << Qt::endl << Qt::endl;
- s << "#ifndef " << includeShield << endl;
- s << "#define " << includeShield << endl << endl;
+ s << "#ifndef " << includeShield << Qt::endl;
+ s << "#define " << includeShield << Qt::endl << Qt::endl;
if (!avoidProtectedHack()) {
s << "//workaround to access protected functions\n";
s << "#define protected public\n\n";
@@ -534,7 +543,7 @@ bool HeaderGenerator::finishGeneration()
s << "// Module Includes\n";
for (const QString &requiredModule : qAsConst(requiredTargetImports))
s << "#include <" << getModuleHeaderFileName(requiredModule) << ">\n";
- s << endl;
+ s << Qt::endl;
}
s << "// Bound library includes\n";
@@ -546,7 +555,7 @@ bool HeaderGenerator::finishGeneration()
const PrimitiveTypeEntryList &primitiveTypeList = primitiveTypes();
for (const PrimitiveTypeEntry *ptype : primitiveTypeList)
s << ptype->include();
- s << endl;
+ s << Qt::endl;
}
if (!containerTypes().isEmpty()) {
@@ -554,24 +563,24 @@ bool HeaderGenerator::finishGeneration()
const ContainerTypeEntryList &containerTypeList = containerTypes();
for (const ContainerTypeEntry *ctype : containerTypeList)
s << ctype->include();
- s << endl;
+ s << Qt::endl;
}
- s << macros << endl;
+ s << macros << Qt::endl;
if (!protectedEnumSurrogates.isEmpty()) {
s << "// Protected enum surrogates\n";
- s << protectedEnumSurrogates << endl;
+ s << protectedEnumSurrogates << Qt::endl;
}
s << "namespace Shiboken\n{\n\n";
s << "// PyType functions, to get the PyObjectType for a type T\n";
- s << sbkTypeFunctions << endl;
+ s << sbkTypeFunctions << Qt::endl;
s << "} // namespace Shiboken\n\n";
- s << "#endif // " << includeShield << endl << endl;
+ s << "#endif // " << includeShield << Qt::endl << Qt::endl;
return file.done() != FileOut::Failure;
}
diff --git a/sources/shiboken2/generator/shiboken2/overloaddata.cpp b/sources/shiboken2/generator/shiboken2/overloaddata.cpp
index 56b64bbd5..bd39e9444 100644
--- a/sources/shiboken2/generator/shiboken2/overloaddata.cpp
+++ b/sources/shiboken2/generator/shiboken2/overloaddata.cpp
@@ -106,7 +106,7 @@ struct OverloadSortData
return;
map[typeName] = counter;
if (!reverseMap.contains(counter))
- reverseMap[counter] = 0;
+ reverseMap[counter] = nullptr;
counter++;
}
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
index fbd3c314b..170cbd74e 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
@@ -335,7 +335,7 @@ void ShibokenGenerator::lookForEnumsInClassesNotToBeGenerated(AbstractMetaEnumLi
{
Q_ASSERT(metaClass);
// if a scope is not to be generated, collect its enums into the parent scope
- if (metaClass->typeEntry()->codeGeneration() == TypeEntry::GenerateForSubclass) {
+ if (!NamespaceTypeEntry::isVisibleScope(metaClass->typeEntry())) {
const AbstractMetaEnumList &enums = metaClass->enums();
for (AbstractMetaEnum *metaEnum : enums) {
if (!metaEnum->isPrivate() && metaEnum->typeEntry()->generateCode()
@@ -346,22 +346,6 @@ void ShibokenGenerator::lookForEnumsInClassesNotToBeGenerated(AbstractMetaEnumLi
}
}
-static const AbstractMetaClass *getProperEnclosingClass(const AbstractMetaClass *metaClass)
-{
- if (!metaClass)
- return nullptr;
-
- if (metaClass->typeEntry()->codeGeneration() != TypeEntry::GenerateForSubclass)
- return metaClass;
-
- return getProperEnclosingClass(metaClass->enclosingClass());
-}
-
-const AbstractMetaClass *ShibokenGenerator::getProperEnclosingClassForEnum(const AbstractMetaEnum *metaEnum)
-{
- return getProperEnclosingClass(metaEnum->enclosingClass());
-}
-
QString ShibokenGenerator::wrapperName(const AbstractMetaClass *metaClass) const
{
if (shouldGenerateCppWrapper(metaClass)) {
@@ -394,7 +378,8 @@ QString ShibokenGenerator::fullPythonClassName(const AbstractMetaClass *metaClas
QString fullClassName = metaClass->name();
const AbstractMetaClass *enclosing = metaClass->enclosingClass();
while (enclosing) {
- fullClassName.prepend(enclosing->name() + QLatin1Char('.'));
+ if (NamespaceTypeEntry::isVisibleScope(enclosing->typeEntry()))
+ fullClassName.prepend(enclosing->name() + QLatin1Char('.'));
enclosing = enclosing->enclosingClass();
}
fullClassName.prepend(packageName() + QLatin1Char('.'));
@@ -2393,7 +2378,7 @@ static bool isGroupable(const AbstractMetaFunction *func)
return false;
// weird operator overloads
if (func->name() == QLatin1String("operator[]") || func->name() == QLatin1String("operator->")) // FIXME: what about cast operators?
- return false;;
+ return false;
return true;
}
@@ -2594,13 +2579,19 @@ void ShibokenGenerator::collectContainerTypesFromConverterMacros(const QString &
QString convMacro = toPythonMacro ? QLatin1String("%CONVERTTOPYTHON[") : QLatin1String("%CONVERTTOCPP[");
int offset = toPythonMacro ? sizeof("%CONVERTTOPYTHON") : sizeof("%CONVERTTOCPP");
int start = 0;
+ QString errorMessage;
while ((start = code.indexOf(convMacro, start)) != -1) {
int end = code.indexOf(QLatin1Char(']'), start);
start += offset;
if (code.at(start) != QLatin1Char('%')) {
QString typeString = code.mid(start, end - start);
- AbstractMetaType *type = buildAbstractMetaTypeFromString(typeString);
- addInstantiatedContainersAndSmartPointers(type, type->originalTypeDescription());
+ if (AbstractMetaType *type =
+ buildAbstractMetaTypeFromString(typeString, &errorMessage)) {
+ addInstantiatedContainersAndSmartPointers(type, type->originalTypeDescription());
+ } else {
+ qFatal("%s: Cannot translate type \"%s\": %s", __FUNCTION__,
+ qPrintable(typeString), qPrintable(errorMessage));
+ }
}
start = end;
}
@@ -2773,7 +2764,7 @@ void ShibokenGenerator::writeMinimalConstructorExpression(QTextStream &s, const
} else {
const QString message = msgCouldNotFindMinimalConstructor(QLatin1String(__FUNCTION__), type->qualifiedCppName());
qCWarning(lcShiboken()).noquote() << message;
- s << ";\n#error " << message << endl;
+ s << ";\n#error " << message << Qt::endl;
}
}
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.h b/sources/shiboken2/generator/shiboken2/shibokengenerator.h
index 24c1374ae..d0e9073c8 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.h
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.h
@@ -219,8 +219,6 @@ protected:
/// Adds enums eligible for generation from classes/namespaces marked not to be generated.
static void lookForEnumsInClassesNotToBeGenerated(AbstractMetaEnumList &enumList, const AbstractMetaClass *metaClass);
- /// Returns the enclosing class for an enum, or nullptr if it should be global.
- const AbstractMetaClass *getProperEnclosingClassForEnum(const AbstractMetaEnum *metaEnum);
QString wrapperName(const AbstractMetaClass *metaClass) const;
QString wrapperName(const AbstractMetaType *metaType) const;
diff --git a/sources/shiboken2/libshiboken/basewrapper.cpp b/sources/shiboken2/libshiboken/basewrapper.cpp
index b0d453cc5..29ee1b185 100644
--- a/sources/shiboken2/libshiboken/basewrapper.cpp
+++ b/sources/shiboken2/libshiboken/basewrapper.cpp
@@ -58,6 +58,8 @@
#include "qapp_macro.h"
#include "voidptr.h"
+#include <iostream>
+
#if defined(__APPLE__)
#include <dlfcn.h>
#endif
@@ -919,8 +921,11 @@ introduceWrapperType(PyObject *enclosingObject,
}
}
// PYSIDE-510: Here is the single change to support signatures.
- if (SbkSpecial_Type_Ready(enclosingObject, reinterpret_cast<PyTypeObject *>(type), signatureStrings) < 0)
+ if (SbkSpecial_Type_Ready(enclosingObject, reinterpret_cast<PyTypeObject *>(type), signatureStrings) < 0) {
+ std::cerr << "Warning: " << __FUNCTION__ << " returns nullptr for "
+ << typeName << '/' << originalName << " due to SbkSpecial_Type_Ready() failing\n";
return nullptr;
+ }
initPrivateData(type);
auto sotp = PepType_SOTP(type);
@@ -936,7 +941,13 @@ introduceWrapperType(PyObject *enclosingObject,
// PyModule_AddObject steals type's reference.
Py_INCREF(ob_type);
- return PyModule_AddObject(enclosingObject, typeName, ob_type) == 0 ? type : nullptr;
+ if (PyModule_AddObject(enclosingObject, typeName, ob_type) != 0) {
+ std::cerr << "Warning: " << __FUNCTION__ << " returns nullptr for "
+ << typeName << '/' << originalName << " due to PyModule_AddObject(enclosingObject="
+ << enclosingObject << ",ob_type=" << ob_type << ") failing\n";
+ return nullptr;
+ }
+ return type;
}
void setSubTypeInitHook(SbkObjectType *type, SubTypeInitHook func)
diff --git a/sources/shiboken2/libshiboken/helper.cpp b/sources/shiboken2/libshiboken/helper.cpp
index 013080b6e..c14bde15c 100644
--- a/sources/shiboken2/libshiboken/helper.cpp
+++ b/sources/shiboken2/libshiboken/helper.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -40,6 +40,10 @@
#include "helper.h"
#include "sbkstring.h"
#include "sbkstaticstrings.h"
+
+#include <iomanip>
+#include <iostream>
+
#include <stdarg.h>
#ifdef _WIN32
@@ -48,9 +52,88 @@
# include <pthread.h>
#endif
+static void formatPyTypeObject(const PyTypeObject *obj, std::ostream &str)
+{
+ if (obj) {
+ str << '"' << obj->tp_name << "\", 0x" << std::hex
+ << obj->tp_flags << std::dec;
+ if (obj->tp_flags & Py_TPFLAGS_HEAPTYPE)
+ str << " [heaptype]";
+ if (obj->tp_flags & Py_TPFLAGS_BASETYPE)
+ str << " [base]";
+ if (obj->tp_flags & Py_TPFLAGS_HAVE_GC)
+ str << " [gc]";
+ if (obj->tp_flags & Py_TPFLAGS_LONG_SUBCLASS)
+ str << " [long]";
+ if (obj->tp_flags & Py_TPFLAGS_LIST_SUBCLASS)
+ str << " [list]";
+ if (obj->tp_flags & Py_TPFLAGS_TUPLE_SUBCLASS)
+ str << " [tuple]";
+ if (obj->tp_flags & Py_TPFLAGS_BYTES_SUBCLASS)
+ str << " [bytes]";
+ if (obj->tp_flags & Py_TPFLAGS_UNICODE_SUBCLASS)
+ str << " [unicode]";
+ if (obj->tp_flags & Py_TPFLAGS_DICT_SUBCLASS)
+ str << " [dict]";
+ if (obj->tp_flags & Py_TPFLAGS_TYPE_SUBCLASS)
+ str << " [type]";
+ if (obj->tp_flags & Py_TPFLAGS_IS_ABSTRACT)
+ str << " [abstract]";
+ } else {
+ str << '0';
+ }
+}
+
+static void formatPyObject(PyObject *obj, std::ostream &str)
+{
+ if (obj) {
+ formatPyTypeObject(obj->ob_type, str);
+ str << ", ";
+ if (PyLong_Check(obj))
+ str << PyLong_AsLong(obj);
+ else if (PyFloat_Check(obj))
+ str << PyFloat_AsDouble(obj);
+#ifdef IS_PY3K
+ else if (PyUnicode_Check(obj))
+ str << '"' << _PepUnicode_AsString(obj) << '"';
+#else
+ else if (PyString_Check(obj))
+ str << '"' << PyString_AsString(obj) << '"';
+#endif
+ else
+ str << "<unknown>";
+ } else {
+ str << '0';
+ }
+}
+
namespace Shiboken
{
+debugPyObject::debugPyObject(PyObject *o) : m_object(o)
+{
+}
+
+debugPyTypeObject::debugPyTypeObject(const PyTypeObject *o) : m_object(o)
+{
+}
+
+std::ostream &operator<<(std::ostream &str, const debugPyTypeObject &o)
+{
+ str << "PyTypeObject(";
+ formatPyTypeObject(o.m_object, str);
+ str << ')';
+ return str;
+}
+
+std::ostream &operator<<(std::ostream &str, const debugPyObject &o)
+{
+ str << "PyObject(";
+ formatPyObject(o.m_object, str);
+ str << ')';
+ return str;
+}
+
// PySide-510: Changed from PySequence to PyList, which is correct.
bool listToArgcArgv(PyObject *argList, int *argc, char ***argv, const char *defaultAppName)
{
@@ -125,7 +208,7 @@ int warning(PyObject *category, int stacklevel, const char *format, ...)
{
va_list args;
va_start(args, format);
-#if _WIN32
+#ifdef _WIN32
va_list args2 = args;
#else
va_list args2;
diff --git a/sources/shiboken2/libshiboken/helper.h b/sources/shiboken2/libshiboken/helper.h
index 14aae8028..7e46f3d93 100644
--- a/sources/shiboken2/libshiboken/helper.h
+++ b/sources/shiboken2/libshiboken/helper.h
@@ -44,6 +44,8 @@
#include "shibokenmacros.h"
#include "autodecref.h"
+#include <iosfwd>
+
#define SBK_UNUSED(x) (void)(x);
namespace Shiboken
@@ -99,6 +101,24 @@ LIBSHIBOKEN_API ThreadId mainThreadId();
*/
LIBSHIBOKEN_API int warning(PyObject *category, int stacklevel, const char *format, ...);
+struct LIBSHIBOKEN_API debugPyObject
+{
+ explicit debugPyObject(PyObject *o);
+
+ PyObject *m_object;
+};
+
+struct LIBSHIBOKEN_API debugPyTypeObject
+{
+ explicit debugPyTypeObject(const PyTypeObject *o);
+
+ const PyTypeObject *m_object;
+};
+
+LIBSHIBOKEN_API std::ostream &operator<<(std::ostream &str, const debugPyObject &o);
+LIBSHIBOKEN_API std::ostream &operator<<(std::ostream &str, const debugPyTypeObject &o);
+
} // namespace Shiboken
+
#endif // HELPER_H
diff --git a/sources/shiboken2/shiboken_version.py b/sources/shiboken2/shiboken_version.py
index 0e0943143..c022fc803 100644
--- a/sources/shiboken2/shiboken_version.py
+++ b/sources/shiboken2/shiboken_version.py
@@ -38,8 +38,8 @@
#############################################################################
major_version = "5"
-minor_version = "14"
-patch_version = "2"
+minor_version = "15"
+patch_version = "0"
# For example: "a", "b", "rc"
# (which means "alpha", "beta", "release candidate").
diff --git a/sources/shiboken2/tests/helper.py b/sources/shiboken2/tests/helper.py
new file mode 100644
index 000000000..2564c91d4
--- /dev/null
+++ b/sources/shiboken2/tests/helper.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+
+def objectFullname(t):
+ module = t.__module__
+ if module is None or module == str.__class__.__module__:
+ return t.__name__
+ else:
+ return module + '.' + t.__name__
diff --git a/sources/shiboken2/tests/libother/CMakeLists.txt b/sources/shiboken2/tests/libother/CMakeLists.txt
index 6aba91e13..d1e4c4354 100644
--- a/sources/shiboken2/tests/libother/CMakeLists.txt
+++ b/sources/shiboken2/tests/libother/CMakeLists.txt
@@ -5,12 +5,13 @@ number.cpp
otherderived.cpp
otherobjecttype.cpp
othermultiplederived.cpp
+smartptrtester.cpp
)
add_library(libother SHARED ${libother_SRC})
target_include_directories(libother PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_compile_definitions(libother PRIVATE LIBOTHER_BUILD)
-target_link_libraries(libother PUBLIC libsample)
+target_link_libraries(libother PUBLIC libsample libsmart)
set_property(TARGET libother PROPERTY PREFIX "")
diff --git a/sources/shiboken2/tests/libother/otherobjecttype.cpp b/sources/shiboken2/tests/libother/otherobjecttype.cpp
index ca356ce94..1f782ecd8 100644
--- a/sources/shiboken2/tests/libother/otherobjecttype.cpp
+++ b/sources/shiboken2/tests/libother/otherobjecttype.cpp
@@ -34,3 +34,13 @@ operator<<(Collector& collector, const OtherObjectType& obj)
collector << obj.identifier()*2;
return collector;
}
+
+int OtherObjectType::enumAsInt(SampleNamespace::SomeClass::PublicScopedEnum value)
+{
+ return static_cast<int>(value);
+}
+
+int OtherObjectType::enumAsIntForInvisibleNamespace(Invisible::EnumOnNamespace value)
+{
+ return static_cast<int>(value);
+}
diff --git a/sources/shiboken2/tests/libother/otherobjecttype.h b/sources/shiboken2/tests/libother/otherobjecttype.h
index 22687c8bd..efd394347 100644
--- a/sources/shiboken2/tests/libother/otherobjecttype.h
+++ b/sources/shiboken2/tests/libother/otherobjecttype.h
@@ -35,11 +35,14 @@
#include "libothermacros.h"
#include "objecttype.h"
#include "collector.h"
+#include "samplenamespace.h"
-class OtherObjectType : public ObjectType
+
+class LIBOTHER_API OtherObjectType : public ObjectType
{
public:
-
+ static int enumAsInt(SampleNamespace::SomeClass::PublicScopedEnum value);
+ static int enumAsIntForInvisibleNamespace(Invisible::EnumOnNamespace value);
};
diff --git a/sources/shiboken2/tests/libother/smartptrtester.cpp b/sources/shiboken2/tests/libother/smartptrtester.cpp
new file mode 100644
index 000000000..9636c7521
--- /dev/null
+++ b/sources/shiboken2/tests/libother/smartptrtester.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "smartptrtester.h"
+
+SharedPtr<Str> SmartPtrTester::createSharedPtrStr(const char *what)
+{
+ return SharedPtr<Str>(new Str(what));
+}
+
+std::string SmartPtrTester::valueOfSharedPtrStr(const SharedPtr<Str> &str)
+{
+ return str->cstring();
+}
+
+SharedPtr<Integer> SmartPtrTester::createSharedPtrInteger(int v)
+{
+ auto i = SharedPtr<Integer>(new Integer);
+ i->m_int = v;
+ return i;
+}
+
+int SmartPtrTester::valueOfSharedPtrInteger(const SharedPtr<Integer> &v)
+{
+ return v->m_int;
+}
+
+void SmartPtrTester::fiddleInt(const SharedPtr<int> &) // no binding, should not cause errors
+{
+}
diff --git a/sources/shiboken2/tests/libother/smartptrtester.h b/sources/shiboken2/tests/libother/smartptrtester.h
new file mode 100644
index 000000000..a560bcf2f
--- /dev/null
+++ b/sources/shiboken2/tests/libother/smartptrtester.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SMARTPTRTESTER_H
+#define SMARTPTRTESTER_H
+
+#include "libothermacros.h"
+
+#include <smart.h>
+#include <str.h>
+
+class LIBOTHER_API SmartPtrTester
+{
+public:
+ SharedPtr<Str> createSharedPtrStr(const char *what);
+ std::string valueOfSharedPtrStr(const SharedPtr<Str> &);
+
+ SharedPtr<Integer> createSharedPtrInteger(int v);
+ int valueOfSharedPtrInteger(const SharedPtr<Integer> &);
+
+ void fiddleInt(const SharedPtr<int> &);
+};
+
+#endif // SMARTPTRTESTER_H
diff --git a/sources/shiboken2/tests/libsample/CMakeLists.txt b/sources/shiboken2/tests/libsample/CMakeLists.txt
index 170829fbc..ae13cd9f2 100644
--- a/sources/shiboken2/tests/libsample/CMakeLists.txt
+++ b/sources/shiboken2/tests/libsample/CMakeLists.txt
@@ -36,6 +36,7 @@ pointf.cpp
polygon.cpp
protected.cpp
reference.cpp
+renaming.cpp
sample.cpp
samplenamespace.cpp
sbkdate.cpp
diff --git a/sources/shiboken2/tests/libsample/renaming.cpp b/sources/shiboken2/tests/libsample/renaming.cpp
new file mode 100644
index 000000000..30586e1db
--- /dev/null
+++ b/sources/shiboken2/tests/libsample/renaming.cpp
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "renaming.h"
+
+#include <iostream>
+
+int ToBeRenamedValue::value() const
+{
+ return m_value;
+}
+
+void ToBeRenamedValue::setValue(int v)
+{
+ m_value = v;
+}
+
+void RenamedUser::useRenamedValue(const ToBeRenamedValue &v)
+{
+ std::cout << __FUNCTION__ << ' ' << v.value() << '\n';
+}
diff --git a/sources/shiboken2/tests/libsample/renaming.h b/sources/shiboken2/tests/libsample/renaming.h
new file mode 100644
index 000000000..cd88b36bf
--- /dev/null
+++ b/sources/shiboken2/tests/libsample/renaming.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RENAMING_H
+#define RENAMING_H
+
+#include "libsamplemacros.h"
+
+class LIBSAMPLE_API ToBeRenamedValue
+{
+public:
+ int value() const;
+ void setValue(int v);
+
+private:
+ int m_value = 42;
+};
+
+class LIBSAMPLE_API RenamedUser
+{
+public:
+ void useRenamedValue(const ToBeRenamedValue &v);
+};
+
+#endif // POINT_H
diff --git a/sources/shiboken2/tests/libsample/samplenamespace.h b/sources/shiboken2/tests/libsample/samplenamespace.h
index 6868b5f0a..9e46b2ad6 100644
--- a/sources/shiboken2/tests/libsample/samplenamespace.h
+++ b/sources/shiboken2/tests/libsample/samplenamespace.h
@@ -51,6 +51,13 @@ enum EnumOnNamespace {
Option3 = 3
};
+struct ObjectOnInvisibleNamespace
+{
+ bool exists() const { return true; }
+ static int toInt(EnumOnNamespace e) { return static_cast<int>(e); }
+ static ObjectOnInvisibleNamespace consume(const ObjectOnInvisibleNamespace &other) { return other; }
+};
+
};
namespace SampleNamespace
@@ -137,6 +144,8 @@ protected:
PublicScopedEnum protectedMethodReturningPublicScopedEnum() const;
};
+LIBSAMPLE_API inline int enumAsInt(SomeClass::PublicScopedEnum value) { return static_cast<int>(value); }
+
class DerivedFromNamespace : public SomeClass::SomeInnerClass::OkThisIsRecursiveEnough
{
public:
diff --git a/sources/shiboken2/tests/libsmart/smart.cpp b/sources/shiboken2/tests/libsmart/smart.cpp
index 6a4deb50a..81fa30c7e 100644
--- a/sources/shiboken2/tests/libsmart/smart.cpp
+++ b/sources/shiboken2/tests/libsmart/smart.cpp
@@ -93,7 +93,7 @@ Obj::~Obj()
void Obj::printObj() {
if (shouldPrint()) {
std::cout << "integer value: " << m_integer
- << " internal integer value: " << m_internalInteger->m_int << '\n';
+ << " internal integer value: " << m_internalInteger->value() << '\n';
}
}
@@ -134,6 +134,17 @@ int Obj::takeSharedPtrToObj(SharedPtr<Obj> pObj)
int Obj::takeSharedPtrToInteger(SharedPtr<Integer> pInt)
{
pInt->printInteger();
+ return pInt->value();
+}
+
+SharedPtr<const Integer> Obj::giveSharedPtrToConstInteger()
+{
+ SharedPtr<const Integer> co(new Integer);
+ return co;
+}
+
+int Obj::takeSharedPtrToConstInteger(SharedPtr<const Integer> pInt)
+{
return pInt->m_int;
}
@@ -173,7 +184,17 @@ Integer::~Integer()
std::cout << "Integer destructor " << this << '\n';
}
-void Integer::printInteger()
+int Integer::value() const
+{
+ return m_int;
+}
+
+void Integer::setValue(int v)
+{
+ m_int = v;
+}
+
+void Integer::printInteger() const
{
if (shouldPrint())
std::cout << "Integer value for object " << this << " is " << m_int << '\n';
diff --git a/sources/shiboken2/tests/libsmart/smart_integer.h b/sources/shiboken2/tests/libsmart/smart_integer.h
index 3756f68b0..126894120 100644
--- a/sources/shiboken2/tests/libsmart/smart_integer.h
+++ b/sources/shiboken2/tests/libsmart/smart_integer.h
@@ -37,8 +37,12 @@ public:
Integer(const Integer &other);
Integer &operator=(const Integer &other);
~Integer();
- void printInteger();
- int m_int;
+ void printInteger() const;
+
+ int value() const;
+ void setValue(int v);
+
+ int m_int; // public for testing member field access.
};
namespace Smart {
diff --git a/sources/shiboken2/tests/libsmart/smart_obj.h b/sources/shiboken2/tests/libsmart/smart_obj.h
index 12425366e..8fe45993f 100644
--- a/sources/shiboken2/tests/libsmart/smart_obj.h
+++ b/sources/shiboken2/tests/libsmart/smart_obj.h
@@ -48,12 +48,14 @@ public:
Integer takeInteger(Integer val);
SharedPtr<Obj> giveSharedPtrToObj();
std::vector<SharedPtr<Obj> > giveSharedPtrToObjList(int size);
- SharedPtr<Integer> giveSharedPtrToInteger();
+ virtual SharedPtr<Integer> giveSharedPtrToInteger(); // virtual for PYSIDE-1188
+ SharedPtr<const Integer> giveSharedPtrToConstInteger();
+ int takeSharedPtrToConstInteger(SharedPtr<const Integer> pInt);
SharedPtr<Smart::Integer2> giveSharedPtrToInteger2();
int takeSharedPtrToObj(SharedPtr<Obj> pObj);
int takeSharedPtrToInteger(SharedPtr<Integer> pInt);
- int m_integer;
+ int m_integer; // public for testing member field access.
Integer *m_internalInteger;
};
diff --git a/sources/shiboken2/tests/otherbinding/CMakeLists.txt b/sources/shiboken2/tests/otherbinding/CMakeLists.txt
index bc5c4bdad..05a282838 100644
--- a/sources/shiboken2/tests/otherbinding/CMakeLists.txt
+++ b/sources/shiboken2/tests/otherbinding/CMakeLists.txt
@@ -10,6 +10,8 @@ ${CMAKE_CURRENT_BINARY_DIR}/other/number_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/other/otherderived_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/other/othermultiplederived_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/other/otherobjecttype_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/other/sharedptr_str_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/other/smartptrtester_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/other/other_module_wrapper.cpp
)
@@ -28,8 +30,9 @@ COMMENT "Running generator for 'other' test binding..."
add_library(other MODULE ${other_SRC})
target_include_directories(other PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
- ${sample_BINARY_DIR}/sample)
-target_link_libraries(other PUBLIC libother libsample libshiboken)
+ ${sample_BINARY_DIR}/sample
+ ${smart_BINARY_DIR}/smart)
+target_link_libraries(other PUBLIC libother libsample libsmart libshiboken)
set_property(TARGET other PROPERTY PREFIX "")
set_property(TARGET other PROPERTY OUTPUT_NAME "other${PYTHON_EXTENSION_SUFFIX}")
@@ -38,6 +41,6 @@ if(WIN32)
endif()
-add_dependencies(other sample)
+add_dependencies(other sample smart)
create_generator_target(other)
diff --git a/sources/shiboken2/tests/otherbinding/global.h b/sources/shiboken2/tests/otherbinding/global.h
index 0fccabb92..763566ae0 100644
--- a/sources/shiboken2/tests/otherbinding/global.h
+++ b/sources/shiboken2/tests/otherbinding/global.h
@@ -32,4 +32,5 @@
#include "otherderived.h"
#include "otherobjecttype.h"
#include "othermultiplederived.h"
+#include "smartptrtester.h"
diff --git a/sources/shiboken2/tests/otherbinding/other-binding.txt.in b/sources/shiboken2/tests/otherbinding/other-binding.txt.in
index a17b70fc1..dbe935a9f 100644
--- a/sources/shiboken2/tests/otherbinding/other-binding.txt.in
+++ b/sources/shiboken2/tests/otherbinding/other-binding.txt.in
@@ -8,11 +8,13 @@ typesystem-file = @other_TYPESYSTEM@
output-directory = @CMAKE_CURRENT_BINARY_DIR@
include-path = @libother_SOURCE_DIR@
+include-path = @libsmart_SOURCE_DIR@
include-path = @libsample_SOURCE_DIR@
include-path = @libsample_SOURCE_DIR@/..
typesystem-path = @CMAKE_CURRENT_SOURCE_DIR@
typesystem-path = @sample_SOURCE_DIR@
+typesystem-path = @smart_SOURCE_DIR@
enable-parent-ctor-heuristic
diff --git a/sources/shiboken2/tests/otherbinding/signature_test.py b/sources/shiboken2/tests/otherbinding/signature_test.py
new file mode 100644
index 000000000..06894eaf8
--- /dev/null
+++ b/sources/shiboken2/tests/otherbinding/signature_test.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+'''Test cases for functions signature'''
+
+import os
+import sys
+import unittest
+
+sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+from shiboken_paths import init_paths
+init_paths()
+
+from other import OtherObjectType
+from helper import objectFullname
+
+class SignatureTest(unittest.TestCase):
+
+ # Check if the argument of 'OtherObjectType::enumAsInt(SampleNamespace::SomeClass::PublicScopedEnum value)'
+ # has the correct representation
+ def testNamespaceFromOtherModule(self):
+ argType = OtherObjectType.enumAsInt.__signature__.parameters['value'].annotation
+ self.assertEqual(objectFullname(argType), 'sample.SampleNamespace.SomeClass.PublicScopedEnum')
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken2/tests/otherbinding/smartptr_test.py b/sources/shiboken2/tests/otherbinding/smartptr_test.py
new file mode 100644
index 000000000..04f657757
--- /dev/null
+++ b/sources/shiboken2/tests/otherbinding/smartptr_test.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+#############################################################################
+##
+## Copyright (C) 2020 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+'''Test cases for the SmartPtrTester class'''
+
+import os
+import sys
+import unittest
+
+sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+from shiboken_paths import init_paths
+init_paths()
+
+from smart import Integer
+from sample import Str
+from other import SmartPtrTester
+
+
+class SmartPtrTest(unittest.TestCase):
+ '''Test case for the SmartPtrTester class'''
+
+ def test(self):
+ tester = SmartPtrTester()
+
+ integerPtr = tester.createSharedPtrInteger(42)
+ self.assertEqual(tester.valueOfSharedPtrInteger(integerPtr), 42)
+
+ strPtr = tester.createSharedPtrStr('hello')
+ self.assertEqual(tester.valueOfSharedPtrStr(strPtr), 'hello')
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken2/tests/otherbinding/typesystem_other.xml b/sources/shiboken2/tests/otherbinding/typesystem_other.xml
index 2932dafb3..78c4dd016 100644
--- a/sources/shiboken2/tests/otherbinding/typesystem_other.xml
+++ b/sources/shiboken2/tests/otherbinding/typesystem_other.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<typesystem package="other">
<load-typesystem name="typesystem_sample.xml" generate="no" />
+ <load-typesystem name="typesystem_smart.xml" generate="no" />
<object-type name="OtherObjectType" />
<object-type name="OtherDerived" />
@@ -9,6 +10,10 @@
<value-type name="ExtendsNoImplicitConversion" />
<value-type name="Number" />
+ <smart-pointer-type name="SharedPtr" type="shared" getter="data" ref-count-method="useCount"
+ instantiations="Str"/>
+ <value-type name="SmartPtrTester"/>
+
<suppress-warning text="signature 'operator!=(ByteArray,const char*)' for function modification in 'ByteArray' not found." />
<suppress-warning text="signature 'operator+(ByteArray,const char*)' for function modification in 'ByteArray' not found." />
<suppress-warning text="signature 'operator==(ByteArray,const char*)' for function modification in 'ByteArray' not found." />
diff --git a/sources/shiboken2/tests/samplebinding/CMakeLists.txt b/sources/shiboken2/tests/samplebinding/CMakeLists.txt
index 61090d30e..b65068dc3 100644
--- a/sources/shiboken2/tests/samplebinding/CMakeLists.txt
+++ b/sources/shiboken2/tests/samplebinding/CMakeLists.txt
@@ -94,6 +94,8 @@ ${CMAKE_CURRENT_BINARY_DIR}/sample/rect_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/rectf_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/reference_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/referentmodelindex_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/toberenamedvalue_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/renameduser_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/sample_module_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/sample_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/sample_sample_wrapper.cpp
@@ -123,6 +125,7 @@ ${CMAKE_CURRENT_BINARY_DIR}/sample/filter_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/data_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/intersection_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/union_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/invisible_objectoninvisiblenamespace_wrapper.cpp
)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/sample-binding.txt.in"
diff --git a/sources/shiboken2/tests/samplebinding/global.h b/sources/shiboken2/tests/samplebinding/global.h
index 3984102a8..f4e20b74f 100644
--- a/sources/shiboken2/tests/samplebinding/global.h
+++ b/sources/shiboken2/tests/samplebinding/global.h
@@ -75,6 +75,7 @@
#include "protected.h"
#include "rect.h"
#include "reference.h"
+#include "renaming.h"
#include "removednamespaces.h"
#include "sample.h"
#include "samplenamespace.h"
diff --git a/sources/shiboken2/tests/samplebinding/namespace_test.py b/sources/shiboken2/tests/samplebinding/namespace_test.py
index aeaf81cff..b1977cf6f 100644
--- a/sources/shiboken2/tests/samplebinding/namespace_test.py
+++ b/sources/shiboken2/tests/samplebinding/namespace_test.py
@@ -40,12 +40,17 @@ from shiboken_paths import init_paths
init_paths()
from sample import *
+from helper import objectFullname
class TestEnumUnderNamespace(unittest.TestCase):
def testInvisibleNamespace(self):
o1 = EnumOnNamespace.Option1
self.assertEqual(o1, 1)
+ def testTpNames(self):
+ self.assertEqual(objectFullname(EnumOnNamespace), "sample.EnumOnNamespace")
+ self.assertEqual(str(EnumOnNamespace.Option1),
+ "sample.EnumOnNamespace.Option1")
class TestClassesUnderNamespace(unittest.TestCase):
def testIt(self):
@@ -72,5 +77,19 @@ class TestClassesUnderNamespace(unittest.TestCase):
self.assertEqual(str(SampleNamespace.SomeClass.SomeInnerClass.OkThisIsRecursiveEnough.NiceEnum),
"<class 'sample.SampleNamespace.SomeClass.SomeInnerClass.OkThisIsRecursiveEnough.NiceEnum'>")
+ # Test if enum inside of class is correct represented
+ self.assertEqual(objectFullname(SampleNamespace.enumInEnumOut.__signature__.parameters['in_'].annotation),
+ "sample.SampleNamespace.InValue")
+ self.assertEqual(objectFullname(SampleNamespace.enumAsInt.__signature__.parameters['value'].annotation),
+ "sample.SampleNamespace.SomeClass.PublicScopedEnum")
+ self.assertEqual(objectFullname(ObjectOnInvisibleNamespace.toInt.__signature__.parameters['e'].annotation),
+ "sample.EnumOnNamespace")
+
+ # Test if enum on namespace that was marked as not gerenated does not appear on type name
+ self.assertEqual(objectFullname(ObjectOnInvisibleNamespace),
+ "sample.ObjectOnInvisibleNamespace")
+ self.assertEqual(objectFullname(ObjectOnInvisibleNamespace.consume.__signature__.parameters['other'].annotation),
+ "sample.ObjectOnInvisibleNamespace")
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken2/tests/samplebinding/renaming_test.py b/sources/shiboken2/tests/samplebinding/renaming_test.py
new file mode 100644
index 000000000..cb59dce3a
--- /dev/null
+++ b/sources/shiboken2/tests/samplebinding/renaming_test.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+'''Test cases for renaming using target-lang-name attribute.'''
+
+import os
+import re
+import sys
+import unittest
+
+sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+from shiboken_paths import init_paths
+init_paths()
+
+from sample import RenamedValue, RenamedUser
+
+class RenamingTest(unittest.TestCase):
+ def test(self):
+ '''Tests whether the C++ class ToBeRenamedValue renamed via attribute
+ target-lang-name to RenamedValue shows up in consuming function
+ signature strings correctly.
+ '''
+ renamed_value = RenamedValue()
+ self.assertEqual(str(type(renamed_value)),
+ "<class 'sample.RenamedValue'>")
+ rename_user = RenamedUser()
+ rename_user.useRenamedValue(renamed_value)
+ actual_signature = str(rename_user.useRenamedValue.__signature__)
+ self.assertTrue(re.match(r"^\(self,\s*v:\s*sample.RenamedValue\)$",
+ actual_signature))
+
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
index 30ad5def7..c3db91324 100644
--- a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
+++ b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
@@ -543,8 +543,9 @@
<enum-type identified-by-value="AnonymousGlobalEnum_Value0"/>
- <namespace-type name="Invisible" generate="no">
+ <namespace-type name="Invisible" visible="no">
<enum-type name="EnumOnNamespace" />
+ <value-type name="ObjectOnInvisibleNamespace" />
</namespace-type>
<namespace-type name="SampleNamespace">
@@ -2432,6 +2433,9 @@
<modify-function signature="dummy(std::list&lt;std::pair&lt;BlackBox *, BlackBox *&gt; &gt; &amp;)" rename="dummy_method" />
</object-type>
+ <value-type name="ToBeRenamedValue" target-lang-name="RenamedValue"/>
+ <value-type name="RenamedUser"/>
+
<suppress-warning text="horribly broken type '__off64_t'" />
<suppress-warning text="enum '__codecvt_result' does not have a type entry or is not an enum" />
<suppress-warning text="Pure virtual method &quot;Abstract::hideFunction(HideType*)&quot; must be implement but was completely removed on typesystem." />
diff --git a/sources/shiboken2/tests/smartbinding/smart_pointer_test.py b/sources/shiboken2/tests/smartbinding/smart_pointer_test.py
index 6210916d3..50b2120a2 100644
--- a/sources/shiboken2/tests/smartbinding/smart_pointer_test.py
+++ b/sources/shiboken2/tests/smartbinding/smart_pointer_test.py
@@ -128,6 +128,10 @@ class SmartPointerTests(unittest.TestCase):
self.assertEqual(integer.m_int, 50)
# Set and get a member value via shared pointer (like operator->).
+ ptrToInteger.setValue(150)
+ self.assertEqual(ptrToInteger.value(), 150)
+
+ # Set and get a member field via shared pointer (like operator->).
ptrToInteger.m_int = 100
self.assertEqual(ptrToInteger.m_int, 100)
@@ -155,6 +159,18 @@ class SmartPointerTests(unittest.TestCase):
self.assertEqual(objCount(), 0)
self.assertEqual(integerCount(), 0)
+ def testConstIntegerSmartPointer(self):
+ # Uncomment to see more debug info about creation of objects and ref counts.
+ # Registry.getInstance().setShouldPrint(True)
+
+ # Create Obj.
+ o = Obj()
+ ptrToConstInteger = o.giveSharedPtrToConstInteger()
+ self.assertEqual(ptrToConstInteger.m_int, 456)
+ result = o.takeSharedPtrToConstInteger(ptrToConstInteger)
+ self.assertEqual(result, 456)
+ self.assertEqual(ptrToConstInteger.value(), 456)
+
def testSmartPointersWithNamespace(self):
# Create the main object
o = Obj()
diff --git a/sources/shiboken2/tests/smartbinding/typesystem_smart.xml b/sources/shiboken2/tests/smartbinding/typesystem_smart.xml
index 0bb485957..8fb3082a0 100644
--- a/sources/shiboken2/tests/smartbinding/typesystem_smart.xml
+++ b/sources/shiboken2/tests/smartbinding/typesystem_smart.xml
@@ -43,7 +43,8 @@
possible to explicitly instantiate a new shared pointer in python e.g. o = SharedPtr_Foo()
won't work.
-->
- <smart-pointer-type name="SharedPtr" type="shared" getter="data" ref-count-method="useCount" />
+ <smart-pointer-type name="SharedPtr" type="shared" getter="data" ref-count-method="useCount"
+ instantiations="Integer,Smart::Integer2,Obj"/>
<object-type name="Obj" />
<value-type name="Integer" />