aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2')
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp216
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.h11
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h9
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.cpp155
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.h49
-rw-r--r--sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp79
-rw-r--r--sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp2
-rw-r--r--sources/shiboken2/ApiExtractor/header_paths.h4
-rw-r--r--sources/shiboken2/ApiExtractor/messages.cpp23
-rw-r--r--sources/shiboken2/ApiExtractor/messages.h7
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp66
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp2
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testresolvetype.cpp16
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testtemplates.cpp32
-rw-r--r--sources/shiboken2/ApiExtractor/typedatabase.cpp8
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.cpp288
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.h184
-rw-r--r--sources/shiboken2/ApiExtractor/typesystemparser.cpp385
-rw-r--r--sources/shiboken2/ApiExtractor/typesystemparser.h6
-rw-r--r--sources/shiboken2/data/shiboken_helpers.cmake17
-rw-r--r--sources/shiboken2/generator/generator.cpp18
-rw-r--r--sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp97
-rw-r--r--sources/shiboken2/generator/qtdoc/qtdocgenerator.h20
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp109
-rw-r--r--sources/shiboken2/generator/shiboken2/headergenerator.cpp7
-rw-r--r--sources/shiboken2/generator/shiboken2/overloaddata.cpp16
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.cpp41
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.h5
-rw-r--r--sources/shiboken2/libshiboken/CMakeLists.txt10
-rw-r--r--sources/shiboken2/libshiboken/basewrapper.cpp12
-rw-r--r--sources/shiboken2/libshiboken/embed/embedding_generator.py4
-rw-r--r--sources/shiboken2/libshiboken/helper.cpp3
-rw-r--r--sources/shiboken2/libshiboken/pep384impl.cpp42
-rw-r--r--sources/shiboken2/libshiboken/pep384impl.h2
-rw-r--r--sources/shiboken2/libshiboken/sbkenum.cpp7
-rw-r--r--sources/shiboken2/libshiboken/sbkstaticstrings.cpp92
-rw-r--r--sources/shiboken2/libshiboken/sbkstaticstrings.h65
-rw-r--r--sources/shiboken2/libshiboken/sbkstaticstrings_p.h73
-rw-r--r--sources/shiboken2/libshiboken/sbkstring.cpp71
-rw-r--r--sources/shiboken2/libshiboken/sbkstring.h10
-rw-r--r--sources/shiboken2/libshiboken/shiboken.h1
-rw-r--r--sources/shiboken2/libshiboken/signature.cpp145
-rw-r--r--sources/shiboken2/libshiboken/signature.h2
-rw-r--r--sources/shiboken2/libshiboken/signature_doc.rst21
-rw-r--r--sources/shiboken2/libshiboken/typespec.cpp3
-rw-r--r--sources/shiboken2/shiboken_version.py7
-rw-r--r--sources/shiboken2/shibokenmodule/CMakeLists.txt2
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/backport_inspect.py4
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/importhandler.py103
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py82
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py12
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py175
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py110
-rw-r--r--sources/shiboken2/tests/libsmart/smart.cpp49
-rw-r--r--sources/shiboken2/tests/libsmart/smart.h194
-rw-r--r--sources/shiboken2/tests/libsmart/smart_integer.h52
-rw-r--r--sources/shiboken2/tests/libsmart/smart_obj.h60
-rw-r--r--sources/shiboken2/tests/libsmart/smart_registry.h68
-rw-r--r--sources/shiboken2/tests/libsmart/smart_sharedptr.h140
-rw-r--r--sources/shiboken2/tests/samplebinding/pointerprimitivetype_test.py79
-rw-r--r--sources/shiboken2/tests/samplebinding/typesystem_sample.xml1
61 files changed, 2264 insertions, 1309 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
index 84721968d..4566ed3bc 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
@@ -539,9 +539,6 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
cls->addDefaultCopyConstructor(ancestorHasPrivateCopyConstructor(cls));
}
}
-
- if (cls->isAbstract() && !cls->isInterface())
- cls->typeEntry()->setLookupName(cls->typeEntry()->targetLangName() + QLatin1String("$ConcreteWrapper"));
}
const auto &allEntries = types->entries();
@@ -584,7 +581,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
AbstractMetaClass *cls = AbstractMetaClass::findClass(m_metaClasses, name);
const bool enumFound = cls
- ? cls->findEnum(entry->targetLangName()) != nullptr
+ ? cls->findEnum(entry->targetLangEntryName()) != nullptr
: m_enums.contains(entry);
if (!enumFound) {
@@ -836,13 +833,10 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(const EnumModelItem &
QString qualifiedName = enumItem->qualifiedName().join(colonColon());
TypeEntry *typeEntry = nullptr;
+ const TypeEntry *enclosingTypeEntry = enclosing ? enclosing->typeEntry() : nullptr;
if (enumItem->accessPolicy() == CodeModel::Private) {
- QStringList names = enumItem->qualifiedName();
- const QString &enumName = names.constLast();
- QString nspace;
- if (names.size() > 1)
- nspace = QStringList(names.mid(0, names.size() - 1)).join(colonColon());
- typeEntry = new EnumTypeEntry(nspace, enumName, QVersionNumber(0, 0));
+ typeEntry = new EnumTypeEntry(enumItem->qualifiedName().constLast(),
+ QVersionNumber(0, 0), enclosingTypeEntry);
TypeDatabase::instance()->addType(typeEntry);
} else if (enumItem->enumKind() != AnonymousEnum) {
typeEntry = TypeDatabase::instance()->findType(qualifiedName);
@@ -862,8 +856,8 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(const EnumModelItem &
QString enumName = enumItem->name();
QString className;
- if (enclosing)
- className = enclosing->typeEntry()->qualifiedCppName();
+ if (enclosingTypeEntry)
+ className = enclosingTypeEntry->qualifiedCppName();
QString rejectReason;
if (TypeDatabase::instance()->isEnumRejected(className, enumName, &rejectReason)) {
@@ -945,25 +939,13 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(const EnumModelItem &
metaEnum->setOriginalAttributes(metaEnum->attributes());
// Register all enum values on Type database
- QString prefix;
- if (enclosing) {
- prefix += enclosing->typeEntry()->qualifiedCppName();
- prefix += colonColon();
- }
- if (enumItem->enumKind() == EnumClass) {
- prefix += enumItem->name();
- prefix += colonColon();
- }
+ const bool isScopedEnum = enumItem->enumKind() == EnumClass;
const EnumeratorList &enumerators = enumItem->enumerators();
for (const EnumeratorModelItem &e : enumerators) {
- QString name;
- if (enclosing) {
- name += enclosing->name();
- name += colonColon();
- }
- EnumValueTypeEntry *enumValue =
- new EnumValueTypeEntry(prefix + e->name(), e->stringValue(),
- enumTypeEntry, enumTypeEntry->version());
+ auto enumValue =
+ new EnumValueTypeEntry(e->name(), e->stringValue(),
+ enumTypeEntry, isScopedEnum,
+ enumTypeEntry->version());
TypeDatabase::instance()->addType(enumValue);
if (e->value().isNullValue())
enumTypeEntry->setNullValue(enumValue);
@@ -1097,9 +1079,11 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
TemplateParameterList template_parameters = classItem->templateParameters();
QVector<TypeEntry *> template_args;
template_args.clear();
+ auto argumentParent = metaClass->typeEntry()->typeSystemTypeEntry();
for (int i = 0; i < template_parameters.size(); ++i) {
const TemplateParameterModelItem &param = template_parameters.at(i);
- TemplateArgumentEntry *param_type = new TemplateArgumentEntry(param->name(), type->version());
+ auto param_type = new TemplateArgumentEntry(param->name(), type->version(),
+ argumentParent);
param_type->setOrdinal(i);
template_args.append(param_type);
}
@@ -1300,27 +1284,37 @@ void AbstractMetaBuilderPrivate::fixReturnTypeOfConversionOperator(AbstractMetaF
metaFunction->replaceType(metaType);
}
-static bool _compareAbstractMetaTypes(const AbstractMetaType *type, const AbstractMetaType *other)
+static bool _compareAbstractMetaTypes(const AbstractMetaType *type,
+ const AbstractMetaType *other,
+ AbstractMetaType::ComparisonFlags flags = {})
{
return (type != nullptr) == (other != nullptr)
- && (type == nullptr || *type == *other);
+ && (type == nullptr || type->compare(*other, flags));
}
-static bool _compareAbstractMetaFunctions(const AbstractMetaFunction *func, const AbstractMetaFunction *other)
+static bool _compareAbstractMetaFunctions(const AbstractMetaFunction *func,
+ const AbstractMetaFunction *other,
+ AbstractMetaType::ComparisonFlags argumentFlags = {})
{
if (!func && !other)
return true;
if (!func || !other)
return false;
- if (func->arguments().count() != other->arguments().count()
+ 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 < func->arguments().count(); ++i) {
- if (!_compareAbstractMetaTypes(func->arguments().at(i)->type(), other->arguments().at(i)->type()))
+ for (int i = 0; i < argumentsCount; ++i) {
+ if (!_compareAbstractMetaTypes(func->arguments().at(i)->type(),
+ other->arguments().at(i)->type(),
+ argumentFlags)) {
return false;
+ }
}
return true;
}
@@ -1346,29 +1340,6 @@ AbstractMetaFunctionList AbstractMetaBuilderPrivate::classFunctionList(const Sco
return result;
}
-// For template classes, entries with more specific types may exist from out-of-
-// line definitions. If there is a declaration which matches it after fixing
-// the parameters, remove it as duplicate. For example:
-// template class<T> Vector { public:
-// Vector(const Vector &rhs);
-// };
-// template class<T>
-// Vector<T>::Vector(const Vector<T>&) {} // More specific, remove declaration.
-
-class DuplicatingFunctionPredicate : public std::unary_function<bool, const AbstractMetaFunction *> {
-public:
- explicit DuplicatingFunctionPredicate(const AbstractMetaFunction *f) : m_function(f) {}
-
- bool operator()(const AbstractMetaFunction *rhs) const
- {
- return rhs != m_function && rhs->name() == m_function->name()
- && _compareAbstractMetaFunctions(m_function, rhs);
- }
-
-private:
- const AbstractMetaFunction *m_function;
-};
-
void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem,
AbstractMetaClass *metaClass)
{
@@ -1418,13 +1389,6 @@ void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem,
metaClass->setHasNonPrivateConstructor(true);
}
- // Classes with virtual destructors should always have a shell class
- // (since we aren't registering the destructors, we need this extra check)
- if (metaFunction->isDestructor() && metaFunction->isVirtual()
- && metaFunction->visibility() != AbstractMetaAttributes::Private) {
- metaClass->setForceShellClass(true);
- }
-
if (!metaFunction->isDestructor()
&& !(metaFunction->isPrivate() && metaFunction->functionType() == AbstractMetaFunction::ConstructorFunction)) {
@@ -1607,8 +1571,13 @@ void AbstractMetaBuilderPrivate::traverseEnums(const ScopeModelItem &scopeItem,
const QStringList &enumsDeclarations)
{
const EnumList &enums = scopeItem->enums();
+#if QT_VERSION >= 0x050E00
+ const QSet<QString> enumsDeclarationSet(enumsDeclarations.cbegin(), enumsDeclarations.cend());
+#else
+ const QSet<QString> enumsDeclarationSet = QSet<QString>::fromList(enumsDeclarations);
+#endif
for (const EnumModelItem &enumItem : enums) {
- AbstractMetaEnum* metaEnum = traverseEnum(enumItem, metaClass, QSet<QString>::fromList(enumsDeclarations));
+ AbstractMetaEnum* metaEnum = traverseEnum(enumItem, metaClass, enumsDeclarationSet);
if (metaEnum) {
metaClass->addEnum(metaEnum);
metaEnum->setEnclosingClass(metaClass);
@@ -1616,6 +1585,26 @@ void AbstractMetaBuilderPrivate::traverseEnums(const ScopeModelItem &scopeItem,
}
}
+static void applyDefaultExpressionModifications(const FunctionModificationList &functionMods,
+ int i, AbstractMetaArgument *metaArg)
+{
+ // use replace/remove-default-expression for set default value
+ for (const auto &modification : functionMods) {
+ for (const auto &argumentModification : modification.argument_mods) {
+ if (argumentModification.index == i + 1) {
+ if (argumentModification.removedDefaultExpression) {
+ metaArg->setDefaultValueExpression(QString());
+ break;
+ }
+ if (!argumentModification.replacedDefaultExpression.isEmpty()) {
+ metaArg->setDefaultValueExpression(argumentModification.replacedDefaultExpression);
+ break;
+ }
+ }
+ }
+ }
+}
+
AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFunctionPtr &addedFunc)
{
return traverseFunction(addedFunc, nullptr);
@@ -1674,20 +1663,13 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu
// Find the correct default values
+ const FunctionModificationList functionMods = metaFunction->modifications(metaClass);
for (int i = 0; i < metaArguments.size(); ++i) {
AbstractMetaArgument* metaArg = metaArguments.at(i);
- //use relace-default-expression for set default value
- QString replacedExpression;
- if (metaClass)
- replacedExpression = metaFunction->replacedDefaultExpression(metaClass, i + 1);
-
- if (!replacedExpression.isEmpty()) {
- if (!metaFunction->removedDefaultExpression(metaClass, i + 1)) {
- metaArg->setDefaultValueExpression(replacedExpression);
- metaArg->setOriginalDefaultValueExpression(replacedExpression);
- }
- }
+ // use replace-default-expression for set default value
+ applyDefaultExpressionModifications(functionMods, i, metaArg);
+ metaArg->setOriginalDefaultValueExpression(metaArg->defaultValueExpression()); // appear unmodified
}
metaFunction->setOriginalAttributes(metaFunction->attributes());
@@ -1919,7 +1901,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
AbstractMetaType *type = nullptr;
if (!returnType.isVoid()) {
- type = translateType(returnType, currentClass, true, &errorMessage);
+ type = translateType(returnType, currentClass, {}, &errorMessage);
if (!type) {
const QString reason = msgUnmatchedReturnType(functionItem, errorMessage);
qCWarning(lcShiboken, "%s",
@@ -1955,7 +1937,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
return nullptr;
}
- AbstractMetaType *metaType = translateType(arg->type(), currentClass, true, &errorMessage);
+ AbstractMetaType *metaType = translateType(arg->type(), currentClass, {}, &errorMessage);
if (!metaType) {
// If an invalid argument has a default value, simply remove it
if (arg->defaultValue()) {
@@ -2006,35 +1988,16 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
const ArgumentModelItem &arg = arguments.at(i);
AbstractMetaArgument* metaArg = metaArguments.at(i);
- //use relace-default-expression for set default value
- QString replacedExpression;
- if (currentClass) {
- replacedExpression = metaFunction->replacedDefaultExpression(currentClass, i + 1);
- } else {
- if (!functionMods.isEmpty()) {
- QVector<ArgumentModification> argMods = functionMods.constFirst().argument_mods;
- if (!argMods.isEmpty())
- replacedExpression = argMods.constFirst().replacedDefaultExpression;
- }
- }
+ const QString originalDefaultExpression =
+ fixDefaultValue(arg, metaArg->type(), metaFunction, currentClass, i);
- bool hasDefaultValue = false;
- if (arg->defaultValue() || !replacedExpression.isEmpty()) {
- QString expr = arg->defaultValueExpression();
- expr = fixDefaultValue(arg, metaArg->type(), metaFunction, currentClass, i);
- metaArg->setOriginalDefaultValueExpression(expr);
+ metaArg->setOriginalDefaultValueExpression(originalDefaultExpression);
+ metaArg->setDefaultValueExpression(originalDefaultExpression);
- if (metaFunction->removedDefaultExpression(currentClass, i + 1)) {
- expr.clear();
- } else if (!replacedExpression.isEmpty()) {
- expr = replacedExpression;
- }
- metaArg->setDefaultValueExpression(expr);
- hasDefaultValue = !expr.isEmpty();
- }
+ applyDefaultExpressionModifications(functionMods, i, metaArg);
//Check for missing argument name
- if (hasDefaultValue
+ if (!metaArg->defaultValueExpression().isEmpty()
&& !metaArg->hasName()
&& !metaFunction->isOperatorOverload()
&& !metaFunction->isSignal()
@@ -2159,22 +2122,27 @@ static const TypeEntry* findTypeEntryUsingContext(const AbstractMetaClass* metaC
AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typei,
AbstractMetaClass *currentClass,
- bool resolveType,
+ TranslateTypeFlags flags,
QString *errorMessage)
{
- return translateTypeStatic(_typei, currentClass, this, resolveType, errorMessage);
+ return translateTypeStatic(_typei, currentClass, this, flags, errorMessage);
}
AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo &_typei,
AbstractMetaClass *currentClass,
AbstractMetaBuilderPrivate *d,
- bool resolveType,
+ TranslateTypeFlags flags,
QString *errorMessageIn)
{
// 1. Test the type info without resolving typedefs in case this is present in the
// type system
+ const bool resolveType = !flags.testFlag(AbstractMetaBuilder::DontResolveType);
if (resolveType) {
- if (AbstractMetaType *resolved = translateTypeStatic(_typei, currentClass, d, false, errorMessageIn))
+ AbstractMetaType *resolved =
+ translateTypeStatic(_typei, currentClass, d,
+ flags | AbstractMetaBuilder::DontResolveType,
+ errorMessageIn);
+ if (resolved)
return resolved;
}
@@ -2233,7 +2201,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo
newInfo.setReferenceType(typeInfo.referenceType());
newInfo.setVolatile(typeInfo.isVolatile());
- AbstractMetaType *elementType = translateTypeStatic(newInfo, currentClass, d, true, &errorMessage);
+ AbstractMetaType *elementType = translateTypeStatic(newInfo, currentClass, d, flags, &errorMessage);
if (!elementType) {
if (errorMessageIn) {
errorMessage.prepend(QLatin1String("Unable to translate array element: "));
@@ -2254,7 +2222,9 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo
if (_ok)
arrayType->setArrayElementCount(int(elems));
}
- arrayType->setTypeEntry(new ArrayTypeEntry(elementType->typeEntry() , elementType->typeEntry()->version()));
+ auto elementTypeEntry = elementType->typeEntry();
+ arrayType->setTypeEntry(new ArrayTypeEntry(elementTypeEntry, elementTypeEntry->version(),
+ elementTypeEntry->parent()));
arrayType->decideUsagePattern();
elementType = arrayType;
@@ -2344,7 +2314,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo
const auto &templateArguments = typeInfo.instantiations();
for (int t = 0, size = templateArguments.size(); t < size; ++t) {
const TypeInfo &ti = templateArguments.at(t);
- AbstractMetaType *targType = translateTypeStatic(ti, currentClass, d, true, &errorMessage);
+ AbstractMetaType *targType = translateTypeStatic(ti, currentClass, d, flags, &errorMessage);
if (!targType) {
if (errorMessageIn)
*errorMessageIn = msgCannotTranslateTemplateArgument(t, ti, errorMessage);
@@ -2366,17 +2336,17 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo
AbstractMetaType *AbstractMetaBuilder::translateType(const TypeInfo &_typei,
AbstractMetaClass *currentClass,
- bool resolveType,
+ TranslateTypeFlags flags,
QString *errorMessage)
{
return AbstractMetaBuilderPrivate::translateTypeStatic(_typei, currentClass,
- nullptr, resolveType,
+ nullptr, flags,
errorMessage);
}
AbstractMetaType *AbstractMetaBuilder::translateType(const QString &t,
AbstractMetaClass *currentClass,
- bool resolveType,
+ TranslateTypeFlags flags,
QString *errorMessageIn)
{
QString errorMessage;
@@ -2389,7 +2359,7 @@ AbstractMetaType *AbstractMetaBuilder::translateType(const QString &t,
qCWarning(lcShiboken, "%s", qPrintable(errorMessage));
return nullptr;
}
- return translateType(typeInfo, currentClass, resolveType, errorMessageIn);
+ return translateType(typeInfo, currentClass, flags, errorMessageIn);
}
qint64 AbstractMetaBuilderPrivate::findOutValueFromString(const QString &stringValue, bool &ok)
@@ -2435,10 +2405,10 @@ QString AbstractMetaBuilderPrivate::fixDefaultValue(const ArgumentModelItem &ite
AbstractMetaClass *implementingClass,
int /* argumentIndex */)
{
- QString functionName = fnc->name();
- QString className = implementingClass ? implementingClass->qualifiedCppName() : QString();
-
QString expr = item->defaultValueExpression();
+ if (expr.isEmpty())
+ return expr;
+
if (type) {
if (type->isPrimitive()) {
if (type->name() == QLatin1String("boolean")) {
@@ -2512,11 +2482,12 @@ QString AbstractMetaBuilderPrivate::fixDefaultValue(const ArgumentModelItem &ite
}
}
} else {
+ const QString className = implementingClass ? implementingClass->qualifiedCppName() : QString();
qCWarning(lcShiboken).noquote().nospace()
<< QStringLiteral("undefined type for default value '%3' of argument in function '%1', class '%2'")
- .arg(functionName, className, item->defaultValueExpression());
+ .arg(fnc->name(), className, item->defaultValueExpression());
- expr = QString();
+ expr.clear();
}
return expr;
@@ -2676,8 +2647,7 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass,
if (isNumber) {
t = typeDb->findType(typeName);
if (!t) {
- t = new EnumValueTypeEntry(typeName, typeName, nullptr,
- QVersionNumber(0, 0));
+ t = new ConstantValueTypeEntry(typeName, subclass->typeEntry()->typeSystemTypeEntry());
t->setCodeGeneration(0);
typeDb->addType(t);
}
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
index 1789ca2aa..93b9d9fd2 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
@@ -90,13 +90,18 @@ public:
void setSkipDeprecated(bool value);
+ enum TranslateTypeFlag {
+ DontResolveType = 0x1
+ };
+ Q_DECLARE_FLAGS(TranslateTypeFlags, TranslateTypeFlag);
+
static AbstractMetaType *translateType(const TypeInfo &_typei,
AbstractMetaClass *currentClass = nullptr,
- bool resolveType = true,
+ TranslateTypeFlags flags = {},
QString *errorMessage = nullptr);
static AbstractMetaType *translateType(const QString &t,
AbstractMetaClass *currentClass = nullptr,
- bool resolveType = true,
+ TranslateTypeFlags flags = {},
QString *errorMessage = nullptr);
@@ -109,6 +114,8 @@ private:
AbstractMetaBuilderPrivate *d;
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaBuilder::TranslateTypeFlags);
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug d, const AbstractMetaBuilder &ab);
#endif
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
index 18c5afc17..b381a62cd 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
@@ -37,12 +37,15 @@
#include <QSet>
#include <QFileInfo>
+#include <QVector>
class TypeDatabase;
class AbstractMetaBuilderPrivate
{
public:
+ using TranslateTypeFlags = AbstractMetaBuilder::TranslateTypeFlags;
+
Q_DISABLE_COPY(AbstractMetaBuilderPrivate)
AbstractMetaBuilderPrivate();
@@ -136,12 +139,12 @@ public:
AbstractMetaType *translateType(const AddedFunction::TypeInfo &typeInfo);
AbstractMetaType *translateType(const TypeInfo &type,
AbstractMetaClass *currentClass,
- bool resolveType = true,
+ TranslateTypeFlags flags = {},
QString *errorMessage = nullptr);
static AbstractMetaType *translateTypeStatic(const TypeInfo &type,
AbstractMetaClass *current,
AbstractMetaBuilderPrivate *d = nullptr,
- bool resolveType = true,
+ TranslateTypeFlags flags = {},
QString *errorMessageIn = nullptr);
qint64 findOutValueFromString(const QString &stringValue, bool &ok);
@@ -185,7 +188,7 @@ public:
QHash<const TypeEntry *, AbstractMetaEnum *> m_enums;
- QList<NamespaceModelItem> m_scopes;
+ QVector<NamespaceModelItem> m_scopes;
QSet<AbstractMetaClass *> m_setupInheritanceDone;
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
index 455140e59..5ae671d87 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -166,19 +166,9 @@ QString AbstractMetaType::package() const
return m_typeEntry->targetLangPackage();
}
-static QString lastNameSegment(QString name)
-{
- const int index = name.lastIndexOf(QStringLiteral("::"));
- if (index >= 0)
- name.remove(0, index + 2);
- return name;
-}
-
QString AbstractMetaType::name() const
{
- if (m_name.isEmpty())
- m_name = lastNameSegment(m_typeEntry->targetLangName());
- return m_name;
+ return m_typeEntry->targetLangEntryName();
}
QString AbstractMetaType::fullName() const
@@ -256,11 +246,16 @@ AbstractMetaTypeCList AbstractMetaType::nestedArrayTypes() const
return result;
}
-bool AbstractMetaType::isConstRef() const
+bool AbstractMetaType::passByConstRef() const
{
return isConstant() && m_referenceType == LValueReference && indirections() == 0;
}
+bool AbstractMetaType::passByValue() const
+{
+ return m_referenceType == NoReference && indirections() == 0;
+}
+
QString AbstractMetaType::cppSignature() const
{
if (m_cachedCppSignature.isEmpty())
@@ -268,12 +263,21 @@ QString AbstractMetaType::cppSignature() const
return m_cachedCppSignature;
}
+QString AbstractMetaType::pythonSignature() const
+{
+ // PYSIDE-921: Handle container returntypes correctly.
+ // This is now a clean reimplementation.
+ if (m_cachedPythonSignature.isEmpty())
+ m_cachedPythonSignature = formatPythonSignature(false);
+ return m_cachedPythonSignature;
+}
+
AbstractMetaType::TypeUsagePattern AbstractMetaType::determineUsagePattern() const
{
if (m_typeEntry->isTemplateArgument() || m_referenceType == RValueReference)
return InvalidPattern;
- if (m_typeEntry->isPrimitive() && (actualIndirections() == 0 || isConstRef()))
+ if (m_typeEntry->isPrimitive() && (actualIndirections() == 0 || passByConstRef()))
return PrimitivePattern;
if (m_typeEntry->isVoid())
@@ -282,7 +286,7 @@ AbstractMetaType::TypeUsagePattern AbstractMetaType::determineUsagePattern() con
if (m_typeEntry->isVarargs())
return VarargsPattern;
- if (m_typeEntry->isEnum() && (actualIndirections() == 0 || isConstRef()))
+ if (m_typeEntry->isEnum() && (actualIndirections() == 0 || passByConstRef()))
return EnumPattern;
if (m_typeEntry->isObject()) {
@@ -297,7 +301,7 @@ AbstractMetaType::TypeUsagePattern AbstractMetaType::determineUsagePattern() con
if (m_typeEntry->isSmartPointer() && indirections() == 0)
return SmartPointerPattern;
- if (m_typeEntry->isFlags() && (actualIndirections() == 0 || isConstRef()))
+ if (m_typeEntry->isFlags() && (actualIndirections() == 0 || passByConstRef()))
return FlagsPattern;
if (m_typeEntry->isArray())
@@ -343,21 +347,29 @@ bool AbstractMetaType::hasTemplateChildren() const
return false;
}
-bool AbstractMetaType::equals(const AbstractMetaType &rhs) const
+bool AbstractMetaType::compare(const AbstractMetaType &rhs, ComparisonFlags flags) const
{
- if (m_typeEntry != rhs.m_typeEntry || m_constant != rhs.m_constant
- || m_referenceType != rhs.m_referenceType
+ if (m_typeEntry != rhs.m_typeEntry
|| m_indirections != rhs.m_indirections
|| m_instantiations.size() != rhs.m_instantiations.size()
|| m_arrayElementCount != rhs.m_arrayElementCount) {
return false;
}
+
+ if (m_constant != rhs.m_constant || m_referenceType != rhs.m_referenceType) {
+ if (!flags.testFlag(ConstRefMatchesValue)
+ || !(passByValue() || passByConstRef())
+ || !(rhs.passByValue() || rhs.passByConstRef())) {
+ return false;
+ }
+ }
+
if ((m_arrayElementType != nullptr) != (rhs.m_arrayElementType != nullptr)
- || (m_arrayElementType != nullptr && !m_arrayElementType->equals(*rhs.m_arrayElementType))) {
+ || (m_arrayElementType != nullptr && !m_arrayElementType->compare(*rhs.m_arrayElementType, flags))) {
return false;
}
for (int i = 0, size = m_instantiations.size(); i < size; ++i) {
- if (!m_instantiations.at(i)->equals(*rhs.m_instantiations.at(i)))
+ if (!m_instantiations.at(i)->compare(*rhs.m_instantiations.at(i), flags))
return false;
}
return true;
@@ -722,37 +734,6 @@ ArgumentOwner AbstractMetaFunction::argumentOwner(const AbstractMetaClass *cls,
return ArgumentOwner();
}
-
-QString AbstractMetaFunction::replacedDefaultExpression(const AbstractMetaClass *cls, int key) const
-{
- const FunctionModificationList &modifications = this->modifications(cls);
- for (const FunctionModification &modification : modifications) {
- for (const ArgumentModification &argumentModification : modification.argument_mods) {
- if (argumentModification.index == key
- && !argumentModification.replacedDefaultExpression.isEmpty()) {
- return argumentModification.replacedDefaultExpression;
- }
- }
- }
-
- return QString();
-}
-
-bool AbstractMetaFunction::removedDefaultExpression(const AbstractMetaClass *cls, int key) const
-{
- const FunctionModificationList &modifications = this->modifications(cls);
- for (const FunctionModification &modification : modifications) {
- for (const ArgumentModification &argumentModification : modification.argument_mods) {
- if (argumentModification.index == key
- && argumentModification.removedDefaultExpression) {
- return true;
- }
- }
- }
-
- return false;
-}
-
QString AbstractMetaFunction::conversionRule(TypeSystem::Language language, int key) const
{
const FunctionModificationList &modifications = this->modifications(declaringClass());
@@ -771,19 +752,6 @@ QString AbstractMetaFunction::conversionRule(TypeSystem::Language language, int
return QString();
}
-QString AbstractMetaFunction::argumentReplaced(int key) const
-{
- const FunctionModificationList &modifications = this->modifications(declaringClass());
- for (const FunctionModification &modification : modifications) {
- for (const ArgumentModification &argumentModification : modification.argument_mods) {
- if (argumentModification.index == key && !argumentModification.replace_value.isEmpty())
- return argumentModification.replace_value;
- }
- }
-
- return QString();
-}
-
// FIXME If we remove a arg. in the method at the base class, it will not reflect here.
bool AbstractMetaFunction::argumentRemoved(int key) const
{
@@ -1361,7 +1329,6 @@ AbstractMetaClass::AbstractMetaClass()
m_hasPrivateDestructor(false),
m_hasProtectedDestructor(false),
m_hasVirtualDestructor(false),
- m_forceShellClass(false),
m_hasHashFunction(false),
m_hasEqualsOperator(false),
m_hasCloneOperator(false),
@@ -1634,7 +1601,7 @@ bool AbstractMetaClass::hasSignal(const AbstractMetaFunction *other) const
QString AbstractMetaClass::name() const
{
- return lastNameSegment(m_typeEntry->targetLangName());
+ return m_typeEntry->targetLangEntryName();
}
void AbstractMetaClass::setBaseClass(AbstractMetaClass *baseClass)
@@ -2555,6 +2522,58 @@ QString AbstractMetaType::formatSignature(bool minimal) const
return result;
}
+QString AbstractMetaType::formatPythonSignature(bool minimal) const
+{
+ /*
+ * This is a version of the above, more suitable for Python.
+ * We avoid extra keywords that are not needed in Python.
+ * We prepend the package name, unless it is a primitive type.
+ *
+ * Primitive types like 'int', 'char' etc.:
+ * When we have a primitive with an indirection, we use that '*'
+ * character for later postprocessing, since those indirections
+ * need to be modified into a result tuple.
+ */
+ QString result;
+ if (m_pattern == AbstractMetaType::NativePointerAsArrayPattern)
+ result += QLatin1String("array ");
+ // We no longer use the "const" qualifier for heuristics. Instead,
+ // NativePointerAsArrayPattern indicates when we have <array> in XML.
+ // if (m_typeEntry->isPrimitive() && isConstant())
+ // result += QLatin1String("const ");
+ if (!m_typeEntry->isPrimitive() && !package().isEmpty())
+ result += package() + QLatin1Char('.');
+ if (isArray()) {
+ // Build nested array dimensions a[2][3] in correct order
+ result += m_arrayElementType->formatPythonSignature(true);
+ const int arrayPos = result.indexOf(QLatin1Char('['));
+ if (arrayPos != -1)
+ result.insert(arrayPos, formatArraySize(m_arrayElementCount));
+ else
+ result.append(formatArraySize(m_arrayElementCount));
+ } else {
+ result += typeEntry()->targetLangName();
+ }
+ if (!m_instantiations.isEmpty()) {
+ result += QLatin1Char('[');
+ for (int i = 0, size = m_instantiations.size(); i < size; ++i) {
+ if (i > 0)
+ result += QLatin1String(", ");
+ result += m_instantiations.at(i)->formatPythonSignature(true);
+ }
+ result += QLatin1Char(']');
+ }
+ if (m_typeEntry->isPrimitive())
+ for (Indirection i : m_indirections)
+ result += TypeInfo::indirectionKeyword(i);
+ // If it is a flags type, we replace it with the full name:
+ // "PySide2.QtCore.Qt.ItemFlags" instead of "PySide2.QtCore.QFlags<Qt.ItemFlag>"
+ if (m_typeEntry->isFlags())
+ result = fullName();
+ result.replace(QLatin1String("::"), QLatin1String("."));
+ return result;
+}
+
bool AbstractMetaType::isCppPrimitive() const
{
return m_pattern == PrimitivePattern && m_typeEntry->isCppPrimitive();
@@ -2762,7 +2781,7 @@ AbstractMetaEnumValue *AbstractMetaEnum::findEnumValue(const QString &value) con
QString AbstractMetaEnum::name() const
{
- return m_typeEntry->targetLangName();
+ return m_typeEntry->targetLangEntryName();
}
QString AbstractMetaEnum::qualifier() const
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h
index 91ca4d7a9..2ae1b6d21 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -249,21 +249,11 @@ public:
return m_originalAttributes & Private;
}
- bool wasProtected() const
- {
- return m_originalAttributes & Protected;
- }
-
bool wasPublic() const
{
return m_originalAttributes & Public;
}
- bool wasFriendly() const
- {
- return m_originalAttributes & Friendly;
- }
-
void setDocumentation(const Documentation& doc)
{
m_doc = doc;
@@ -312,6 +302,11 @@ public:
};
Q_ENUM(TypeUsagePattern)
+ enum ComparisonFlag {
+ ConstRefMatchesValue = 0x1
+ };
+ Q_DECLARE_FLAGS(ComparisonFlags, ComparisonFlag);
+
AbstractMetaType();
~AbstractMetaType();
@@ -438,7 +433,8 @@ public:
bool isVolatile() const { return m_volatile; }
void setVolatile(bool v) { m_volatile = v; }
- bool isConstRef() const;
+ bool passByConstRef() const;
+ bool passByValue() const;
ReferenceType referenceType() const { return m_referenceType; }
void setReferenceType(ReferenceType ref) { m_referenceType = ref; }
@@ -483,6 +479,8 @@ public:
QString cppSignature() const;
+ QString pythonSignature() const;
+
AbstractMetaType *copy() const;
bool applyArrayModification(QString *errorMessage);
@@ -535,17 +533,18 @@ public:
bool hasTemplateChildren() const;
- bool equals(const AbstractMetaType &rhs) const;
+ bool compare(const AbstractMetaType &rhs, ComparisonFlags = {}) const;
private:
TypeUsagePattern determineUsagePattern() const;
QString formatSignature(bool minimal) const;
+ QString formatPythonSignature(bool minimal) const;
const TypeEntry *m_typeEntry = nullptr;
AbstractMetaTypeList m_instantiations;
QString m_package;
- mutable QString m_name;
mutable QString m_cachedCppSignature;
+ mutable QString m_cachedPythonSignature;
QString m_originalTypeDescription;
int m_arrayElementCount = -1;
@@ -565,10 +564,12 @@ private:
Q_DISABLE_COPY(AbstractMetaType)
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaType::ComparisonFlags);
+
inline bool operator==(const AbstractMetaType &t1, const AbstractMetaType &t2)
-{ return t1.equals(t2); }
+{ return t1.compare(t2); }
inline bool operator!=(const AbstractMetaType &t1, const AbstractMetaType &t2)
-{ return !t1.equals(t2); }
+{ return !t1.compare(t2); }
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug d, const AbstractMetaType *at);
@@ -667,7 +668,9 @@ public:
}
bool hasDefaultValueExpression() const
- { return !m_originalExpression.isEmpty() || !m_expression.isEmpty(); }
+ { return !m_expression.isEmpty(); }
+ bool hasOriginalDefaultValueExpression() const
+ { return !m_originalExpression.isEmpty(); }
bool hasUnmodifiedDefaultValueExpression() const
{ return !m_originalExpression.isEmpty() && m_originalExpression == m_expression; }
bool hasModifiedDefaultValueExpression() const
@@ -886,7 +889,6 @@ public:
QString minimalSignature() const;
QString debugSignature() const; // including virtual/override/final, etc., for debugging only.
- QStringList possibleIntrospectionCompatibleSignatures() const;
bool isModifiedRemoved(int types = TypeSystem::All) const;
@@ -1016,8 +1018,6 @@ public:
AbstractMetaFunction *copy() const;
- QString replacedDefaultExpression(const AbstractMetaClass *cls, int idx) const;
- bool removedDefaultExpression(const AbstractMetaClass *cls, int idx) const;
QString conversionRule(TypeSystem::Language language, int idx) const;
QVector<ReferenceCount> referenceCounts(const AbstractMetaClass *cls, int idx = -2) const;
ArgumentOwner argumentOwner(const AbstractMetaClass *cls, int idx) const;
@@ -1030,9 +1030,6 @@ public:
bool isRemovedFromAllLanguages(const AbstractMetaClass *) const;
bool isRemovedFrom(const AbstractMetaClass *, TypeSystem::Language language) const;
bool argumentRemoved(int) const;
-
- QString argumentReplaced(int key) const;
-
/**
* Verifies if any modification to the function is an inject code.
* \return true if there is inject code modifications to the function.
@@ -1529,11 +1526,6 @@ public:
bool hasSignals() const;
bool inheritsFrom(const AbstractMetaClass *other) const;
- void setForceShellClass(bool on)
- {
- m_forceShellClass = on;
- }
-
/**
* Says if the class that declares or inherits a virtual function.
* \return true if the class implements or inherits any virtual methods
@@ -1731,7 +1723,6 @@ private:
uint m_hasPrivateDestructor : 1;
uint m_hasProtectedDestructor : 1;
uint m_hasVirtualDestructor : 1;
- uint m_forceShellClass : 1;
uint m_hasHashFunction : 1;
uint m_hasEqualsOperator : 1;
uint m_hasCloneOperator : 1;
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
index 8d1b4debf..a5b153499 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
@@ -40,7 +40,7 @@
#include <QtCore/QStack>
#include <QtCore/QVector>
-#include <string.h>
+#include <cstring>
#include <ctype.h>
#if QT_VERSION < 0x050800
@@ -202,6 +202,8 @@ public:
template <class Item>
void qualifyTypeDef(const CXCursor &typeRefCursor, const QSharedPointer<Item> &item) const;
+ bool visitHeader(const char *cFileName) const;
+
BaseVisitor *m_baseVisitor;
CodeModel *m_model;
@@ -665,31 +667,62 @@ Builder::~Builder()
delete d;
}
-static inline bool compareHeaderName(const char *haystack, const char *needle)
+static const char *cBaseName(const char *fileName)
{
- const char *lastSlash = strrchr(haystack, '/');
+ const char *lastSlash = std::strrchr(fileName, '/');
#ifdef Q_OS_WIN
if (lastSlash == nullptr)
- lastSlash = strrchr(haystack, '\\');
+ lastSlash = std::strrchr(fileName, '\\');
#endif
- if (lastSlash == nullptr)
- lastSlash = haystack;
- else
- ++lastSlash;
+ return lastSlash != nullptr ? (lastSlash + 1) : fileName;
+}
+
+static inline bool cCompareFileName(const char *f1, const char *f2)
+{
#ifdef Q_OS_WIN
- return _stricmp(lastSlash, needle) == 0;
+ return _stricmp(f1, f2) == 0;
#else
- return strcmp(lastSlash, needle) == 0;
+ return std::strcmp(f1, f2) == 0;
#endif
}
#ifdef Q_OS_UNIX
-static bool cStringStartsWith(const char *prefix, const char *str)
+template<size_t N>
+static bool cStringStartsWith(const char *str, const char (&prefix)[N])
{
- return strncmp(prefix, str, strlen(prefix)) == 0;
+ return std::strncmp(prefix, str, N - 1) == 0;
}
#endif
+bool BuilderPrivate::visitHeader(const char *cFileName) const
+{
+ // Resolve OpenGL typedefs although the header is considered a system header.
+ const char *baseName = cBaseName(cFileName);
+ if (cCompareFileName(baseName, "gl.h"))
+ return true;
+#if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
+ if (cStringStartsWith(cFileName, "/usr/include/stdint.h"))
+ return true;
+#endif
+#ifdef Q_OS_LINUX
+ if (cStringStartsWith(cFileName, "/usr/include/stdlib.h")
+ || cStringStartsWith(cFileName, "/usr/include/sys/types.h")) {
+ return true;
+ }
+#endif // Q_OS_LINUX
+#ifdef Q_OS_MACOS
+ // Parse the following system headers to get the correct typdefs for types like
+ // int32_t, which are used in the macOS implementation of OpenGL framework.
+ if (cCompareFileName(baseName, "gltypes.h")
+ || cStringStartsWith(cFileName, "/usr/include/_types")
+ || cStringStartsWith(cFileName, "/usr/include/_types")
+ || cStringStartsWith(cFileName, "/usr/include/sys/_types")) {
+ return true;
+ }
+#endif // Q_OS_MACOS
+ return false;
+}
+
bool Builder::visitLocation(const CXSourceLocation &location) const
{
if (clang_Location_isInSystemHeader(location) == 0)
@@ -701,28 +734,12 @@ bool Builder::visitLocation(const CXSourceLocation &location) const
clang_getExpansionLocation(location, &file, &line, &column, &offset);
const CXString cxFileName = clang_getFileName(file);
// Has been observed to be 0 for invalid locations
+ bool result = false;
if (const char *cFileName = clang_getCString(cxFileName)) {
- // Resolve OpenGL typedefs although the header is considered a system header.
- const bool visitHeader = compareHeaderName(cFileName, "gl.h")
-#if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
- || cStringStartsWith("/usr/include/stdint.h", cFileName)
-#endif
-#if defined(Q_OS_LINUX)
- || cStringStartsWith("/usr/include/stdlib.h", cFileName)
- || cStringStartsWith("/usr/include/sys/types.h", cFileName)
-#elif defined(Q_OS_MACOS)
- // Parse the following system headers to get the correct typdefs for types like
- // int32_t, which are used in the macOS implementation of OpenGL framework.
- || compareHeaderName(cFileName, "gltypes.h")
- || cStringStartsWith("/usr/include/_types", cFileName)
- || cStringStartsWith("/usr/include/sys/_types", cFileName)
-#endif
- ;
+ result = d->visitHeader(cFileName);
clang_disposeString(cxFileName);
- if (visitHeader)
- return true;
}
- return false;
+ return result;
}
FileModelItem Builder::dom() const
diff --git a/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp b/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp
index f301733fe..d3e5e212f 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp
+++ b/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp
@@ -309,6 +309,8 @@ QByteArrayList emulatedCompilerOptions()
HeaderPaths headerPaths;
result.append(QByteArrayLiteral("-fms-compatibility-version=19"));
result.append(QByteArrayLiteral("-Wno-microsoft-enum-value"));
+ // Fix yvals_core.h: STL1000: Unexpected compiler version, expected Clang 7 or newer (MSVC2017 update)
+ result.append(QByteArrayLiteral("-D_ALLOW_COMPILER_AND_STL_VERSION_MISMATCH"));
#elif defined(Q_CC_CLANG)
HeaderPaths headerPaths = gppInternalIncludePaths(compilerFromCMake(QStringLiteral("clang++")));
result.append(noStandardIncludeOption());
diff --git a/sources/shiboken2/ApiExtractor/header_paths.h b/sources/shiboken2/ApiExtractor/header_paths.h
index 0c25702ef..c9b5144c8 100644
--- a/sources/shiboken2/ApiExtractor/header_paths.h
+++ b/sources/shiboken2/ApiExtractor/header_paths.h
@@ -30,7 +30,7 @@
#define HEADER_PATHS_H
#include <QByteArray>
-#include <QList>
+#include <QVector>
#include <QString>
enum class HeaderType
@@ -67,6 +67,6 @@ public:
}
};
-using HeaderPaths = QList<HeaderPath>;
+using HeaderPaths = QVector<HeaderPath>;
#endif // HEADER_PATHS_H
diff --git a/sources/shiboken2/ApiExtractor/messages.cpp b/sources/shiboken2/ApiExtractor/messages.cpp
index 5b3a57fcc..546e9c4ed 100644
--- a/sources/shiboken2/ApiExtractor/messages.cpp
+++ b/sources/shiboken2/ApiExtractor/messages.cpp
@@ -328,6 +328,18 @@ QString msgConversionTypesDiffer(const QString &varType, const QString &conversi
return result;
}
+QString msgCannotFindSmartPointer(const QString &instantiationType,
+ const AbstractMetaClassList &pointers)
+{
+ QString result;
+ QTextStream str(&result);
+ str << "Unable to find smart pointer type for " << instantiationType << " (known types:";
+ for (auto t : pointers)
+ str << ' ' << t->fullName();
+ str << ").";
+ return result;
+}
+
// main.cpp
QString msgLeftOverArguments(const QMap<QString, QString> &remainingArgs)
@@ -463,6 +475,17 @@ QString msgInvalidRegularExpression(const QString &pattern, const QString &why)
return QLatin1String("Invalid pattern \"") + pattern + QLatin1String("\": ") + why;
}
+QString msgNoRootTypeSystemEntry()
+{
+ return QLatin1String("Type system entry appears out of order, there does not seem to be a root type system element.");
+}
+
+QString msgIncorrectlyNestedName(const QString &name)
+{
+ return QLatin1String("Nesting types by specifying '::' is no longer supported (")
+ + name + QLatin1String(").");
+}
+
// qtdocgenerator.cpp
QString msgTagWarning(const QXmlStreamReader &reader, const QString &context,
diff --git a/sources/shiboken2/ApiExtractor/messages.h b/sources/shiboken2/ApiExtractor/messages.h
index 2fee0de8f..2b7b75ba0 100644
--- a/sources/shiboken2/ApiExtractor/messages.h
+++ b/sources/shiboken2/ApiExtractor/messages.h
@@ -117,6 +117,9 @@ QString msgCannotUseEnumAsInt(const QString &name);
QString msgConversionTypesDiffer(const QString &varType, const QString &conversionType);
+QString msgCannotFindSmartPointer(const QString &instantiationType,
+ const AbstractMetaClassList &pointers);
+
QString msgLeftOverArguments(const QMap<QString, QString> &remainingArgs);
QString msgInvalidVersion(const QString &package, const QString &version);
@@ -128,6 +131,10 @@ QString msgExtendingNamespaceRequiresPattern(const QString &name);
QString msgInvalidRegularExpression(const QString &pattern, const QString &why);
+QString msgNoRootTypeSystemEntry();
+
+QString msgIncorrectlyNestedName(const QString &name);
+
QString msgCyclicDependency(const QString &funcName, const QString &graphName,
const QVector<const AbstractMetaFunction *> &involvedConversions);
diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp
index 98b493c67..b85a022b3 100644
--- a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp
@@ -47,11 +47,12 @@ void TestAbstractMetaClass::testClassName()
void TestAbstractMetaClass::testClassNameUnderNamespace()
{
const char* cppCode ="namespace Namespace { class ClassName {}; }\n";
- const char* xmlCode = "\
- <typesystem package=\"Foo\">\n\
- <namespace-type name=\"Namespace\"/>\n\
- <value-type name=\"Namespace::ClassName\"/>\n\
- </typesystem>\n";
+ const char* xmlCode = R"XML(
+ <typesystem package="Foo">
+ <namespace-type name="Namespace">
+ <value-type name="ClassName"/>
+ </namespace-type>
+ </typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
@@ -201,11 +202,12 @@ void TestAbstractMetaClass::testDefaultValues()
class B {};\n\
void method(B b = B());\n\
};\n";
- const char* xmlCode = "\
- <typesystem package=\"Foo\">\n\
- <value-type name='A'/>\n\
- <value-type name='A::B'/>\n\
- </typesystem>\n";
+ const char* xmlCode = R"XML(
+ <typesystem package="Foo">
+ <value-type name='A'>
+ <value-type name='B'/>
+ </value-type>
+ </typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
@@ -224,17 +226,17 @@ void TestAbstractMetaClass::testModifiedDefaultValues()
class B {};\n\
void method(B b = B());\n\
};\n";
- const char* xmlCode = "\
- <typesystem package=\"Foo\">\n\
- <value-type name='A'>\n\
- <modify-function signature='method(A::B)'>\n\
- <modify-argument index='1'>\n\
- <replace-default-expression with='Hello'/>\n\
- </modify-argument>\n\
- </modify-function>\n\
- </value-type>\n\
- <value-type name='A::B'/>\n\
- </typesystem>\n";
+ const char* xmlCode = R"XML(
+ <typesystem package="Foo">
+ <value-type name='A'>
+ <modify-function signature='method(A::B)'>
+ <modify-argument index='1'>
+ <replace-default-expression with='Hello'/>
+ </modify-argument>
+ </modify-function>
+ <value-type name='B'/>
+ </value-type>
+ </typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
@@ -254,11 +256,12 @@ void TestAbstractMetaClass::testInnerClassOfAPolymorphicOne()
class B {};\n\
virtual void method();\n\
};\n";
- const char* xmlCode = "\
- <typesystem package=\"Foo\">\n\
- <object-type name='A'/>\n\
- <value-type name='A::B'/>\n\
- </typesystem>\n";
+ const char* xmlCode = R"XML(
+ <typesystem package="Foo">
+ <object-type name='A'>
+ <value-type name='B'/>
+ </object-type>
+ </typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
@@ -281,11 +284,12 @@ void TestAbstractMetaClass::testForwardDeclaredInnerClass()
public:\n\
void foo();\n\
};\n";
- const char xmlCode[] = "\
- <typesystem package=\"Foo\">\n\
- <value-type name='A'/>\n\
- <value-type name='A::B'/>\n\
- </typesystem>\n";
+ const char xmlCode[] = R"XML(
+ <typesystem package="Foo">
+ <value-type name='A'>
+ <value-type name='B'/>
+ </value-type>
+ </typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
diff --git a/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp
index c438e0c37..aeca2d3f4 100644
--- a/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp
@@ -71,8 +71,8 @@ void TestCodeInjections::testReadFile()
<value-type name='A'>\n\
<conversion-rule ") + attribute + QLatin1String("/>\n\
<inject-code class='target' ") + attribute + QLatin1String("/>\n\
+ <value-type name='B'/>\n\
</value-type>\n\
- <value-type name='A::B'/>\n\
</typesystem>\n");
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode.toLocal8Bit().constData()));
QVERIFY(!builder.isNull());
diff --git a/sources/shiboken2/ApiExtractor/tests/testresolvetype.cpp b/sources/shiboken2/ApiExtractor/tests/testresolvetype.cpp
index 2e5a5759a..2203f3648 100644
--- a/sources/shiboken2/ApiExtractor/tests/testresolvetype.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testresolvetype.cpp
@@ -44,13 +44,15 @@ void TestResolveType::testResolveReturnTypeFromParentScope()
C* method();\n\
};\n\
};";
- const char* xmlCode = "\n\
- <typesystem package='Foo'>\n\
- <namespace-type name='A'/>\n\
- <value-type name='A::B'/>\n\
- <value-type name='A::B::C'/>\n\
- <value-type name='A::D'/>\n\
- </typesystem>";
+ const char* xmlCode = R"XML(
+ <typesystem package='Foo'>
+ <namespace-type name='A'>
+ <value-type name='B'>
+ <value-type name='C'/>
+ </value-type>
+ <value-type name='D'/>
+ </namespace-type>
+ </typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
diff --git a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp
index 59b601f3b..5191cb38d 100644
--- a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp
@@ -63,9 +63,10 @@ namespace Internet {
<typesystem package='Package.Internet'>
<load-typesystem name='%1' generate='no'/>
<container-type name='QList' type='list'/>
- <namespace-type name='Internet' generate='no'/>
- <value-type name='Internet::Url'/>
- <value-type name='Internet::Bookmarks'/>
+ <namespace-type name='Internet' generate='no'>
+ <value-type name='Url'/>
+ <value-type name='Bookmarks'/>
+ </namespace-type>
</typesystem>)XML").arg(file.fileName());
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, qPrintable(xmlCode1), false));
@@ -97,11 +98,12 @@ namespace Namespace {
const char xmlCode[] = R"XML(
<typesystem package="Package">
<container-type name='QList' type='list'/>
- <namespace-type name='Namespace'/>
- <enum-type name='Namespace::SomeEnum'/>
+ <namespace-type name='Namespace'>
+ <enum-type name='SomeEnum'/>
+ <object-type name='A' generate='no'/>
+ <object-type name='B'/>
+ </namespace-type>
<object-type name='Base'/>
- <object-type name='Namespace::A' generate='no'/>
- <object-type name='Namespace::B'/>
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
@@ -211,8 +213,9 @@ struct List {
const char xmlCode[] = R"XML(
<typesystem package='Package'>
- <container-type name='List' type='list'/>
- <value-type name='List::Iterator'/>
+ <container-type name='List' type='list'>
+ <value-type name='Iterator'/>
+ </container-type>
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
@@ -324,11 +327,12 @@ template<SomeEnum type> struct Future {};
const char xmlCode[] = R"XML(
<typesystem package='Package'>
- <namespace-type name='Namespace'/>
- <enum-type name='Namespace::SomeEnum'/>
- <value-type name='Namespace::A' generate='no'/>
- <value-type name='Namespace::B'/>
- <value-type name='Namespace::Future' generate='no'/>
+ <namespace-type name='Namespace'>
+ <enum-type name='SomeEnum'/>
+ <value-type name='A' generate='no'/>
+ <value-type name='B'/>
+ <value-type name='Future' generate='no'/>
+ </namespace-type>
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
diff --git a/sources/shiboken2/ApiExtractor/typedatabase.cpp b/sources/shiboken2/ApiExtractor/typedatabase.cpp
index 4f8887bd2..014f4dadc 100644
--- a/sources/shiboken2/ApiExtractor/typedatabase.cpp
+++ b/sources/shiboken2/ApiExtractor/typedatabase.cpp
@@ -793,7 +793,8 @@ void TypeEntry::formatDebug(QDebug &d) const
if (m_name != cppName)
d << "\", cppName=\"" << cppName << '"';
d << ", type=" << m_type << ", codeGeneration=0x"
- << hex << m_codeGeneration << dec;
+ << hex << m_codeGeneration << dec
+ << ", target=\"" << targetLangName() << '"';
FORMAT_NONEMPTY_STRING("package", m_targetLangPackage)
FORMAT_BOOL("stream", m_stream)
FORMAT_LIST_SIZE("codeSnips", m_codeSnips)
@@ -812,7 +813,6 @@ void TypeEntry::formatDebug(QDebug &d) const
void ComplexTypeEntry::formatDebug(QDebug &d) const
{
TypeEntry::formatDebug(d);
- FORMAT_NONEMPTY_STRING("targetLangName", m_targetLangName)
FORMAT_BOOL("polymorphicBase", m_polymorphicBase)
FORMAT_BOOL("genericClass", m_genericClass)
FORMAT_BOOL("deleteInMainThread", m_deleteInMainThread)
@@ -822,7 +822,6 @@ void ComplexTypeEntry::formatDebug(QDebug &d) const
<< ", except=" << int(m_exceptionHandling);
FORMAT_NONEMPTY_STRING("defaultSuperclass", m_defaultSuperclass)
FORMAT_NONEMPTY_STRING("polymorphicIdValue", m_polymorphicIdValue)
- FORMAT_NONEMPTY_STRING("lookupName", m_lookupName)
FORMAT_NONEMPTY_STRING("targetType", m_targetType)
FORMAT_NONEMPTY_STRING("hash", m_hashFunction)
FORMAT_LIST_SIZE("addedFunctions", m_addedFunctions)
@@ -840,9 +839,6 @@ void TypedefEntry::formatDebug(QDebug &d) const
void EnumTypeEntry::formatDebug(QDebug &d) const
{
TypeEntry::formatDebug(d);
- FORMAT_NONEMPTY_STRING("package", m_packageName)
- FORMAT_NONEMPTY_STRING("qualifier", m_qualifier)
- FORMAT_NONEMPTY_STRING("targetLangName", m_targetLangName)
if (m_flags)
d << ", flags=(" << m_flags << ')';
}
diff --git a/sources/shiboken2/ApiExtractor/typesystem.cpp b/sources/shiboken2/ApiExtractor/typesystem.cpp
index fa141670c..abd2bfb07 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.cpp
+++ b/sources/shiboken2/ApiExtractor/typesystem.cpp
@@ -43,17 +43,13 @@ static QString strings_jobject = QLatin1String("jobject");
static inline QString callOperator() { return QStringLiteral("operator()"); }
-PrimitiveTypeEntry::PrimitiveTypeEntry(const QString &name, const QVersionNumber &vr) :
- TypeEntry(name, PrimitiveType, vr),
+PrimitiveTypeEntry::PrimitiveTypeEntry(const QString &entryName, const QVersionNumber &vr,
+ const TypeEntry *parent) :
+ TypeEntry(entryName, PrimitiveType, vr, parent),
m_preferredTargetLangType(true)
{
}
-QString PrimitiveTypeEntry::targetLangName() const
-{
- return m_targetLangName;
-}
-
QString PrimitiveTypeEntry::targetLangApiName() const
{
return m_targetLangApiName;
@@ -80,6 +76,12 @@ CodeSnipList TypeEntry::codeSnips() const
return m_codeSnips;
}
+void TypeEntry::addExtraInclude(const Include &newInclude)
+{
+ if (!m_extraIncludes.contains(newInclude))
+ m_extraIncludes.append(newInclude);
+}
+
QString Modification::accessModifierString() const
{
if (isPrivate()) return QLatin1String("private");
@@ -112,12 +114,6 @@ FieldModification ComplexTypeEntry::fieldModification(const QString &name) const
return mod;
}
-QString ComplexTypeEntry::targetLangName() const
-{
- return m_targetLangName.isEmpty() ?
- TypeEntry::targetLangName() : m_targetLangName;
-}
-
void ComplexTypeEntry::setDefaultConstructor(const QString& defaultConstructor)
{
m_defaultConstructor = defaultConstructor;
@@ -141,36 +137,11 @@ void ComplexTypeEntry::useAsTypedef(const ComplexTypeEntry *source)
{
TypeEntry::useAsTypedef(source);
m_qualifiedCppName = source->m_qualifiedCppName;
- m_targetLangName = source->m_targetLangName;
- m_lookupName = source->m_lookupName;
m_targetType = source->m_targetType;
}
ComplexTypeEntry::ComplexTypeEntry(const ComplexTypeEntry &) = default;
-QString ContainerTypeEntry::targetLangName() const
-{
-
- switch (m_type) {
- case StringListContainer: return QLatin1String("QStringList");
- case ListContainer: return QLatin1String("QList");
- case LinkedListContainer: return QLatin1String("QLinkedList");
- case VectorContainer: return QLatin1String("QVector");
- case StackContainer: return QLatin1String("QStack");
- case QueueContainer: return QLatin1String("QQueue");
- case SetContainer: return QLatin1String("QSet");
- case MapContainer: return QLatin1String("QMap");
- case MultiMapContainer: return QLatin1String("QMultiMap");
- case HashContainer: return QLatin1String("QHash");
- case MultiHashContainer: return QLatin1String("QMultiHash");
- case PairContainer: return QLatin1String("QPair");
- default:
- qWarning("bad type... %d", m_type);
- break;
- }
- return QString();
-}
-
QString ContainerTypeEntry::qualifiedCppName() const
{
if (m_type == StringListContainer)
@@ -187,23 +158,19 @@ ContainerTypeEntry::ContainerTypeEntry(const ContainerTypeEntry &) = default;
QString EnumTypeEntry::targetLangQualifier() const
{
- TypeEntry *te = TypeDatabase::instance()->findType(m_qualifier);
- return te ? te->targetLangName() : m_qualifier;
+ const QString q = qualifier();
+ if (!q.isEmpty()) {
+ if (auto te = TypeDatabase::instance()->findType(q))
+ return te->targetLangName();
+ }
+ return q;
}
-QString EnumTypeEntry::qualifiedTargetLangName() const
+QString EnumTypeEntry::qualifier() const
{
- QString qualifiedName;
- QString pkg = targetLangPackage();
- QString qualifier = targetLangQualifier();
-
- if (!pkg.isEmpty())
- qualifiedName += pkg + QLatin1Char('.');
- if (!qualifier.isEmpty())
- qualifiedName += qualifier + QLatin1Char('.');
- qualifiedName += targetLangName();
-
- return qualifiedName;
+ auto parentEntry = parent();
+ return parentEntry && parentEntry->type() != TypeEntry::TypeSystemType ?
+ parentEntry->name() : QString();
}
QString EnumTypeEntry::targetLangApiName() const
@@ -230,30 +197,6 @@ TypeEntry *FlagsTypeEntry::clone() const
FlagsTypeEntry::FlagsTypeEntry(const FlagsTypeEntry &) = default;
-QString FlagsTypeEntry::qualifiedTargetLangName() const
-{
- return targetLangPackage() + QLatin1Char('.') + m_enum->targetLangQualifier()
- + QLatin1Char('.') + targetLangName();
-}
-
-QString FlagsTypeEntry::targetLangName() const
-{
- return m_targetLangName;
-}
-
-/*!
- * The Visual Studio 2002 compiler doesn't support these symbols,
- * which our typedefs unforntuatly expand to.
- */
-QString fixCppTypeName(const QString &name)
-{
- if (name == QLatin1String("long long"))
- return QLatin1String("qint64");
- if (name == QLatin1String("unsigned long long"))
- return QLatin1String("quint64");
- return name;
-}
-
QString TemplateInstance::expandCode() const
{
TemplateEntry *templateEntry = TypeDatabase::instance()->findTemplate(m_name);
@@ -623,10 +566,17 @@ AddedFunction::TypeInfo AddedFunction::TypeInfo::fromSignature(const QString& si
return parseType(signature);
}
-ComplexTypeEntry::ComplexTypeEntry(const QString &name, TypeEntry::Type t,
- const QVersionNumber &vr) :
- TypeEntry(name, t, vr),
- m_qualifiedCppName(name),
+static QString buildName(const QString &entryName, const TypeEntry *parent)
+{
+ return parent == nullptr || parent->type() == TypeEntry::TypeSystemType
+ ? entryName : parent->name() + QLatin1String("::") + entryName;
+}
+
+ComplexTypeEntry::ComplexTypeEntry(const QString &entryName, TypeEntry::Type t,
+ const QVersionNumber &vr,
+ const TypeEntry *parent) :
+ TypeEntry(entryName, t, vr, parent),
+ m_qualifiedCppName(buildName(entryName, parent)),
m_polymorphicBase(false),
m_genericClass(false),
m_deleteInMainThread(false)
@@ -638,11 +588,6 @@ bool ComplexTypeEntry::isComplex() const
return true;
}
-QString ComplexTypeEntry::lookupName() const
-{
- return m_lookupName.isEmpty() ? targetLangName() : m_lookupName;
-}
-
QString ComplexTypeEntry::targetLangApiName() const
{
return strings_jobject;
@@ -724,10 +669,13 @@ bool TypeEntry::isCppPrimitive() const
return typeName.contains(QLatin1Char(' ')) || primitiveCppTypes().contains(typeName);
}
-TypeEntry::TypeEntry(const QString &name, TypeEntry::Type t, const QVersionNumber &vr) :
- m_name(name),
- m_type(t),
- m_version(vr)
+TypeEntry::TypeEntry(const QString &entryName, TypeEntry::Type t, const QVersionNumber &vr,
+ const TypeEntry *parent) :
+ m_parent(parent),
+ m_name(buildName(entryName, parent)),
+ m_entryName(entryName),
+ m_version(vr),
+ m_type(t)
{
}
@@ -736,6 +684,51 @@ TypeEntry::~TypeEntry()
delete m_customConversion;
}
+const TypeSystemTypeEntry *TypeEntry::typeSystemTypeEntry() const
+{
+ for (auto e = this; e; e = e->parent()) {
+ if (e->type() == TypeEntry::TypeSystemType)
+ return static_cast<const TypeSystemTypeEntry *>(e);
+ }
+ return nullptr;
+}
+
+QString TypeEntry::targetLangName() const
+{
+ if (m_cachedTargetLangName.isEmpty())
+ m_cachedTargetLangName = buildTargetLangName();
+ return m_cachedTargetLangName;
+}
+
+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);
+ }
+ return result;
+}
+
+QString TypeEntry::targetLangEntryName() const
+{
+ if (m_cachedTargetLangEntryName.isEmpty()) {
+ m_cachedTargetLangEntryName = targetLangName();
+ const int lastDot = m_cachedTargetLangEntryName.lastIndexOf(QLatin1Char('.'));
+ if (lastDot != -1)
+ m_cachedTargetLangEntryName.remove(0, lastDot + 1);
+ }
+ return m_cachedTargetLangEntryName;
+}
+
+QString TypeEntry::qualifiedTargetLangName() const
+{
+ return targetLangPackage() + QLatin1Char('.') + targetLangName();
+}
+
bool TypeEntry::hasCustomConversion() const
{
return m_customConversion != nullptr;
@@ -759,6 +752,7 @@ TypeEntry *TypeEntry::clone() const
// Take over parameters relevant for typedefs
void TypeEntry::useAsTypedef(const TypeEntry *source)
{
+ m_entryName = source->m_entryName;
m_name = source->m_name;
m_targetLangPackage = source->m_targetLangPackage;
m_codeGeneration = source->m_codeGeneration;
@@ -767,8 +761,9 @@ void TypeEntry::useAsTypedef(const TypeEntry *source)
TypeEntry::TypeEntry(const TypeEntry &) = default;
-TypeSystemTypeEntry::TypeSystemTypeEntry(const QString &name, const QVersionNumber &vr) :
- TypeEntry(name, TypeSystemType, vr)
+TypeSystemTypeEntry::TypeSystemTypeEntry(const QString &entryName, const QVersionNumber &vr,
+ const TypeEntry *parent) :
+ TypeEntry(entryName, TypeSystemType, vr, parent)
{
}
@@ -780,7 +775,7 @@ TypeEntry *TypeSystemTypeEntry::clone() const
TypeSystemTypeEntry::TypeSystemTypeEntry(const TypeSystemTypeEntry &) = default;
VoidTypeEntry::VoidTypeEntry() :
- TypeEntry(QLatin1String("void"), VoidType, QVersionNumber(0, 0))
+ TypeEntry(QLatin1String("void"), VoidType, QVersionNumber(0, 0), nullptr)
{
}
@@ -792,7 +787,7 @@ TypeEntry *VoidTypeEntry::clone() const
VoidTypeEntry::VoidTypeEntry(const VoidTypeEntry &) = default;
VarargsTypeEntry::VarargsTypeEntry() :
- TypeEntry(QLatin1String("..."), VarargsType, QVersionNumber(0, 0))
+ TypeEntry(QLatin1String("..."), VarargsType, QVersionNumber(0, 0), nullptr)
{
}
@@ -803,8 +798,9 @@ TypeEntry *VarargsTypeEntry::clone() const
VarargsTypeEntry::VarargsTypeEntry(const VarargsTypeEntry &) = default;
-TemplateArgumentEntry::TemplateArgumentEntry(const QString &name, const QVersionNumber &vr) :
- TypeEntry(name, TemplateArgumentType, vr)
+TemplateArgumentEntry::TemplateArgumentEntry(const QString &entryName, const QVersionNumber &vr,
+ const TypeEntry *parent) :
+ TypeEntry(entryName, TemplateArgumentType, vr, parent)
{
}
@@ -815,14 +811,15 @@ TypeEntry *TemplateArgumentEntry::clone() const
TemplateArgumentEntry::TemplateArgumentEntry(const TemplateArgumentEntry &) = default;
-ArrayTypeEntry::ArrayTypeEntry(const TypeEntry *nested_type, const QVersionNumber &vr) :
- TypeEntry(QLatin1String("Array"), ArrayType, vr),
+ArrayTypeEntry::ArrayTypeEntry(const TypeEntry *nested_type, const QVersionNumber &vr,
+ const TypeEntry *parent) :
+ TypeEntry(QLatin1String("Array"), ArrayType, vr, parent),
m_nestedType(nested_type)
{
Q_ASSERT(m_nestedType);
}
-QString ArrayTypeEntry::targetLangName() const
+QString ArrayTypeEntry::buildTargetLangName() const
{
return m_nestedType->targetLangName() + QLatin1String("[]");
}
@@ -841,24 +838,19 @@ TypeEntry *ArrayTypeEntry::clone() const
ArrayTypeEntry::ArrayTypeEntry(const ArrayTypeEntry &) = default;
-EnumTypeEntry::EnumTypeEntry(const QString &nspace, const QString &enumName,
- const QVersionNumber &vr) :
- TypeEntry(nspace.isEmpty() ? enumName : nspace + QLatin1String("::") + enumName,
- EnumType, vr),
- m_qualifier(nspace),
- m_targetLangName(enumName)
-{
-}
-
-QString EnumTypeEntry::targetLangName() const
+EnumTypeEntry::EnumTypeEntry(const QString &entryName,
+ const QVersionNumber &vr,
+ const TypeEntry *parent) :
+ TypeEntry(entryName, EnumType, vr, parent)
{
- return m_targetLangName;
}
EnumValueTypeEntry::EnumValueTypeEntry(const QString &name, const QString &value,
const EnumTypeEntry *enclosingEnum,
+ bool isScopedEnum,
const QVersionNumber &vr) :
- TypeEntry(name, TypeEntry::EnumValue, vr),
+ TypeEntry(name, TypeEntry::EnumValue, vr,
+ isScopedEnum ? enclosingEnum : enclosingEnum->parent()),
m_value(value),
m_enclosingEnum(enclosingEnum)
{
@@ -871,16 +863,37 @@ TypeEntry *EnumValueTypeEntry::clone() const
EnumValueTypeEntry::EnumValueTypeEntry(const EnumValueTypeEntry &) = default;
-FlagsTypeEntry::FlagsTypeEntry(const QString &name, const QVersionNumber &vr) :
- TypeEntry(name, FlagsType, vr)
+FlagsTypeEntry::FlagsTypeEntry(const QString &entryName, const QVersionNumber &vr,
+ const TypeEntry *parent) :
+ TypeEntry(entryName, FlagsType, vr, parent)
+{
+}
+
+QString FlagsTypeEntry::buildTargetLangName() const
{
+ QString on = m_originalName;
+ on.replace(QLatin1String("::"), QLatin1String("."));
+ return on;
}
+ConstantValueTypeEntry::ConstantValueTypeEntry(const QString& name,
+ const TypeEntry *parent) :
+ TypeEntry(name, ConstantValueType, QVersionNumber(0, 0), parent)
+{
+}
+
+TypeEntry *ConstantValueTypeEntry::clone() const
+{
+ return new ConstantValueTypeEntry(*this);
+}
+
+ConstantValueTypeEntry::ConstantValueTypeEntry(const ConstantValueTypeEntry &) = default;
+
/* A typedef entry allows for specifying template specializations in the
* typesystem XML file. */
-TypedefEntry::TypedefEntry(const QString &name, const QString &sourceType,
- const QVersionNumber &vr) :
- ComplexTypeEntry(name, TypedefType, vr),
+TypedefEntry::TypedefEntry(const QString &entryName, const QString &sourceType,
+ const QVersionNumber &vr, const TypeEntry *parent) :
+ ComplexTypeEntry(entryName, TypedefType, vr, parent),
m_sourceType(sourceType)
{
}
@@ -892,20 +905,21 @@ TypeEntry *TypedefEntry::clone() const
TypedefEntry::TypedefEntry(const TypedefEntry &) = default;
-ContainerTypeEntry::ContainerTypeEntry(const QString &name, Type type,
- const QVersionNumber &vr) :
- ComplexTypeEntry(name, ContainerType, vr),
+ContainerTypeEntry::ContainerTypeEntry(const QString &entryName, Type type,
+ const QVersionNumber &vr,
+ const TypeEntry *parent) :
+ ComplexTypeEntry(entryName, ContainerType, vr, parent),
m_type(type)
{
setCodeGeneration(GenerateForSubclass);
}
-SmartPointerTypeEntry::SmartPointerTypeEntry(const QString &name,
+SmartPointerTypeEntry::SmartPointerTypeEntry(const QString &entryName,
const QString &getterName,
const QString &smartPointerType,
const QString &refCountMethodName,
- const QVersionNumber &vr) :
- ComplexTypeEntry(name, SmartPointerType, vr),
+ const QVersionNumber &vr, const TypeEntry *parent) :
+ ComplexTypeEntry(entryName, SmartPointerType, vr, parent),
m_getterName(getterName),
m_smartPointerType(smartPointerType),
m_refCountMethodName(refCountMethodName)
@@ -919,8 +933,9 @@ TypeEntry *SmartPointerTypeEntry::clone() const
SmartPointerTypeEntry::SmartPointerTypeEntry(const SmartPointerTypeEntry &) = default;
-NamespaceTypeEntry::NamespaceTypeEntry(const QString &name, const QVersionNumber &vr) :
- ComplexTypeEntry(name, NamespaceType, vr)
+NamespaceTypeEntry::NamespaceTypeEntry(const QString &entryName, const QVersionNumber &vr,
+ const TypeEntry *parent) :
+ ComplexTypeEntry(entryName, NamespaceType, vr, parent)
{
}
@@ -944,8 +959,9 @@ bool NamespaceTypeEntry::matchesFile(const QString &needle) const
return m_filePattern.match(needle).hasMatch();
}
-ValueTypeEntry::ValueTypeEntry(const QString &name, const QVersionNumber &vr) :
- ComplexTypeEntry(name, BasicValueType, vr)
+ValueTypeEntry::ValueTypeEntry(const QString &entryName, const QVersionNumber &vr,
+ const TypeEntry *parent) :
+ ComplexTypeEntry(entryName, BasicValueType, vr, parent)
{
}
@@ -966,8 +982,9 @@ TypeEntry *ValueTypeEntry::clone() const
ValueTypeEntry::ValueTypeEntry(const ValueTypeEntry &) = default;
-ValueTypeEntry::ValueTypeEntry(const QString &name, Type t, const QVersionNumber &vr) :
- ComplexTypeEntry(name, t, vr)
+ValueTypeEntry::ValueTypeEntry(const QString &entryName, Type t, const QVersionNumber &vr,
+ const TypeEntry *parent) :
+ ComplexTypeEntry(entryName, t, vr, parent)
{
}
@@ -1105,8 +1122,9 @@ void CustomConversion::TargetToNativeConversion::setConversion(const QString& co
m_d->conversion = conversion;
}
-InterfaceTypeEntry::InterfaceTypeEntry(const QString &name, const QVersionNumber &vr) :
- ComplexTypeEntry(name, InterfaceType, vr)
+InterfaceTypeEntry::InterfaceTypeEntry(const QString &entryName, const QVersionNumber &vr,
+ const TypeEntry *parent) :
+ ComplexTypeEntry(entryName, InterfaceType, vr, parent)
{
}
@@ -1128,9 +1146,10 @@ TypeEntry *InterfaceTypeEntry::clone() const
InterfaceTypeEntry::InterfaceTypeEntry(const InterfaceTypeEntry &) = default;
-FunctionTypeEntry::FunctionTypeEntry(const QString &name, const QString &signature,
- const QVersionNumber &vr) :
- TypeEntry(name, FunctionType, vr)
+FunctionTypeEntry::FunctionTypeEntry(const QString &entryName, const QString &signature,
+ const QVersionNumber &vr,
+ const TypeEntry *parent) :
+ TypeEntry(entryName, FunctionType, vr, parent)
{
addSignature(signature);
}
@@ -1142,8 +1161,9 @@ TypeEntry *FunctionTypeEntry::clone() const
FunctionTypeEntry::FunctionTypeEntry(const FunctionTypeEntry &) = default;
-ObjectTypeEntry::ObjectTypeEntry(const QString &name, const QVersionNumber &vr)
- : ComplexTypeEntry(name, ObjectType, vr)
+ObjectTypeEntry::ObjectTypeEntry(const QString &entryName, const QVersionNumber &vr,
+ const TypeEntry *parent)
+ : ComplexTypeEntry(entryName, ObjectType, vr, parent)
{
}
diff --git a/sources/shiboken2/ApiExtractor/typesystem.h b/sources/shiboken2/ApiExtractor/typesystem.h
index 6a88ecd4d..4d0a23ca1 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.h
+++ b/sources/shiboken2/ApiExtractor/typesystem.h
@@ -543,6 +543,7 @@ private:
};
class CustomConversion;
+class TypeSystemTypeEntry;
class TypeEntry
{
@@ -559,6 +560,7 @@ public:
FlagsType,
EnumType,
EnumValue,
+ ConstantValueType,
TemplateArgumentType,
ThreadType,
BasicValueType,
@@ -591,7 +593,8 @@ public:
};
Q_ENUM(CodeGeneration)
- explicit TypeEntry(const QString &name, Type t, const QVersionNumber &vr);
+ explicit TypeEntry(const QString &entryName, Type t, const QVersionNumber &vr,
+ const TypeEntry *parent);
virtual ~TypeEntry();
@@ -599,6 +602,11 @@ public:
{
return m_type;
}
+
+ const TypeEntry *parent() const { return m_parent; }
+ void setParent(const TypeEntry *p) { m_parent = p; }
+ const TypeSystemTypeEntry *typeSystemTypeEntry() const;
+
bool isPrimitive() const
{
return m_type == PrimitiveType;
@@ -699,10 +707,9 @@ public:
}
// The type's name in C++, fully qualified
- QString name() const
- {
- return m_name;
- }
+ QString name() const { return m_name; }
+ // Name as specified in XML
+ QString entryName() const { return m_entryName; }
uint codeGeneration() const
{
@@ -749,28 +756,15 @@ public:
}
// The type's name in TargetLang
- virtual QString targetLangName() const
- {
- return m_name;
- }
-
- // The type to lookup when converting to TargetLang
- virtual QString lookupName() const
- {
- return targetLangName();
- }
+ QString targetLangName() const; // "Foo.Bar"
+ void setTargetLangName(const QString &n) { m_cachedTargetLangName = n; }
+ QString targetLangEntryName() const; // "Bar"
// The package
QString targetLangPackage() const { return m_targetLangPackage; }
void setTargetLangPackage(const QString &p) { m_targetLangPackage = p; }
- virtual QString qualifiedTargetLangName() const
- {
- QString pkg = targetLangPackage();
- if (pkg.isEmpty())
- return targetLangName();
- return pkg + QLatin1Char('.') + targetLangName();
- }
+ QString qualifiedTargetLangName() const;
virtual InterfaceTypeEntry *designatedInterface() const
{
@@ -836,13 +830,7 @@ public:
{
m_extraIncludes = includes;
}
- void addExtraInclude(const Include &include)
- {
- if (!m_includesUsed.value(include.name(), false)) {
- m_extraIncludes << include;
- m_includesUsed[include.name()] = true;
- }
- }
+ void addExtraInclude(const Include &newInclude);
Include include() const
{
@@ -904,30 +892,36 @@ public:
protected:
TypeEntry(const TypeEntry &);
+ virtual QString buildTargetLangName() const;
+
private:
- QString m_name;
+ const TypeEntry *m_parent;
+ QString m_name; // fully qualified
+ QString m_entryName;
QString m_targetLangPackage;
- Type m_type;
- uint m_codeGeneration = GenerateAll;
+ mutable QString m_cachedTargetLangName; // "Foo.Bar"
+ mutable QString m_cachedTargetLangEntryName; // "Bar"
CustomFunction m_customConstructor;
CustomFunction m_customDestructor;
CodeSnipList m_codeSnips;
DocModificationList m_docModifications;
IncludeList m_extraIncludes;
Include m_include;
- QHash<QString, bool> m_includesUsed;
QString m_conversionRule;
- bool m_stream = false;
QVersionNumber m_version;
CustomConversion *m_customConversion = nullptr;
+ uint m_codeGeneration = GenerateAll;
int m_revision = 0;
int m_sbkIndex = 0;
+ Type m_type;
+ bool m_stream = false;
};
class TypeSystemTypeEntry : public TypeEntry
{
public:
- explicit TypeSystemTypeEntry(const QString &name, const QVersionNumber &vr);
+ explicit TypeSystemTypeEntry(const QString &entryName, const QVersionNumber &vr,
+ const TypeEntry *parent);
TypeEntry *clone() const override;
@@ -960,7 +954,8 @@ protected:
class TemplateArgumentEntry : public TypeEntry
{
public:
- explicit TemplateArgumentEntry(const QString &name, const QVersionNumber &vr);
+ explicit TemplateArgumentEntry(const QString &entryName, const QVersionNumber &vr,
+ const TypeEntry *parent);
int ordinal() const
{
@@ -983,7 +978,8 @@ private:
class ArrayTypeEntry : public TypeEntry
{
public:
- explicit ArrayTypeEntry(const TypeEntry *nested_type, const QVersionNumber &vr);
+ explicit ArrayTypeEntry(const TypeEntry *nested_type, const QVersionNumber &vr,
+ const TypeEntry *parent);
void setNestedTypeEntry(TypeEntry *nested)
{
@@ -994,7 +990,6 @@ public:
return m_nestedType;
}
- QString targetLangName() const override;
QString targetLangApiName() const override;
TypeEntry *clone() const override;
@@ -1002,6 +997,8 @@ public:
protected:
ArrayTypeEntry(const ArrayTypeEntry &);
+ QString buildTargetLangName() const override;
+
private:
const TypeEntry *m_nestedType;
};
@@ -1010,13 +1007,8 @@ private:
class PrimitiveTypeEntry : public TypeEntry
{
public:
- explicit PrimitiveTypeEntry(const QString &name, const QVersionNumber &vr);
-
- QString targetLangName() const override;
- void setTargetLangName(const QString &targetLangName)
- {
- m_targetLangName = targetLangName;
- }
+ explicit PrimitiveTypeEntry(const QString &entryName, const QVersionNumber &vr,
+ const TypeEntry *parent);
QString targetLangApiName() const override;
void setTargetLangApiName(const QString &targetLangApiName)
@@ -1077,7 +1069,6 @@ protected:
PrimitiveTypeEntry(const PrimitiveTypeEntry &);
private:
- QString m_targetLangName;
QString m_targetLangApiName;
QString m_defaultConstructor;
uint m_preferredTargetLangType : 1;
@@ -1089,23 +1080,15 @@ class EnumValueTypeEntry;
class EnumTypeEntry : public TypeEntry
{
public:
- explicit EnumTypeEntry(const QString &nspace, const QString &enumName,
- const QVersionNumber &vr);
+ explicit EnumTypeEntry(const QString &entryName,
+ const QVersionNumber &vr,
+ const TypeEntry *parent);
- QString targetLangName() const override;
QString targetLangQualifier() const;
- QString qualifiedTargetLangName() const override;
QString targetLangApiName() const override;
- QString qualifier() const
- {
- return m_qualifier;
- }
- void setQualifier(const QString &q)
- {
- m_qualifier = q;
- }
+ QString qualifier() const;
const EnumValueTypeEntry *nullValue() const { return m_nullValue; }
void setNullValue(const EnumValueTypeEntry *n) { m_nullValue = n; }
@@ -1140,9 +1123,6 @@ protected:
EnumTypeEntry(const EnumTypeEntry &);
private:
- QString m_packageName;
- QString m_qualifier;
- QString m_targetLangName;
const EnumValueTypeEntry *m_nullValue = nullptr;
QStringList m_rejectedEnums;
@@ -1156,7 +1136,9 @@ private:
class EnumValueTypeEntry : public TypeEntry
{
public:
- explicit EnumValueTypeEntry(const QString& name, const QString& value, const EnumTypeEntry* enclosingEnum, const QVersionNumber &vr);
+ explicit EnumValueTypeEntry(const QString& name, const QString& value,
+ const EnumTypeEntry* enclosingEnum,
+ bool isScopedEnum, const QVersionNumber &vr);
QString value() const { return m_value; }
const EnumTypeEntry* enclosingEnum() const { return m_enclosingEnum; }
@@ -1174,10 +1156,9 @@ private:
class FlagsTypeEntry : public TypeEntry
{
public:
- explicit FlagsTypeEntry(const QString &name, const QVersionNumber &vr);
+ explicit FlagsTypeEntry(const QString &entryName, const QVersionNumber &vr,
+ const TypeEntry *parent);
- QString qualifiedTargetLangName() const override;
- QString targetLangName() const override;
QString targetLangApiName() const override;
QString originalName() const
@@ -1191,11 +1172,11 @@ public:
QString flagsName() const
{
- return m_targetLangName;
+ return m_flagsName;
}
void setFlagsName(const QString &name)
{
- m_targetLangName = name;
+ m_flagsName = name;
}
EnumTypeEntry *originator() const
@@ -1212,12 +1193,27 @@ public:
protected:
FlagsTypeEntry(const FlagsTypeEntry &);
+ QString buildTargetLangName() const override;
+
private:
QString m_originalName;
- QString m_targetLangName;
+ QString m_flagsName;
EnumTypeEntry *m_enum = nullptr;
};
+// For primitive values, typically to provide a dummy type for
+// example the '2' in non-type template 'Array<2>'.
+class ConstantValueTypeEntry : public TypeEntry
+{
+public:
+ explicit ConstantValueTypeEntry(const QString& name,
+ const TypeEntry *parent);
+
+ TypeEntry *clone() const override;
+
+protected:
+ ConstantValueTypeEntry(const ConstantValueTypeEntry &);
+};
class ComplexTypeEntry : public TypeEntry
{
@@ -1233,17 +1229,11 @@ public:
Unknown
};
- explicit ComplexTypeEntry(const QString &name, Type t, const QVersionNumber &vr);
+ explicit ComplexTypeEntry(const QString &entryName, Type t, const QVersionNumber &vr,
+ const TypeEntry *parent);
bool isComplex() const override;
- void setLookupName(const QString &name)
- {
- m_lookupName = name;
- }
-
- QString lookupName() const override;
-
QString targetLangApiName() const override;
void setTypeFlags(TypeFlags flags)
@@ -1335,12 +1325,6 @@ public:
m_targetType = code;
}
- QString targetLangName() const override;
- void setTargetLangName(const QString &name)
- {
- m_targetLangName = name;
- }
-
bool isGenericClass() const
{
return m_genericClass;
@@ -1408,14 +1392,12 @@ private:
QString m_defaultConstructor;
QString m_defaultSuperclass;
QString m_qualifiedCppName;
- QString m_targetLangName;
uint m_polymorphicBase : 1;
uint m_genericClass : 1;
uint m_deleteInMainThread : 1;
QString m_polymorphicIdValue;
- QString m_lookupName;
QString m_targetType;
TypeFlags m_typeFlags;
CopyableFlag m_copyableFlag = Unknown;
@@ -1432,9 +1414,10 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(ComplexTypeEntry::TypeFlags)
class TypedefEntry : public ComplexTypeEntry
{
public:
- explicit TypedefEntry(const QString &name,
+ explicit TypedefEntry(const QString &entryName,
const QString &sourceType,
- const QVersionNumber &vr);
+ const QVersionNumber &vr,
+ const TypeEntry *parent);
QString sourceType() const { return m_sourceType; }
void setSourceType(const QString &s) { m_sourceType =s; }
@@ -1480,7 +1463,8 @@ public:
};
Q_ENUM(Type)
- explicit ContainerTypeEntry(const QString &name, Type type, const QVersionNumber &vr);
+ explicit ContainerTypeEntry(const QString &entryName, Type type, const QVersionNumber &vr,
+ const TypeEntry *parent);
Type type() const
{
@@ -1488,7 +1472,6 @@ public:
}
QString typeName() const;
- QString targetLangName() const override;
QString qualifiedCppName() const override;
TypeEntry *clone() const override;
@@ -1506,11 +1489,12 @@ private:
class SmartPointerTypeEntry : public ComplexTypeEntry
{
public:
- explicit SmartPointerTypeEntry(const QString &name,
+ explicit SmartPointerTypeEntry(const QString &entryName,
const QString &getterName,
const QString &smartPointerType,
const QString &refCountMethodName,
- const QVersionNumber &vr);
+ const QVersionNumber &vr,
+ const TypeEntry *parent);
QString getter() const
{
@@ -1536,7 +1520,8 @@ private:
class NamespaceTypeEntry : public ComplexTypeEntry
{
public:
- explicit NamespaceTypeEntry(const QString &name, const QVersionNumber &vr);
+ explicit NamespaceTypeEntry(const QString &entryName, const QVersionNumber &vr,
+ const TypeEntry *parent);
TypeEntry *clone() const override;
@@ -1566,7 +1551,8 @@ private:
class ValueTypeEntry : public ComplexTypeEntry
{
public:
- explicit ValueTypeEntry(const QString &name, const QVersionNumber &vr);
+ explicit ValueTypeEntry(const QString &entryName, const QVersionNumber &vr,
+ const TypeEntry *parent);
bool isValue() const override;
@@ -1575,14 +1561,16 @@ public:
TypeEntry *clone() const override;
protected:
- explicit ValueTypeEntry(const QString &name, Type t, const QVersionNumber &vr);
+ explicit ValueTypeEntry(const QString &entryName, Type t, const QVersionNumber &vr,
+ const TypeEntry *parent);
ValueTypeEntry(const ValueTypeEntry &);
};
class InterfaceTypeEntry : public ComplexTypeEntry
{
public:
- explicit InterfaceTypeEntry(const QString &name, const QVersionNumber &vr);
+ explicit InterfaceTypeEntry(const QString &entryName, const QVersionNumber &vr,
+ const TypeEntry *parent);
static QString interfaceName(const QString &name)
{
@@ -1615,7 +1603,8 @@ class FunctionTypeEntry : public TypeEntry
{
public:
explicit FunctionTypeEntry(const QString& name, const QString& signature,
- const QVersionNumber &vr);
+ const QVersionNumber &vr,
+ const TypeEntry *parent);
void addSignature(const QString& signature)
{
m_signatures << signature;
@@ -1643,7 +1632,8 @@ private:
class ObjectTypeEntry : public ComplexTypeEntry
{
public:
- explicit ObjectTypeEntry(const QString &name, const QVersionNumber &vr);
+ explicit ObjectTypeEntry(const QString &entryName, const QVersionNumber &vr,
+ const TypeEntry *parent);
InterfaceTypeEntry *designatedInterface() const override;
void setDesignatedInterface(InterfaceTypeEntry *entry)
@@ -1684,8 +1674,6 @@ struct TypeRejection
QDebug operator<<(QDebug d, const TypeRejection &r);
#endif
-QString fixCppTypeName(const QString &name);
-
class CustomConversion
{
public:
diff --git a/sources/shiboken2/ApiExtractor/typesystemparser.cpp b/sources/shiboken2/ApiExtractor/typesystemparser.cpp
index 57ceb357f..7388b07fc 100644
--- a/sources/shiboken2/ApiExtractor/typesystemparser.cpp
+++ b/sources/shiboken2/ApiExtractor/typesystemparser.cpp
@@ -81,6 +81,7 @@ static inline QString preferredTargetLangTypeAttribute() { return QStringLiteral
static inline QString removeAttribute() { return QStringLiteral("remove"); }
static inline QString renameAttribute() { return QStringLiteral("rename"); }
static inline QString readAttribute() { return QStringLiteral("read"); }
+static inline QString targetLangNameAttribute() { return QStringLiteral("target-lang-name"); }
static inline QString writeAttribute() { return QStringLiteral("write"); }
static inline QString replaceAttribute() { return QStringLiteral("replace"); }
static inline QString toAttribute() { return QStringLiteral("to"); }
@@ -191,200 +192,200 @@ static EnumType functionName(QStringView needle, EnumType defaultValue = default
ENUM_LOOKUP_BEGIN(TypeSystem::AllowThread, Qt::CaseInsensitive,
allowThreadFromAttribute, TypeSystem::AllowThread::Unspecified)
{
- {QStringViewLiteral("yes"), TypeSystem::AllowThread::Allow},
- {QStringViewLiteral("true"), TypeSystem::AllowThread::Allow},
- {QStringViewLiteral("auto"), TypeSystem::AllowThread::Auto},
- {QStringViewLiteral("no"), TypeSystem::AllowThread::Disallow},
- {QStringViewLiteral("false"), TypeSystem::AllowThread::Disallow},
+ {u"yes", TypeSystem::AllowThread::Allow},
+ {u"true", TypeSystem::AllowThread::Allow},
+ {u"auto", TypeSystem::AllowThread::Auto},
+ {u"no", TypeSystem::AllowThread::Disallow},
+ {u"false", TypeSystem::AllowThread::Disallow},
};
ENUM_LOOKUP_LINEAR_SEARCH()
ENUM_LOOKUP_BEGIN(TypeSystem::Language, Qt::CaseInsensitive,
languageFromAttribute, TypeSystem::NoLanguage)
{
- {QStringViewLiteral("all"), TypeSystem::All}, // sorted!
- {QStringViewLiteral("constructors"), TypeSystem::Constructors},
- {QStringViewLiteral("destructor-function"), TypeSystem::DestructorFunction},
- {QStringViewLiteral("interface"), TypeSystem::Interface},
- {QStringViewLiteral("library-initializer"), TypeSystem::PackageInitializer},
- {QStringViewLiteral("native"), TypeSystem::NativeCode}, // em algum lugar do cpp
- {QStringViewLiteral("shell"), TypeSystem::ShellCode}, // coloca no header, mas antes da declaracao da classe
- {QStringViewLiteral("shell-declaration"), TypeSystem::ShellDeclaration},
- {QStringViewLiteral("target"), TypeSystem::TargetLangCode} // em algum lugar do cpp
+ {u"all", TypeSystem::All}, // sorted!
+ {u"constructors", TypeSystem::Constructors},
+ {u"destructor-function", TypeSystem::DestructorFunction},
+ {u"interface", TypeSystem::Interface},
+ {u"library-initializer", TypeSystem::PackageInitializer},
+ {u"native", TypeSystem::NativeCode}, // em algum lugar do cpp
+ {u"shell", TypeSystem::ShellCode}, // coloca no header, mas antes da declaracao da classe
+ {u"shell-declaration", TypeSystem::ShellDeclaration},
+ {u"target", TypeSystem::TargetLangCode} // em algum lugar do cpp
};
ENUM_LOOKUP_BINARY_SEARCH()
ENUM_LOOKUP_BEGIN(TypeSystem::Ownership, Qt::CaseInsensitive,
ownershipFromFromAttribute, TypeSystem::InvalidOwnership)
{
- {QStringViewLiteral("target"), TypeSystem::TargetLangOwnership},
- {QStringViewLiteral("c++"), TypeSystem::CppOwnership},
- {QStringViewLiteral("default"), TypeSystem::DefaultOwnership}
+ {u"target", TypeSystem::TargetLangOwnership},
+ {u"c++", TypeSystem::CppOwnership},
+ {u"default", TypeSystem::DefaultOwnership}
};
ENUM_LOOKUP_LINEAR_SEARCH()
ENUM_LOOKUP_BEGIN(AddedFunction::Access, Qt::CaseInsensitive,
addedFunctionAccessFromAttribute, AddedFunction::InvalidAccess)
{
- {QStringViewLiteral("public"), AddedFunction::Public},
- {QStringViewLiteral("protected"), AddedFunction::Protected},
+ {u"public", AddedFunction::Public},
+ {u"protected", AddedFunction::Protected},
};
ENUM_LOOKUP_LINEAR_SEARCH()
ENUM_LOOKUP_BEGIN(Modification::Modifiers, Qt::CaseSensitive,
modifierFromAttribute, Modification::InvalidModifier)
{
- {QStringViewLiteral("private"), Modification::Private},
- {QStringViewLiteral("public"), Modification::Public},
- {QStringViewLiteral("protected"), Modification::Protected},
- {QStringViewLiteral("friendly"), Modification::Friendly},
- {QStringViewLiteral("rename"), Modification::Rename},
- {QStringViewLiteral("final"), Modification::Final},
- {QStringViewLiteral("non-final"), Modification::NonFinal}
+ {u"private", Modification::Private},
+ {u"public", Modification::Public},
+ {u"protected", Modification::Protected},
+ {u"friendly", Modification::Friendly},
+ {u"rename", Modification::Rename},
+ {u"final", Modification::Final},
+ {u"non-final", Modification::NonFinal}
};
ENUM_LOOKUP_LINEAR_SEARCH()
ENUM_LOOKUP_BEGIN(ReferenceCount::Action, Qt::CaseInsensitive,
referenceCountFromAttribute, ReferenceCount::Invalid)
{
- {QStringViewLiteral("add"), ReferenceCount::Add},
- {QStringViewLiteral("add-all"), ReferenceCount::AddAll},
- {QStringViewLiteral("remove"), ReferenceCount::Remove},
- {QStringViewLiteral("set"), ReferenceCount::Set},
- {QStringViewLiteral("ignore"), ReferenceCount::Ignore}
+ {u"add", ReferenceCount::Add},
+ {u"add-all", ReferenceCount::AddAll},
+ {u"remove", ReferenceCount::Remove},
+ {u"set", ReferenceCount::Set},
+ {u"ignore", ReferenceCount::Ignore}
};
ENUM_LOOKUP_LINEAR_SEARCH()
ENUM_LOOKUP_BEGIN(ArgumentOwner::Action, Qt::CaseInsensitive,
argumentOwnerActionFromAttribute, ArgumentOwner::Invalid)
{
- {QStringViewLiteral("add"), ArgumentOwner::Add},
- {QStringViewLiteral("remove"), ArgumentOwner::Remove}
+ {u"add", ArgumentOwner::Add},
+ {u"remove", ArgumentOwner::Remove}
};
ENUM_LOOKUP_LINEAR_SEARCH()
ENUM_LOOKUP_BEGIN(TypeSystem::CodeSnipPosition, Qt::CaseInsensitive,
codeSnipPositionFromAttribute, TypeSystem::CodeSnipPositionInvalid)
{
- {QStringViewLiteral("beginning"), TypeSystem::CodeSnipPositionBeginning},
- {QStringViewLiteral("end"), TypeSystem::CodeSnipPositionEnd},
- {QStringViewLiteral("declaration"), TypeSystem::CodeSnipPositionDeclaration},
- {QStringViewLiteral("prototype-initialization"), TypeSystem::CodeSnipPositionPrototypeInitialization},
- {QStringViewLiteral("constructor-initialization"), TypeSystem::CodeSnipPositionConstructorInitialization},
- {QStringViewLiteral("constructor"), TypeSystem::CodeSnipPositionConstructor}
+ {u"beginning", TypeSystem::CodeSnipPositionBeginning},
+ {u"end", TypeSystem::CodeSnipPositionEnd},
+ {u"declaration", TypeSystem::CodeSnipPositionDeclaration},
+ {u"prototype-initialization", TypeSystem::CodeSnipPositionPrototypeInitialization},
+ {u"constructor-initialization", TypeSystem::CodeSnipPositionConstructorInitialization},
+ {u"constructor", TypeSystem::CodeSnipPositionConstructor}
};
ENUM_LOOKUP_LINEAR_SEARCH()
ENUM_LOOKUP_BEGIN(Include::IncludeType, Qt::CaseInsensitive,
locationFromAttribute, Include::InvalidInclude)
{
- {QStringViewLiteral("global"), Include::IncludePath},
- {QStringViewLiteral("local"), Include::LocalPath},
- {QStringViewLiteral("target"), Include::TargetLangImport}
+ {u"global", Include::IncludePath},
+ {u"local", Include::LocalPath},
+ {u"target", Include::TargetLangImport}
};
ENUM_LOOKUP_LINEAR_SEARCH()
ENUM_LOOKUP_BEGIN(TypeSystem::DocModificationMode, Qt::CaseInsensitive,
docModificationFromAttribute, TypeSystem::DocModificationInvalid)
{
- {QStringViewLiteral("append"), TypeSystem::DocModificationAppend},
- {QStringViewLiteral("prepend"), TypeSystem::DocModificationPrepend},
- {QStringViewLiteral("replace"), TypeSystem::DocModificationReplace}
+ {u"append", TypeSystem::DocModificationAppend},
+ {u"prepend", TypeSystem::DocModificationPrepend},
+ {u"replace", TypeSystem::DocModificationReplace}
};
ENUM_LOOKUP_LINEAR_SEARCH()
ENUM_LOOKUP_BEGIN(ContainerTypeEntry::Type, Qt::CaseSensitive,
containerTypeFromAttribute, ContainerTypeEntry::NoContainer)
{
- {QStringViewLiteral("list"), ContainerTypeEntry::ListContainer},
- {QStringViewLiteral("string-list"), ContainerTypeEntry::StringListContainer},
- {QStringViewLiteral("linked-list"), ContainerTypeEntry::LinkedListContainer},
- {QStringViewLiteral("vector"), ContainerTypeEntry::VectorContainer},
- {QStringViewLiteral("stack"), ContainerTypeEntry::StackContainer},
- {QStringViewLiteral("queue"), ContainerTypeEntry::QueueContainer},
- {QStringViewLiteral("set"), ContainerTypeEntry::SetContainer},
- {QStringViewLiteral("map"), ContainerTypeEntry::MapContainer},
- {QStringViewLiteral("multi-map"), ContainerTypeEntry::MultiMapContainer},
- {QStringViewLiteral("hash"), ContainerTypeEntry::HashContainer},
- {QStringViewLiteral("multi-hash"), ContainerTypeEntry::MultiHashContainer},
- {QStringViewLiteral("pair"), ContainerTypeEntry::PairContainer}
+ {u"list", ContainerTypeEntry::ListContainer},
+ {u"string-list", ContainerTypeEntry::StringListContainer},
+ {u"linked-list", ContainerTypeEntry::LinkedListContainer},
+ {u"vector", ContainerTypeEntry::VectorContainer},
+ {u"stack", ContainerTypeEntry::StackContainer},
+ {u"queue", ContainerTypeEntry::QueueContainer},
+ {u"set", ContainerTypeEntry::SetContainer},
+ {u"map", ContainerTypeEntry::MapContainer},
+ {u"multi-map", ContainerTypeEntry::MultiMapContainer},
+ {u"hash", ContainerTypeEntry::HashContainer},
+ {u"multi-hash", ContainerTypeEntry::MultiHashContainer},
+ {u"pair", ContainerTypeEntry::PairContainer}
};
ENUM_LOOKUP_LINEAR_SEARCH()
ENUM_LOOKUP_BEGIN(TypeRejection::MatchType, Qt::CaseSensitive,
typeRejectionFromAttribute, TypeRejection::Invalid)
{
- {QStringViewLiteral("class"), TypeRejection::ExcludeClass},
- {QStringViewLiteral("function-name"), TypeRejection::Function},
- {QStringViewLiteral("field-name"), TypeRejection::Field},
- {QStringViewLiteral("enum-name"), TypeRejection::Enum },
- {QStringViewLiteral("argument-type"), TypeRejection::ArgumentType},
- {QStringViewLiteral("return-type"), TypeRejection::ReturnType}
+ {u"class", TypeRejection::ExcludeClass},
+ {u"function-name", TypeRejection::Function},
+ {u"field-name", TypeRejection::Field},
+ {u"enum-name", TypeRejection::Enum },
+ {u"argument-type", TypeRejection::ArgumentType},
+ {u"return-type", TypeRejection::ReturnType}
};
ENUM_LOOKUP_LINEAR_SEARCH()
ENUM_LOOKUP_BEGIN(TypeSystem::ExceptionHandling, Qt::CaseSensitive,
exceptionHandlingFromAttribute, TypeSystem::ExceptionHandling::Unspecified)
{
- {QStringViewLiteral("no"), TypeSystem::ExceptionHandling::Off},
- {QStringViewLiteral("false"), TypeSystem::ExceptionHandling::Off},
- {QStringViewLiteral("auto-off"), TypeSystem::ExceptionHandling::AutoDefaultToOff},
- {QStringViewLiteral("auto-on"), TypeSystem::ExceptionHandling::AutoDefaultToOn},
- {QStringViewLiteral("yes"), TypeSystem::ExceptionHandling::On},
- {QStringViewLiteral("true"), TypeSystem::ExceptionHandling::On},
+ {u"no", TypeSystem::ExceptionHandling::Off},
+ {u"false", TypeSystem::ExceptionHandling::Off},
+ {u"auto-off", TypeSystem::ExceptionHandling::AutoDefaultToOff},
+ {u"auto-on", TypeSystem::ExceptionHandling::AutoDefaultToOn},
+ {u"yes", TypeSystem::ExceptionHandling::On},
+ {u"true", TypeSystem::ExceptionHandling::On},
};
ENUM_LOOKUP_LINEAR_SEARCH()
ENUM_LOOKUP_BEGIN(StackElement::ElementType, Qt::CaseInsensitive,
elementFromTag, StackElement::None)
{
- {QStringViewLiteral("access"), StackElement::Access}, // sorted!
- {QStringViewLiteral("add-conversion"), StackElement::AddConversion},
- {QStringViewLiteral("add-function"), StackElement::AddFunction},
- {QStringViewLiteral("argument-map"), StackElement::ArgumentMap},
- {QStringViewLiteral("array"), StackElement::Array},
- {QStringViewLiteral("container-type"), StackElement::ContainerTypeEntry},
- {QStringViewLiteral("conversion-rule"), StackElement::ConversionRule},
- {QStringViewLiteral("custom-constructor"), StackElement::CustomMetaConstructor},
- {QStringViewLiteral("custom-destructor"), StackElement::CustomMetaDestructor},
- {QStringViewLiteral("custom-type"), StackElement::CustomTypeEntry},
- {QStringViewLiteral("define-ownership"), StackElement::DefineOwnership},
- {QStringViewLiteral("enum-type"), StackElement::EnumTypeEntry},
- {QStringViewLiteral("extra-includes"), StackElement::ExtraIncludes},
- {QStringViewLiteral("function"), StackElement::FunctionTypeEntry},
- {QStringViewLiteral("include"), StackElement::Include},
- {QStringViewLiteral("inject-code"), StackElement::InjectCode},
- {QStringViewLiteral("inject-documentation"), StackElement::InjectDocumentation},
- {QStringViewLiteral("insert-template"), StackElement::TemplateInstanceEnum},
- {QStringViewLiteral("interface-type"), StackElement::InterfaceTypeEntry},
- {QStringViewLiteral("load-typesystem"), StackElement::LoadTypesystem},
- {QStringViewLiteral("modify-argument"), StackElement::ModifyArgument},
- {QStringViewLiteral("modify-documentation"), StackElement::ModifyDocumentation},
- {QStringViewLiteral("modify-field"), StackElement::ModifyField},
- {QStringViewLiteral("modify-function"), StackElement::ModifyFunction},
- {QStringViewLiteral("namespace-type"), StackElement::NamespaceTypeEntry},
- {QStringViewLiteral("native-to-target"), StackElement::NativeToTarget},
- {QStringViewLiteral("no-null-pointer"), StackElement::NoNullPointers},
- {QStringViewLiteral("object-type"), StackElement::ObjectTypeEntry},
- {QStringViewLiteral("parent"), StackElement::ParentOwner},
- {QStringViewLiteral("primitive-type"), StackElement::PrimitiveTypeEntry},
- {QStringViewLiteral("reference-count"), StackElement::ReferenceCount},
- {QStringViewLiteral("reject-enum-value"), StackElement::RejectEnumValue},
- {QStringViewLiteral("rejection"), StackElement::Rejection},
- {QStringViewLiteral("remove"), StackElement::Removal},
- {QStringViewLiteral("remove-argument"), StackElement::RemoveArgument},
- {QStringViewLiteral("remove-default-expression"), StackElement::RemoveDefaultExpression},
- {QStringViewLiteral("rename"), StackElement::Rename},
- {QStringViewLiteral("replace"), StackElement::Replace},
- {QStringViewLiteral("replace-default-expression"), StackElement::ReplaceDefaultExpression},
- {QStringViewLiteral("replace-type"), StackElement::ReplaceType},
- {QStringViewLiteral("smart-pointer-type"), StackElement::SmartPointerTypeEntry},
- {QStringViewLiteral("suppress-warning"), StackElement::SuppressedWarning},
- {QStringViewLiteral("target-to-native"), StackElement::TargetToNative},
- {QStringViewLiteral("template"), StackElement::Template},
- {QStringViewLiteral("typedef-type"), StackElement::TypedefTypeEntry},
- {QStringViewLiteral("typesystem"), StackElement::Root},
- {QStringViewLiteral("value-type"), StackElement::ValueTypeEntry},
+ {u"access", StackElement::Access}, // sorted!
+ {u"add-conversion", StackElement::AddConversion},
+ {u"add-function", StackElement::AddFunction},
+ {u"argument-map", StackElement::ArgumentMap},
+ {u"array", StackElement::Array},
+ {u"container-type", StackElement::ContainerTypeEntry},
+ {u"conversion-rule", StackElement::ConversionRule},
+ {u"custom-constructor", StackElement::CustomMetaConstructor},
+ {u"custom-destructor", StackElement::CustomMetaDestructor},
+ {u"custom-type", StackElement::CustomTypeEntry},
+ {u"define-ownership", StackElement::DefineOwnership},
+ {u"enum-type", StackElement::EnumTypeEntry},
+ {u"extra-includes", StackElement::ExtraIncludes},
+ {u"function", StackElement::FunctionTypeEntry},
+ {u"include", StackElement::Include},
+ {u"inject-code", StackElement::InjectCode},
+ {u"inject-documentation", StackElement::InjectDocumentation},
+ {u"insert-template", StackElement::TemplateInstanceEnum},
+ {u"interface-type", StackElement::InterfaceTypeEntry},
+ {u"load-typesystem", StackElement::LoadTypesystem},
+ {u"modify-argument", StackElement::ModifyArgument},
+ {u"modify-documentation", StackElement::ModifyDocumentation},
+ {u"modify-field", StackElement::ModifyField},
+ {u"modify-function", StackElement::ModifyFunction},
+ {u"namespace-type", StackElement::NamespaceTypeEntry},
+ {u"native-to-target", StackElement::NativeToTarget},
+ {u"no-null-pointer", StackElement::NoNullPointers},
+ {u"object-type", StackElement::ObjectTypeEntry},
+ {u"parent", StackElement::ParentOwner},
+ {u"primitive-type", StackElement::PrimitiveTypeEntry},
+ {u"reference-count", StackElement::ReferenceCount},
+ {u"reject-enum-value", StackElement::RejectEnumValue},
+ {u"rejection", StackElement::Rejection},
+ {u"remove", StackElement::Removal},
+ {u"remove-argument", StackElement::RemoveArgument},
+ {u"remove-default-expression", StackElement::RemoveDefaultExpression},
+ {u"rename", StackElement::Rename},
+ {u"replace", StackElement::Replace},
+ {u"replace-default-expression", StackElement::ReplaceDefaultExpression},
+ {u"replace-type", StackElement::ReplaceType},
+ {u"smart-pointer-type", StackElement::SmartPointerTypeEntry},
+ {u"suppress-warning", StackElement::SuppressedWarning},
+ {u"target-to-native", StackElement::TargetToNative},
+ {u"template", StackElement::Template},
+ {u"typedef-type", StackElement::TypedefTypeEntry},
+ {u"typesystem", StackElement::Root},
+ {u"value-type", StackElement::ValueTypeEntry},
};
ENUM_LOOKUP_BINARY_SEARCH()
@@ -991,17 +992,17 @@ static bool convertRemovalAttribute(QStringView remove, Modification& mod, QStri
if (remove.isEmpty())
return true;
#ifdef QTBUG_69389_FIXED
- if (remove.compare(QStringViewLiteral("all"), Qt::CaseInsensitive) == 0) {
+ if (remove.compare(u"all", Qt::CaseInsensitive) == 0) {
#else
- if (QtPrivate::compareStrings(remove, QStringViewLiteral("all"), Qt::CaseInsensitive) == 0) {
+ if (QtPrivate::compareStrings(remove, u"all", Qt::CaseInsensitive) == 0) {
#endif
mod.removal = TypeSystem::All;
return true;
}
#ifdef QTBUG_69389_FIXED
- if (remove.compare(QStringViewLiteral("target"), Qt::CaseInsensitive) == 0) {
+ if (remove.compare(u"target", Qt::CaseInsensitive) == 0) {
#else
- if (QtPrivate::compareStrings(remove, QStringViewLiteral("target"), Qt::CaseInsensitive) == 0) {
+ if (QtPrivate::compareStrings(remove, u"target", Qt::CaseInsensitive) == 0) {
#endif
mod.removal = TypeSystem::TargetLangAndNativeCode;
return true;
@@ -1040,41 +1041,59 @@ static QString checkSignatureError(const QString& signature, const QString& tag)
return QString();
}
+inline const TypeEntry *TypeSystemParser::currentParentTypeEntry() const
+{
+ return m_current ? m_current->entry : nullptr;
+}
+
+bool TypeSystemParser::checkRootElement()
+{
+ const bool ok = currentParentTypeEntry() != nullptr;
+ if (!ok)
+ m_error = msgNoRootTypeSystemEntry();
+ return ok;
+}
+
void TypeSystemParser::applyCommonAttributes(TypeEntry *type, QXmlStreamAttributes *attributes) const
{
type->setCodeGeneration(m_generate);
const int revisionIndex =
- indexOfAttribute(*attributes, QStringViewLiteral("revision"));
+ indexOfAttribute(*attributes, u"revision");
if (revisionIndex != -1)
type->setRevision(attributes->takeAt(revisionIndex).value().toInt());
}
FlagsTypeEntry *
TypeSystemParser::parseFlagsEntry(const QXmlStreamReader &,
- EnumTypeEntry *enumEntry,
- const QString &name, QString flagName,
+ EnumTypeEntry *enumEntry, QString flagName,
const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
- FlagsTypeEntry *ftype = new FlagsTypeEntry(QLatin1String("QFlags<") + name + QLatin1Char('>'), since);
+ if (!checkRootElement())
+ return nullptr;
+ auto ftype = new FlagsTypeEntry(QLatin1String("QFlags<") + enumEntry->name() + QLatin1Char('>'),
+ since,
+ currentParentTypeEntry()->typeSystemTypeEntry());
ftype->setOriginator(enumEntry);
ftype->setTargetLangPackage(enumEntry->targetLangPackage());
- // Try to get the guess the qualified flag name
- const int lastSepPos = name.lastIndexOf(colonColon());
- if (lastSepPos >= 0 && !flagName.contains(colonColon()))
- flagName.prepend(name.left(lastSepPos + 2));
+ // Try toenumEntry get the guess the qualified flag name
+ if (!flagName.contains(colonColon())) {
+ auto eq = enumEntry->qualifier();
+ if (!eq.isEmpty())
+ flagName.prepend(eq + colonColon());
+ }
ftype->setOriginalName(flagName);
applyCommonAttributes(ftype, attributes);
- QString n = ftype->originalName();
- QStringList lst = n.split(colonColon());
+ QStringList lst = flagName.split(colonColon());
+ const QString targetLangFlagName = QStringList(lst.mid(0, lst.size() - 1)).join(QLatin1Char('.'));
const QString &targetLangQualifier = enumEntry->targetLangQualifier();
- if (QStringList(lst.mid(0, lst.size() - 1)).join(colonColon()) != targetLangQualifier) {
+ if (targetLangFlagName != targetLangQualifier) {
qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("enum %1 and flags %2 differ in qualifiers")
- .arg(targetLangQualifier, lst.constFirst());
+ << QStringLiteral("enum %1 and flags %2 (%3) differ in qualifiers")
+ .arg(targetLangQualifier, lst.constFirst(), targetLangFlagName);
}
ftype->setFlagsName(lst.constLast());
@@ -1084,7 +1103,7 @@ FlagsTypeEntry *
m_database->addType(ftype);
const int revisionIndex =
- indexOfAttribute(*attributes, QStringViewLiteral("flags-revision"));
+ indexOfAttribute(*attributes, u"flags-revision");
ftype->setRevision(revisionIndex != -1
? attributes->takeAt(revisionIndex).value().toInt()
: enumEntry->revision());
@@ -1096,6 +1115,8 @@ SmartPointerTypeEntry *
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
+ if (!checkRootElement())
+ return nullptr;
QString smartPointerType;
QString getter;
QString refCountMethodName;
@@ -1138,7 +1159,8 @@ SmartPointerTypeEntry *
return nullptr;
}
- auto *type = new SmartPointerTypeEntry(name, getter, smartPointerType, refCountMethodName, since);
+ auto *type = new SmartPointerTypeEntry(name, getter, smartPointerType,
+ refCountMethodName, since, currentParentTypeEntry());
applyCommonAttributes(type, attributes);
return type;
}
@@ -1148,12 +1170,14 @@ PrimitiveTypeEntry *
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
- auto *type = new PrimitiveTypeEntry(name, since);
+ if (!checkRootElement())
+ return nullptr;
+ auto *type = new PrimitiveTypeEntry(name, since, currentParentTypeEntry());
applyCommonAttributes(type, attributes);
for (int i = attributes->size() - 1; i >= 0; --i) {
const QStringRef name = attributes->at(i).qualifiedName();
- if (name == QLatin1String("target-lang-name")) {
- type->setTargetLangName(attributes->takeAt(i).value().toString());
+ if (name == targetLangNameAttribute()) {
+ type->setTargetLangName(attributes->takeAt(i).value().toString());
} else if (name == QLatin1String("target-lang-api-name")) {
type->setTargetLangApiName(attributes->takeAt(i).value().toString());
} else if (name == preferredConversionAttribute()) {
@@ -1168,8 +1192,6 @@ PrimitiveTypeEntry *
}
}
- if (type->targetLangName().isEmpty())
- type->setTargetLangName(type->name());
if (type->targetLangApiName().isEmpty())
type->setTargetLangApiName(type->name());
type->setTargetLangPackage(m_defaultPackage);
@@ -1181,7 +1203,9 @@ ContainerTypeEntry *
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
- const int typeIndex = indexOfAttribute(*attributes, QStringViewLiteral("type"));
+ if (!checkRootElement())
+ return nullptr;
+ const int typeIndex = indexOfAttribute(*attributes, u"type");
if (typeIndex == -1) {
m_error = QLatin1String("no 'type' attribute specified");
return nullptr;
@@ -1192,24 +1216,19 @@ ContainerTypeEntry *
m_error = QLatin1String("there is no container of type ") + typeName.toString();
return nullptr;
}
- auto *type = new ContainerTypeEntry(name, containerType, since);
+ auto *type = new ContainerTypeEntry(name, containerType, since, currentParentTypeEntry());
applyCommonAttributes(type, attributes);
return type;
}
EnumTypeEntry *
TypeSystemParser::parseEnumTypeEntry(const QXmlStreamReader &reader,
- const QString &fullName, const QVersionNumber &since,
+ const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
- QString scope;
- QString name = fullName;
- const int sep = fullName.lastIndexOf(colonColon());
- if (sep != -1) {
- scope = fullName.left(sep);
- name = fullName.right(fullName.size() - sep - 2);
- }
- auto *entry = new EnumTypeEntry(scope, name, since);
+ if (!checkRootElement())
+ return nullptr;
+ auto *entry = new EnumTypeEntry(name, since, currentParentTypeEntry());
applyCommonAttributes(entry, attributes);
entry->setTargetLangPackage(m_defaultPackage);
@@ -1237,7 +1256,7 @@ EnumTypeEntry *
if (!flagNames.isEmpty()) {
const QStringList &flagNameList = flagNames.split(QLatin1Char(','));
for (const QString &flagName : flagNameList)
- parseFlagsEntry(reader, entry, fullName, flagName.trimmed(), since, attributes);
+ parseFlagsEntry(reader, entry, flagName.trimmed(), since, attributes);
}
return entry;
}
@@ -1247,13 +1266,15 @@ ObjectTypeEntry *
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
- auto *otype = new ObjectTypeEntry(name, since);
+ if (!checkRootElement())
+ return nullptr;
+ auto *otype = new ObjectTypeEntry(name, since, currentParentTypeEntry());
applyCommonAttributes(otype, attributes);
QString targetLangName = name;
bool generate = true;
for (int i = attributes->size() - 1; i >= 0; --i) {
const QStringRef name = attributes->at(i).qualifiedName();
- if (name == QLatin1String("target-lang-name")) {
+ if (name == targetLangNameAttribute()) {
targetLangName = attributes->takeAt(i).value().toString();
} else if (name == generateAttribute()) {
generate = convertBoolean(attributes->takeAt(i).value(),
@@ -1261,8 +1282,9 @@ ObjectTypeEntry *
}
}
- InterfaceTypeEntry *itype =
- new InterfaceTypeEntry(InterfaceTypeEntry::interfaceName(targetLangName), since);
+ auto itype = new InterfaceTypeEntry(InterfaceTypeEntry::interfaceName(targetLangName),
+ since, currentParentTypeEntry());
+ itype->setTargetLangName(targetLangName);
if (generate)
itype->setCodeGeneration(m_generate);
@@ -1279,7 +1301,9 @@ NamespaceTypeEntry *
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
- QScopedPointer<NamespaceTypeEntry> result(new NamespaceTypeEntry(name, since));
+ if (!checkRootElement())
+ return nullptr;
+ QScopedPointer<NamespaceTypeEntry> result(new NamespaceTypeEntry(name, since, currentParentTypeEntry()));
applyCommonAttributes(result.data(), attributes);
applyComplexTypeAttributes(reader, result.data(), attributes);
for (int i = attributes->size() - 1; i >= 0; --i) {
@@ -1320,10 +1344,12 @@ ValueTypeEntry *
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
- auto *typeEntry = new ValueTypeEntry(name, since);
+ if (!checkRootElement())
+ return nullptr;
+ auto *typeEntry = new ValueTypeEntry(name, since, currentParentTypeEntry());
applyCommonAttributes(typeEntry, attributes);
const int defaultCtIndex =
- indexOfAttribute(*attributes, QStringViewLiteral("default-constructor"));
+ indexOfAttribute(*attributes, u"default-constructor");
if (defaultCtIndex != -1)
typeEntry->setDefaultConstructor(attributes->takeAt(defaultCtIndex).value().toString());
return typeEntry;
@@ -1334,6 +1360,8 @@ FunctionTypeEntry *
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
+ if (!checkRootElement())
+ return nullptr;
const int signatureIndex = indexOfAttribute(*attributes, signatureAttribute());
if (signatureIndex == -1) {
m_error = msgMissingAttribute(signatureAttribute());
@@ -1345,7 +1373,7 @@ FunctionTypeEntry *
TypeEntry *existingType = m_database->findType(name);
if (!existingType) {
- auto *result = new FunctionTypeEntry(name, signature, since);
+ auto *result = new FunctionTypeEntry(name, signature, since, currentParentTypeEntry());
applyCommonAttributes(result, attributes);
return result;
}
@@ -1366,6 +1394,8 @@ TypedefEntry *
const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
+ if (!checkRootElement())
+ return nullptr;
if (m_current && m_current->type != StackElement::Root
&& m_current->type != StackElement::NamespaceTypeEntry) {
m_error = QLatin1String("typedef entries must be nested in namespaces or type system.");
@@ -1377,7 +1407,7 @@ TypedefEntry *
return nullptr;
}
const QString sourceType = attributes->takeAt(sourceIndex).value().toString();
- auto result = new TypedefEntry(name, sourceType, since);
+ auto result = new TypedefEntry(name, sourceType, since, currentParentTypeEntry());
applyCommonAttributes(result, attributes);
return result;
}
@@ -1407,7 +1437,7 @@ void TypeSystemParser::applyComplexTypeAttributes(const QXmlStreamReader &reader
qPrintable(msgUnimplementedAttributeWarning(reader, name)));
const bool v = convertBoolean(attributes->takeAt(i).value(), genericClassAttribute(), false);
ctype->setGenericClass(v);
- } else if (name == QLatin1String("target-lang-name")) {
+ } else if (name == targetLangNameAttribute()) {
ctype->setTargetLangName(attributes->takeAt(i).value().toString());
} else if (name == QLatin1String("polymorphic-base")) {
ctype->setPolymorphicIdValue(attributes->takeAt(i).value().toString());
@@ -1618,8 +1648,10 @@ TypeSystemTypeEntry *TypeSystemParser::parseRootElement(const QXmlStreamReader &
auto *moduleEntry =
const_cast<TypeSystemTypeEntry *>(m_database->findTypeSystemType(m_defaultPackage));
const bool add = moduleEntry == nullptr;
- if (add)
- moduleEntry = new TypeSystemTypeEntry(m_defaultPackage, since);
+ if (add) {
+ moduleEntry = new TypeSystemTypeEntry(m_defaultPackage, since,
+ currentParentTypeEntry());
+ }
moduleEntry->setCodeGeneration(m_generate);
if ((m_generate == TypeEntry::GenerateForSubclass ||
@@ -1887,7 +1919,7 @@ bool TypeSystemParser::parseNoNullPointer(const QXmlStreamReader &reader,
lastArgMod.noNullPointers = true;
const int defaultValueIndex =
- indexOfAttribute(*attributes, QStringViewLiteral("default-value"));
+ indexOfAttribute(*attributes, u"default-value");
if (defaultValueIndex != -1) {
const QXmlStreamAttribute attribute = attributes->takeAt(defaultValueIndex);
qCWarning(lcShiboken, "%s",
@@ -2266,7 +2298,7 @@ bool TypeSystemParser::parseReplaceDefaultExpression(const QXmlStreamReader &,
m_error = QLatin1String("Replace default expression only allowed as child of argument modification");
return false;
}
- const int withIndex = indexOfAttribute(*attributes, QStringViewLiteral("with"));
+ const int withIndex = indexOfAttribute(*attributes, u"with");
if (withIndex == -1 || attributes->at(withIndex).value().isEmpty()) {
m_error = QLatin1String("Default expression replaced with empty string. Use remove-default-expression instead.");
return false;
@@ -2630,6 +2662,12 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
return false;
}
}
+ // Allow for primitive and/or std:: types only, else require proper nesting.
+ if (element->type != StackElement::PrimitiveTypeEntry && name.contains(QLatin1Char(':'))
+ && !name.contains(QLatin1String("std::"))) {
+ m_error = msgIncorrectlyNestedName(name);
+ return false;
+ }
if (m_database->hasDroppedTypeEntries()) {
QString identifier = getNamePrefix(element) + QLatin1Char('.');
@@ -2677,13 +2715,6 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
}
}
- // Fix type entry name using nesting information.
- if (element->type & StackElement::TypeEntryMask
- && element->parent && element->parent->type != StackElement::Root) {
- name = element->parent->entry->name() + colonColon() + name;
- }
-
-
if (name.isEmpty()) {
m_error = QLatin1String("no 'name' attribute specified");
return false;
@@ -2691,7 +2722,9 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
switch (element->type) {
case StackElement::CustomTypeEntry:
- element->entry = new TypeEntry(name, TypeEntry::CustomType, since);
+ if (!checkRootElement())
+ return false;
+ element->entry = new TypeEntry(name, TypeEntry::CustomType, since, m_current->entry);
break;
case StackElement::PrimitiveTypeEntry:
element->entry = parsePrimitiveTypeEntry(reader, name, since, &attributes);
@@ -2745,7 +2778,9 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
return false;
break;
case StackElement::ObjectTypeEntry:
- element->entry = new ObjectTypeEntry(name, since);
+ if (!checkRootElement())
+ return false;
+ element->entry = new ObjectTypeEntry(name, since, currentParentTypeEntry());
applyCommonAttributes(element->entry, &attributes);
applyComplexTypeAttributes(reader, static_cast<ComplexTypeEntry *>(element->entry), &attributes);
break;
diff --git a/sources/shiboken2/ApiExtractor/typesystemparser.h b/sources/shiboken2/ApiExtractor/typesystemparser.h
index aaf22353e..d3ea54fc6 100644
--- a/sources/shiboken2/ApiExtractor/typesystemparser.h
+++ b/sources/shiboken2/ApiExtractor/typesystemparser.h
@@ -162,6 +162,8 @@ private:
bool importFileElement(const QXmlStreamAttributes &atts);
+ const TypeEntry *currentParentTypeEntry() const;
+ bool checkRootElement();
void applyCommonAttributes(TypeEntry *type, QXmlStreamAttributes *attributes) const;
PrimitiveTypeEntry *
parsePrimitiveTypeEntry(const QXmlStreamReader &, const QString &name,
@@ -174,8 +176,8 @@ private:
const QVersionNumber &since, QXmlStreamAttributes *);
FlagsTypeEntry *
parseFlagsEntry(const QXmlStreamReader &, EnumTypeEntry *enumEntry,
- const QString &name, QString flagName,
- const QVersionNumber &since, QXmlStreamAttributes *);
+ QString flagName, const QVersionNumber &since,
+ QXmlStreamAttributes *);
NamespaceTypeEntry *
parseNamespaceTypeEntry(const QXmlStreamReader &,
diff --git a/sources/shiboken2/data/shiboken_helpers.cmake b/sources/shiboken2/data/shiboken_helpers.cmake
index 8111fa61f..5d7ff56bb 100644
--- a/sources/shiboken2/data/shiboken_helpers.cmake
+++ b/sources/shiboken2/data/shiboken_helpers.cmake
@@ -221,15 +221,20 @@ macro(set_quiet_build)
endmacro()
macro(get_python_extension_suffix)
- # Result of imp.get_suffixes() depends on the platform, but generally looks something like:
- # [('.cpython-34m-x86_64-linux-gnu.so', 'rb', 3), ('.cpython-34m.so', 'rb', 3),
- # ('.abi3.so', 'rb', 3), ('.so', 'rb', 3), ('.py', 'r', 1), ('.pyc', 'rb', 2)]
- # We pick the first most detailed one, strip of the file extension part.
+ # Result of importlib.machinery.EXTENSION_SUFFIXES depends on the platform,
+ # but generally looks something like:
+ # ['.cpython-38-x86_64-linux-gnu.so', '.abi3.so', '.so']
+ # We pick the first most detailed one.
execute_process(
COMMAND ${PYTHON_EXECUTABLE} -c "if True:
- import imp, re
- first_suffix = imp.get_suffixes()[0][0]
+ import re
+ try:
+ from importlib import machinery
+ first_suffix = machinery.EXTENSION_SUFFIXES[0]
+ except AttributeError:
+ import imp
+ first_suffix = imp.get_suffixes()[0][0]
res = re.search(r'^(.+)\\.', first_suffix)
if res:
first_suffix = res.group(1)
diff --git a/sources/shiboken2/generator/generator.cpp b/sources/shiboken2/generator/generator.cpp
index 6da9fd933..484b1f641 100644
--- a/sources/shiboken2/generator/generator.cpp
+++ b/sources/shiboken2/generator/generator.cpp
@@ -430,9 +430,16 @@ bool Generator::generate()
return false;
}
+ const auto smartPointers = m_d->apiextractor->smartPointers();
for (const AbstractMetaType *type : qAsConst(m_d->instantiatedSmartPointers)) {
AbstractMetaClass *smartPointerClass =
- AbstractMetaClass::findClass(m_d->apiextractor->smartPointers(), type->typeEntry());
+ AbstractMetaClass::findClass(smartPointers, type->typeEntry());
+ if (!smartPointerClass) {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgCannotFindSmartPointer(type->cppSignature(),
+ smartPointers)));
+ return false;
+ }
GeneratorContext context(smartPointerClass, type, true);
if (!generateFileForContext(context))
return false;
@@ -760,7 +767,7 @@ DefaultValue Generator::minimalConstructor(const AbstractMetaClass *metaClass) c
bool simple = true;
bool suitable = true;
for (int i = 0, size = arguments.size();
- suitable && i < size && !arguments.at(i)->hasDefaultValueExpression(); ++i) {
+ suitable && i < size && !arguments.at(i)->hasOriginalDefaultValueExpression(); ++i) {
const AbstractMetaArgument *arg = arguments.at(i);
const TypeEntry *aType = arg->type()->typeEntry();
suitable &= aType != cType;
@@ -777,11 +784,12 @@ DefaultValue Generator::minimalConstructor(const AbstractMetaClass *metaClass) c
bool ok = true;
for (int i =0, size = arguments.size(); ok && i < size; ++i) {
const AbstractMetaArgument *arg = arguments.at(i);
- if (arg->hasDefaultValueExpression()) {
- if (arg->hasModifiedDefaultValueExpression())
- args << arg->defaultValueExpression(); // Spell out modified values
+ if (arg->hasModifiedDefaultValueExpression()) {
+ args << arg->defaultValueExpression(); // Spell out modified values
break;
}
+ if (arg->hasOriginalDefaultValueExpression())
+ break;
auto argValue = minimalConstructor(arg->type());
ok &= argValue.isValid();
args << argValue.constructorParameter();
diff --git a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
index 86abf21b0..ca9f9b3ae 100644
--- a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
+++ b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
@@ -438,15 +438,15 @@ QString QtXmlToSphinx::resolveContextForMethod(const QString& methodName) const
}
if (metaClass) {
- QList<const AbstractMetaFunction*> funcList;
+ AbstractMetaFunctionList funcList;
const AbstractMetaFunctionList &methods = metaClass->queryFunctionsByName(methodName);
- for (const AbstractMetaFunction *func : methods) {
+ for (AbstractMetaFunction *func : methods) {
if (methodName == func->name())
funcList.append(func);
}
const AbstractMetaClass *implementingClass = nullptr;
- for (const AbstractMetaFunction *func : qAsConst(funcList)) {
+ for (AbstractMetaFunction *func : qAsConst(funcList)) {
implementingClass = func->implementingClass();
if (implementingClass->name() == currentClass)
break;
@@ -847,7 +847,7 @@ void QtXmlToSphinx::handleTableTag(QXmlStreamReader& reader)
m_tableHasHeader = false;
} else if (token == QXmlStreamReader::EndElement) {
// write the table on m_output
- m_currentTable.enableHeader(m_tableHasHeader);
+ m_currentTable.setHeaderEnabled(m_tableHasHeader);
m_currentTable.normalize();
m_output << ensureEndl << m_currentTable;
m_currentTable.clear();
@@ -864,7 +864,7 @@ void QtXmlToSphinx::handleTermTag(QXmlStreamReader& reader)
} else if (token == QXmlStreamReader::EndElement) {
TableCell cell;
cell.data = popOutputBuffer().trimmed();
- m_currentTable << (TableRow() << cell);
+ m_currentTable.appendRow(TableRow(1, cell));
}
}
@@ -874,7 +874,7 @@ void QtXmlToSphinx::handleItemTag(QXmlStreamReader& reader)
QXmlStreamReader::TokenType token = reader.tokenType();
if (token == QXmlStreamReader::StartElement) {
if (m_currentTable.isEmpty())
- m_currentTable << TableRow();
+ m_currentTable.appendRow({});
TableRow& row = m_currentTable.last();
TableCell cell;
cell.colSpan = reader.attributes().value(QLatin1String("colspan")).toShort();
@@ -896,7 +896,7 @@ void QtXmlToSphinx::handleRowTag(QXmlStreamReader& reader)
QXmlStreamReader::TokenType token = reader.tokenType();
if (token == QXmlStreamReader::StartElement) {
m_tableHasHeader = reader.name() == QLatin1String("header");
- m_currentTable << TableRow();
+ m_currentTable.appendRow({});
}
}
@@ -919,8 +919,8 @@ void QtXmlToSphinx::handleListTag(QXmlStreamReader& reader)
if (token == QXmlStreamReader::StartElement) {
listType = webXmlListType(reader.attributes().value(QLatin1String("type")));
if (listType == EnumeratedList) {
- m_currentTable << TableRow{TableCell(QLatin1String("Constant")),
- TableCell(QLatin1String("Description"))};
+ m_currentTable.appendRow(TableRow{TableCell(QLatin1String("Constant")),
+ TableCell(QLatin1String("Description"))});
m_tableHasHeader = true;
}
INDENT.indent--;
@@ -943,7 +943,7 @@ void QtXmlToSphinx::handleListTag(QXmlStreamReader& reader)
}
break;
case EnumeratedList:
- m_currentTable.enableHeader(m_tableHasHeader);
+ m_currentTable.setHeaderEnabled(m_tableHasHeader);
m_currentTable.normalize();
m_output << ensureEndl << m_currentTable;
break;
@@ -1328,53 +1328,49 @@ void QtXmlToSphinx::Table::normalize()
if (m_normalized || isEmpty())
return;
- int row;
- int col;
- QtXmlToSphinx::Table& self = *this;
-
//QDoc3 generates tables with wrong number of columns. We have to
//check and if necessary, merge the last columns.
int maxCols = -1;
- for (const auto &row : qAsConst(self)) {
+ for (const auto &row : qAsConst(m_rows)) {
if (row.count() > maxCols)
maxCols = row.count();
}
if (maxCols <= 0)
return;
// add col spans
- for (row = 0; row < count(); ++row) {
- for (col = 0; col < at(row).count(); ++col) {
- QtXmlToSphinx::TableCell& cell = self[row][col];
+ for (int row = 0; row < m_rows.count(); ++row) {
+ for (int col = 0; col < m_rows.at(row).count(); ++col) {
+ QtXmlToSphinx::TableCell& cell = m_rows[row][col];
bool mergeCols = (col >= maxCols);
if (cell.colSpan > 0) {
QtXmlToSphinx::TableCell newCell;
newCell.colSpan = -1;
for (int i = 0, max = cell.colSpan-1; i < max; ++i) {
- self[row].insert(col+1, newCell);
+ m_rows[row].insert(col + 1, newCell);
}
cell.colSpan = 0;
col++;
} else if (mergeCols) {
- self[row][maxCols - 1].data += QLatin1Char(' ') + cell.data;
+ m_rows[row][maxCols - 1].data += QLatin1Char(' ') + cell.data;
}
}
}
// row spans
- const int numCols = first().count();
- for (col = 0; col < numCols; ++col) {
- for (row = 0; row < count(); ++row) {
- if (col < self[row].count()) {
- QtXmlToSphinx::TableCell& cell = self[row][col];
+ const int numCols = m_rows.constFirst().count();
+ for (int col = 0; col < numCols; ++col) {
+ for (int row = 0; row < m_rows.count(); ++row) {
+ if (col < m_rows[row].count()) {
+ QtXmlToSphinx::TableCell& cell = m_rows[row][col];
if (cell.rowSpan > 0) {
QtXmlToSphinx::TableCell newCell;
newCell.rowSpan = -1;
int targetRow = row + 1;
const int targetEndRow =
- std::min(targetRow + cell.rowSpan - 1, count());
+ std::min(targetRow + cell.rowSpan - 1, m_rows.count());
cell.rowSpan = 0;
for ( ; targetRow < targetEndRow; ++targetRow)
- self[targetRow].insert(col, newCell);
+ m_rows[targetRow].insert(col, newCell);
row++;
}
}
@@ -1385,20 +1381,26 @@ void QtXmlToSphinx::Table::normalize()
QTextStream& operator<<(QTextStream& s, const QtXmlToSphinx::Table &table)
{
- if (table.isEmpty())
- return s;
+ table.format(s);
+ return s;
+}
- if (!table.isNormalized()) {
+void QtXmlToSphinx::Table::format (QTextStream& s) const
+{
+ if (isEmpty())
+ return;
+
+ if (!isNormalized()) {
qCDebug(lcShiboken) << "Attempt to print an unnormalized table!";
- return s;
+ return;
}
// calc width and height of each column and row
- const int headerColumnCount = table.constFirst().count();
+ const int headerColumnCount = m_rows.constFirst().count();
QVector<int> colWidths(headerColumnCount);
- QVector<int> rowHeights(table.count());
- for (int i = 0, maxI = table.count(); i < maxI; ++i) {
- const QtXmlToSphinx::TableRow& row = table[i];
+ QVector<int> rowHeights(m_rows.count());
+ for (int i = 0, maxI = m_rows.count(); i < maxI; ++i) {
+ const QtXmlToSphinx::TableRow& row = m_rows.at(i);
for (int j = 0, maxJ = std::min(row.count(), colWidths.size()); j < maxJ; ++j) {
const QVector<QStringRef> rowLines = row[j].data.splitRef(QLatin1Char('\n')); // cache this would be a good idea
for (const QStringRef &str : rowLines)
@@ -1408,7 +1410,7 @@ QTextStream& operator<<(QTextStream& s, const QtXmlToSphinx::Table &table)
}
if (!*std::max_element(colWidths.begin(), colWidths.end()))
- return s; // empty table (table with empty cells)
+ return; // empty table (table with empty cells)
// create a horizontal line to be used later.
QString horizontalLine = QLatin1String("+");
@@ -1418,8 +1420,8 @@ QTextStream& operator<<(QTextStream& s, const QtXmlToSphinx::Table &table)
}
// write table rows
- for (int i = 0, maxI = table.count(); i < maxI; ++i) { // for each row
- const QtXmlToSphinx::TableRow& row = table[i];
+ for (int i = 0, maxI = m_rows.count(); i < maxI; ++i) { // for each row
+ const QtXmlToSphinx::TableRow& row = m_rows.at(i);
// print line
s << INDENT << '+';
@@ -1427,7 +1429,7 @@ QTextStream& operator<<(QTextStream& s, const QtXmlToSphinx::Table &table)
char c;
if (col >= row.length() || row[col].rowSpan == -1)
c = ' ';
- else if (i == 1 && table.hasHeader())
+ else if (i == 1 && hasHeader())
c = '=';
else
c = '-';
@@ -1461,7 +1463,6 @@ QTextStream& operator<<(QTextStream& s, const QtXmlToSphinx::Table &table)
}
s << INDENT << horizontalLine << endl;
s << endl;
- return s;
}
static QString getFuncName(const AbstractMetaFunction* cppFunc) {
@@ -2159,7 +2160,7 @@ static void writeFancyToc(QTextStream& s, const QStringList& items, int cols = 4
currentColData.clear();
i = 0;
}
- table << row;
+ table.appendRow(row);
table.normalize();
s << ".. container:: pysidetoc" << endl << endl;
s << table;
@@ -2192,15 +2193,23 @@ void QtDocGenerator::writeModuleDocumentation()
/* Avoid showing "Detailed Description for *every* class in toc tree */
Indentation indentation(INDENT);
+ // Store the it.key() in a QString so that it can be stripped off unwanted
+ // information when neeeded. For example, the RST files in the extras directory
+ // doesn't include the PySide# prefix in their names.
+ const QString moduleName = it.key();
+ const int lastIndex = moduleName.lastIndexOf(QLatin1Char('.'));
// Search for extra-sections
if (!m_extraSectionDir.isEmpty()) {
QDir extraSectionDir(m_extraSectionDir);
- QStringList fileList = extraSectionDir.entryList(QStringList() << (it.key() + QLatin1String("?*.rst")), QDir::Files);
+ if (!extraSectionDir.exists())
+ qCWarning(lcShiboken) << m_extraSectionDir << "doesn't exist";
+
+ QStringList fileList = extraSectionDir.entryList(QStringList() << (moduleName.mid(lastIndex + 1) + QLatin1String("?*.rst")), QDir::Files);
QStringList::iterator it2 = fileList.begin();
for (; it2 != fileList.end(); ++it2) {
QString origFileName(*it2);
- it2->remove(0, it.key().count() + 1);
+ it2->remove(0, moduleName.indexOf(QLatin1Char('.')));
QString newFilePath = outputDir + QLatin1Char('/') + *it2;
if (QFile::exists(newFilePath))
QFile::remove(newFilePath);
@@ -2230,7 +2239,7 @@ void QtDocGenerator::writeModuleDocumentation()
s << "--------------------" << endl << endl;
// module doc is always wrong and C++istic, so go straight to the extra directory!
- QFile moduleDoc(m_extraSectionDir + QLatin1Char('/') + it.key() + QLatin1String(".rst"));
+ QFile moduleDoc(m_extraSectionDir + QLatin1Char('/') + moduleName.mid(lastIndex + 1) + QLatin1String(".rst"));
if (moduleDoc.open(QIODevice::ReadOnly | QIODevice::Text)) {
s << moduleDoc.readAll();
moduleDoc.close();
diff --git a/sources/shiboken2/generator/qtdoc/qtdocgenerator.h b/sources/shiboken2/generator/qtdoc/qtdocgenerator.h
index 53e292d22..56cb9c4bb 100644
--- a/sources/shiboken2/generator/qtdoc/qtdocgenerator.h
+++ b/sources/shiboken2/generator/qtdoc/qtdocgenerator.h
@@ -67,13 +67,16 @@ public:
TableCell(const char* text) : data(QLatin1String(text)) {}
};
- using TableRow = QList<TableCell>;
- class Table : public QList<TableRow>
+ using TableRow = QVector<TableCell>;
+
+ class Table
{
public:
Table() = default;
- void enableHeader(bool enable)
+ bool isEmpty() const { return m_rows.isEmpty(); }
+
+ void setHeaderEnabled(bool enable)
{
m_hasHeader = enable;
}
@@ -92,10 +95,19 @@ public:
void clear() {
m_normalized = false;
- QList<TableRow>::clear();
+ m_rows.clear();
}
+ void appendRow(const TableRow &row) { m_rows.append(row); }
+
+ const TableRow &constFirst() { return m_rows.constFirst(); }
+ TableRow &first() { return m_rows.first(); }
+ TableRow &last() { return m_rows.last(); }
+
+ void format (QTextStream& s) const;
+
private:
+ QVector<TableRow> m_rows;
bool m_hasHeader = false;
bool m_normalized = false;
};
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index 61429b383..5460fd7c7 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -317,7 +317,10 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
s << "#include <pyside.h>" << endl;
s << "#include <destroylistener.h>" << endl;
s << "#include <qapp_macro.h>" << endl;
- }
+ s << endl;
+ s << "QT_WARNING_DISABLE_DEPRECATED" << endl;
+ s << endl;
+ }
s << "#include <typeinfo>" << endl;
if (usePySideExtensions() && metaClass->isQObject()) {
@@ -368,9 +371,6 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
if (metaClass->typeEntry()->typeFlags() & ComplexTypeEntry::Deprecated)
s << "#Deprecated" << endl;
- if (usePySideExtensions())
- s << "\nQT_WARNING_DISABLE_DEPRECATED\n";
-
// Use class base namespace
{
const AbstractMetaClass *context = metaClass->enclosingClass();
@@ -1684,7 +1684,7 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
argNamesSet << arg->name();
}
}
- QStringList argNamesList = argNamesSet.toList();
+ QStringList argNamesList = argNamesSet.values();
std::sort(argNamesList.begin(), argNamesList.end());
if (argNamesList.isEmpty()) {
s << INDENT << "const char **argNames{};" << endl;
@@ -1860,18 +1860,19 @@ void CppGenerator::writeMethodWrapper(QTextStream &s, const AbstractMetaFunction
// For custom classes, operations like __radd__ and __rmul__
// will enter an infinite loop.
if (rfunc->isBinaryOperator() && revOpName.contains(QLatin1String("shift"))) {
+ s << INDENT << "Shiboken::AutoDecRef attrName(Py_BuildValue(\"s\", \"" << revOpName << "\"));" << endl;
s << INDENT << "if (!isReverse" << endl;
{
Indentation indent(INDENT);
s << INDENT << "&& Shiboken::Object::checkType(" << PYTHON_ARG << ")" << endl;
s << INDENT << "&& !PyObject_TypeCheck(" << PYTHON_ARG << ", self->ob_type)" << endl;
- s << INDENT << "&& PyObject_HasAttrString(" << PYTHON_ARG << ", const_cast<char *>(\"" << revOpName << "\"))) {" << endl;
+ s << INDENT << "&& PyObject_HasAttr(" << PYTHON_ARG << ", attrName)) {" << endl;
// This PyObject_CallMethod call will emit lots of warnings like
// "deprecated conversion from string constant to char *" during compilation
// due to the method name argument being declared as "char *" instead of "const char *"
// issue 6952 http://bugs.python.org/issue6952
- s << INDENT << "PyObject *revOpMethod = PyObject_GetAttrString(" << PYTHON_ARG << ", const_cast<char *>(\"" << revOpName << "\"));" << endl;
+ s << INDENT << "PyObject *revOpMethod = PyObject_GetAttr(" << PYTHON_ARG << ", attrName);" << endl;
s << INDENT << "if (revOpMethod && PyCallable_Check(revOpMethod)) {" << endl;
{
Indentation indent(INDENT);
@@ -2154,6 +2155,8 @@ void CppGenerator::writeTypeCheck(QTextStream &s, const AbstractMetaType *argTyp
QString customCheck;
if (!customType.isEmpty()) {
AbstractMetaType *metaType;
+ // PYSIDE-795: Note: XML-Overrides are handled in this shibokengenerator function!
+ // This enables iterables for QMatrix4x4 for instance.
customCheck = guessCPythonCheckFunction(customType, &metaType);
if (metaType)
argType = metaType;
@@ -2939,6 +2942,9 @@ void CppGenerator::writePythonToCppConversionFunctions(QTextStream &s,
typeCheck = QLatin1String("PyType_Check(%in)");
else if (pyTypeName == QLatin1String("PyObject"))
typeCheck = QLatin1String("PyObject_TypeCheck(%in, &PyBaseObject_Type)");
+ // PYSIDE-795: We abuse PySequence for iterables
+ else if (pyTypeName == QLatin1String("PySequence"))
+ typeCheck = QLatin1String("Shiboken::String::checkIterable(%in)");
else if (pyTypeName.startsWith(QLatin1String("Py")))
typeCheck = pyTypeName + QLatin1String("_Check(%in)");
}
@@ -3039,29 +3045,31 @@ void CppGenerator::writeNamedArgumentResolution(QTextStream &s, const AbstractMe
QString pyArgName = usePyArgs ? pythonArgsAt(pyArgIndex) : QLatin1String(PYTHON_ARG);
s << INDENT << "keyName = Py_BuildValue(\"s\",\"" << arg->name() << "\");" << endl;
s << INDENT << "if (PyDict_Contains(kwds, keyName)) {" << endl;
- s << INDENT << "value = PyDict_GetItemString(kwds, \"" << arg->name() << "\");" << endl;
- s << INDENT << "if (value && " << pyArgName << ") {" << endl;
{
Indentation indent(INDENT);
- s << INDENT << pyErrString.arg(arg->name()) << endl;
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
- }
- s << INDENT << INDENT << "} else if (value) {" << endl;
- {
- Indentation indent(INDENT);
- s << INDENT << pyArgName << " = value;" << endl;
- s << INDENT << "if (!";
- writeTypeCheck(s, arg->type(), pyArgName, isNumber(arg->type()->typeEntry()), func->typeReplaced(arg->argumentIndex() + 1));
- s << ')' << endl;
+ s << INDENT << "value = PyDict_GetItem(kwds, keyName);" << endl;
+ s << INDENT << "if (value && " << pyArgName << ") {" << endl;
+ {
+ Indentation indent(INDENT);
+ s << INDENT << pyErrString.arg(arg->name()) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ }
+ s << INDENT << '}' << endl;
+ s << INDENT << "if (value) {" << endl;
{
Indentation indent(INDENT);
- s << INDENT << "goto " << cpythonFunctionName(func) << "_TypeError;" << endl;
+ s << INDENT << pyArgName << " = value;" << endl;
+ s << INDENT << "if (!";
+ writeTypeCheck(s, arg->type(), pyArgName, isNumber(arg->type()->typeEntry()), func->typeReplaced(arg->argumentIndex() + 1));
+ s << ')' << endl;
+ {
+ Indentation indent(INDENT);
+ s << INDENT << "goto " << cpythonFunctionName(func) << "_TypeError;" << endl;
+ }
}
+ s << INDENT << '}' << endl;
}
s << INDENT << '}' << endl;
- if (arg != args.constLast())
- s << INDENT;
- s << "}" << endl;
}
}
s << INDENT << '}' << endl;
@@ -4563,23 +4571,6 @@ void CppGenerator::writeMethodDefinition(QTextStream &s, const AbstractMetaFunct
s << ',' << endl;
}
-static QString resolveRetOrArgType(const AbstractMetaType *someType)
-{
- QString strRetArg;
- if (CppGenerator::isCString(someType)) {
- strRetArg = QLatin1String("str");
- } else if (someType->isPrimitive()) {
- auto ptp = static_cast<const PrimitiveTypeEntry *>(someType->typeEntry());
- while (ptp->referencedTypeEntry())
- ptp = ptp->referencedTypeEntry();
- strRetArg = ptp->name();
- } else {
- strRetArg = someType->fullName();
- }
- strRetArg.replace(QLatin1String("::"), QLatin1String("."));
- return strRetArg;
-}
-
void CppGenerator::writeSignatureInfo(QTextStream &s, const AbstractMetaFunctionList &overloads)
{
OverloadData overloadData(overloads, this);
@@ -4593,11 +4584,7 @@ void CppGenerator::writeSignatureInfo(QTextStream &s, const AbstractMetaFunction
QStringList args;
const AbstractMetaArgumentList &arguments = f->arguments();
for (const AbstractMetaArgument *arg : arguments) {
- AbstractMetaType *argType = getTypeWithoutContainer(arg->type());
- QString strArg = resolveRetOrArgType(arg->type());
- // PYSIDE-921: Handle container returntypes correctly.
- if (argType != arg->type())
- strArg += QLatin1Char('[') + resolveRetOrArgType(argType) + QLatin1Char(']');
+ QString strArg = arg->type()->pythonSignature();
if (!arg->defaultValueExpression().isEmpty()) {
strArg += QLatin1Char('=');
QString e = arg->defaultValueExpression();
@@ -4612,12 +4599,8 @@ void CppGenerator::writeSignatureInfo(QTextStream &s, const AbstractMetaFunction
if (multiple)
s << idx-- << ':';
s << funcName << '(' << args.join(QLatin1Char(',')) << ')';
- AbstractMetaType *returnType = getTypeWithoutContainer(f->type());
- // PYSIDE-921: Handle container returntypes correctly.
- if (returnType != f->type())
- s << "->" << resolveRetOrArgType(f->type()) << '[' << resolveRetOrArgType(returnType) << ']';
- else if (returnType)
- s << "->" << resolveRetOrArgType(returnType);
+ if (f->type())
+ s << "->" << f->type()->pythonSignature();
s << endl;
}
}
@@ -4634,6 +4617,15 @@ void CppGenerator::writeEnumsInitialization(QTextStream &s, AbstractMetaEnumList
}
}
+static QString mangleName(QString name)
+{
+ if ( name == QLatin1String("None")
+ || name == QLatin1String("False")
+ || name == QLatin1String("True"))
+ name += QLatin1Char('_');
+ return name;
+}
+
void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnum *cppEnum)
{
const AbstractMetaClass *enclosingClass = getProperEnclosingClassForEnum(cppEnum);
@@ -4713,7 +4705,7 @@ void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnu
Indentation indent(INDENT);
s << INDENT << "PyObject *anonEnumItem = PyInt_FromLong(" << enumValueText << ");" << endl;
s << INDENT << "if (PyDict_SetItemString(reinterpret_cast<PyTypeObject *>(reinterpret_cast<SbkObjectType *>(" << enclosingObjectVariable
- << "))->tp_dict, \"" << enumValue->name() << "\", anonEnumItem) < 0)" << endl;
+ << "))->tp_dict, \"" << mangleName(enumValue->name()) << "\", anonEnumItem) < 0)" << endl;
{
Indentation indent(INDENT);
s << INDENT << returnStatement(m_currentErrorCode) << endl;
@@ -4722,7 +4714,7 @@ void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnu
}
s << INDENT << '}' << endl;
} else {
- s << INDENT << "if (PyModule_AddIntConstant(module, \"" << enumValue->name() << "\", ";
+ s << INDENT << "if (PyModule_AddIntConstant(module, \"" << mangleName(enumValue->name()) << "\", ";
s << enumValueText << ") < 0)" << endl;
{
Indentation indent(INDENT);
@@ -4735,7 +4727,7 @@ void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnu
s << ((enclosingClass || hasUpperEnclosingClass) ? "createScopedEnumItem" : "createGlobalEnumItem");
s << '(' << enumVarTypeObj << ',' << endl;
Indentation indent(INDENT);
- s << INDENT << enclosingObjectVariable << ", \"" << enumValue->name() << "\", ";
+ s << INDENT << enclosingObjectVariable << ", \"" << mangleName(enumValue->name()) << "\", ";
s << enumValueText << "))" << endl;
s << INDENT << returnStatement(m_currentErrorCode) << endl;
}
@@ -4744,7 +4736,7 @@ void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnu
s << INDENT << "if (!Shiboken::Enum::createScopedEnumItem("
<< enumVarTypeObj << ',' << endl;
Indentation indent(INDENT);
- s << INDENT << enumVarTypeObj<< ", \"" << enumValue->name() << "\", "
+ s << INDENT << enumVarTypeObj<< ", \"" << mangleName(enumValue->name()) << "\", "
<< enumValueText << "))" << endl
<< INDENT << returnStatement(m_currentErrorCode) << endl;
}
@@ -5567,10 +5559,11 @@ bool CppGenerator::finishGeneration()
{
Indentation indentation(INDENT);
s << INDENT << "PyObject *pyType = reinterpret_cast<PyObject *>(" << cppApiVariableName() << "[i]);" << endl;
- s << INDENT << "if (pyType && PyObject_HasAttrString(pyType, \"staticMetaObject\"))"<< endl;
+ s << INDENT << "Shiboken::AutoDecRef attrName(Py_BuildValue(\"s\", \"staticMetaObject\"));" << endl;
+ s << INDENT << "if (pyType && PyObject_HasAttr(pyType, attrName))"<< endl;
{
Indentation indentation(INDENT);
- s << INDENT << "PyObject_SetAttrString(pyType, \"staticMetaObject\", Py_None);" << endl;
+ s << INDENT << "PyObject_SetAttr(pyType, attrName, Py_None);" << endl;
}
}
s << INDENT << "}" << endl;
@@ -6034,7 +6027,7 @@ QString CppGenerator::writeReprFunction(QTextStream &s,
s << INDENT << "str.replace(0, idx, Py_TYPE(self)->tp_name);" << endl;
}
s << INDENT << "str = str.trimmed();" << endl;
- s << INDENT << "PyObject *mod = PyDict_GetItemString(Py_TYPE(self)->tp_dict, \"__module__\");" << endl;
+ s << INDENT << "PyObject *mod = PyDict_GetItem(Py_TYPE(self)->tp_dict, Shiboken::PyMagicName::module());" << endl;
// PYSIDE-595: The introduction of heap types has the side effect that the module name
// is always prepended to the type name. Therefore the strchr check:
s << INDENT << "if (mod && !strchr(str, '.'))" << endl;
diff --git a/sources/shiboken2/generator/shiboken2/headergenerator.cpp b/sources/shiboken2/generator/shiboken2/headergenerator.cpp
index 8a2c56232..e47c37523 100644
--- a/sources/shiboken2/generator/shiboken2/headergenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/headergenerator.cpp
@@ -454,6 +454,11 @@ bool HeaderGenerator::finishGeneration()
// TODO-CONVERTER ------------------------------------------------------------------------------
macrosStream << "// Macros for type check" << endl;
+
+ if (usePySideExtensions()) {
+ typeFunctions << "QT_WARNING_PUSH" << endl;
+ typeFunctions << "QT_WARNING_DISABLE_DEPRECATED" << endl;
+ }
for (const AbstractMetaEnum *cppEnum : qAsConst(globalEnums)) {
if (cppEnum->isAnonymous() || cppEnum->isPrivate())
continue;
@@ -489,6 +494,8 @@ bool HeaderGenerator::finishGeneration()
includes << classType->include();
writeSbkTypeFunction(typeFunctions, metaType);
}
+ if (usePySideExtensions())
+ typeFunctions << "QT_WARNING_POP" << endl;
QString moduleHeaderFileName(outputDirectory()
+ QDir::separator() + subDirectoryForPackage(packageName())
diff --git a/sources/shiboken2/generator/shiboken2/overloaddata.cpp b/sources/shiboken2/generator/shiboken2/overloaddata.cpp
index 5c3d7d0b8..5f74ee64d 100644
--- a/sources/shiboken2/generator/shiboken2/overloaddata.cpp
+++ b/sources/shiboken2/generator/shiboken2/overloaddata.cpp
@@ -520,7 +520,7 @@ void OverloadData::addOverload(const AbstractMetaFunction *func)
for (int i = 0; m_headOverloadData->m_minArgs > 0 && i < origNumArgs; i++) {
if (func->argumentRemoved(i + 1))
continue;
- if (!ShibokenGenerator::getDefaultValue(func, func->arguments().at(i)).isEmpty()) {
+ if (func->arguments().at(i)->hasDefaultValueExpression()) {
int fixedArgIndex = i - removed;
if (fixedArgIndex < m_headOverloadData->m_minArgs)
m_headOverloadData->m_minArgs = fixedArgIndex;
@@ -576,7 +576,7 @@ QStringList OverloadData::returnTypes() const
else
retTypes << QLatin1String("void");
}
- return QStringList(retTypes.toList());
+ return retTypes.values();
}
bool OverloadData::hasNonVoidReturnType() const
@@ -754,7 +754,7 @@ const AbstractMetaFunction *OverloadData::getFunctionWithDefaultValue() const
if (func->argumentRemoved(i + 1))
removedArgs++;
}
- if (!ShibokenGenerator::getDefaultValue(func, func->arguments().at(m_argPos + removedArgs)).isEmpty())
+ if (func->arguments().at(m_argPos + removedArgs)->hasDefaultValueExpression())
return func;
}
return nullptr;
@@ -771,7 +771,7 @@ QVector<int> OverloadData::invalidArgumentLengths() const
if (func->argumentRemoved(i+1)) {
offset++;
} else {
- if (!ShibokenGenerator::getDefaultValue(func, args[i]).isEmpty())
+ if (args.at(i)->hasDefaultValueExpression())
validArgLengths << i-offset;
}
}
@@ -820,7 +820,7 @@ QPair<int, int> OverloadData::getMinMaxArguments(const AbstractMetaFunctionList
if (func->argumentRemoved(j + 1))
continue;
int fixedArgIndex = j - removed;
- if (fixedArgIndex < minArgs && !ShibokenGenerator::getDefaultValue(func, func->arguments().at(j)).isEmpty())
+ if (fixedArgIndex < minArgs && func->arguments().at(j)->hasDefaultValueExpression())
minArgs = fixedArgIndex;
}
}
@@ -967,7 +967,7 @@ QString OverloadData::dumpGraph() const
const AbstractMetaArgument *arg = argument(func);
if (!arg)
continue;
- QString argDefault = ShibokenGenerator::getDefaultValue(func, arg);
+ QString argDefault = arg->defaultValueExpression();
if (!argDefault.isEmpty() ||
argDefault != arg->originalDefaultValueExpression()) {
s << "<tr><td bgcolor=\"gray\" align=\"right\">f" << functionNumber(func);
@@ -1038,7 +1038,7 @@ bool OverloadData::hasArgumentWithDefaultValue(const AbstractMetaFunction *func)
for (const AbstractMetaArgument *arg : arguments) {
if (func->argumentRemoved(arg->argumentIndex() + 1))
continue;
- if (!ShibokenGenerator::getDefaultValue(func, arg).isEmpty())
+ if (arg->hasDefaultValueExpression())
return true;
}
return false;
@@ -1049,7 +1049,7 @@ AbstractMetaArgumentList OverloadData::getArgumentsWithDefaultValues(const Abstr
AbstractMetaArgumentList args;
const AbstractMetaArgumentList &arguments = func->arguments();
for (AbstractMetaArgument *arg : arguments) {
- if (ShibokenGenerator::getDefaultValue(func, arg).isEmpty()
+ if (!arg->hasDefaultValueExpression()
|| func->argumentRemoved(arg->argumentIndex() + 1))
continue;
args << arg;
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
index 2a8eefba6..fd75c620e 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
@@ -324,18 +324,16 @@ bool ShibokenGenerator::shouldGenerateCppWrapper(const AbstractMetaClass *metaCl
void ShibokenGenerator::lookForEnumsInClassesNotToBeGenerated(AbstractMetaEnumList &enumList, const AbstractMetaClass *metaClass)
{
- if (!metaClass)
- return;
-
+ Q_ASSERT(metaClass);
+ // if a scope is not to be generated, collect its enums into the parent scope
if (metaClass->typeEntry()->codeGeneration() == TypeEntry::GenerateForSubclass) {
const AbstractMetaEnumList &enums = metaClass->enums();
- for (const AbstractMetaEnum *metaEnum : enums) {
- if (metaEnum->isPrivate() || metaEnum->typeEntry()->codeGeneration() == TypeEntry::GenerateForSubclass)
- continue;
- if (!enumList.contains(const_cast<AbstractMetaEnum *>(metaEnum)))
- enumList.append(const_cast<AbstractMetaEnum *>(metaEnum));
+ for (AbstractMetaEnum *metaEnum : enums) {
+ if (!metaEnum->isPrivate() && metaEnum->typeEntry()->generateCode()
+ && !enumList.contains(metaEnum)) {
+ enumList.append(metaEnum);
+ }
}
- lookForEnumsInClassesNotToBeGenerated(enumList, metaClass->enclosingClass());
}
}
@@ -571,7 +569,7 @@ QString ShibokenGenerator::guessScopeForDefaultFlagsValue(const AbstractMetaFunc
QString ShibokenGenerator::guessScopeForDefaultValue(const AbstractMetaFunction *func,
const AbstractMetaArgument *arg) const
{
- QString value = getDefaultValue(func, arg);
+ QString value = arg->defaultValueExpression();
if (value.isEmpty()
|| arg->hasModifiedDefaultValueExpression()
@@ -1255,6 +1253,11 @@ QString ShibokenGenerator::cpythonCheckFunction(const TypeEntry *type, bool gene
QString ShibokenGenerator::guessCPythonCheckFunction(const QString &type, AbstractMetaType **metaType)
{
*metaType = nullptr;
+ // PYSIDE-795: We abuse PySequence for iterables.
+ // This part handles the overrides in the XML files.
+ if (type == QLatin1String("PySequence"))
+ return QLatin1String("Shiboken::String::checkIterable");
+
if (type == QLatin1String("PyTypeObject"))
return QLatin1String("PyType_Check");
@@ -2306,7 +2309,7 @@ AbstractMetaType *ShibokenGenerator::buildAbstractMetaTypeFromString(QString typ
auto it = m_metaTypeFromStringCache.find(typeSignature);
if (it == m_metaTypeFromStringCache.end()) {
AbstractMetaType *metaType =
- AbstractMetaBuilder::translateType(typeSignature, nullptr, true, errorMessage);
+ AbstractMetaBuilder::translateType(typeSignature, nullptr, {}, errorMessage);
if (Q_UNLIKELY(!metaType)) {
if (errorMessage)
errorMessage->prepend(msgCannotBuildMetaType(typeSignature));
@@ -2708,22 +2711,6 @@ bool ShibokenGenerator::pythonFunctionWrapperUsesListOfArguments(const OverloadD
|| overloadData.hasArgumentWithDefaultValue();
}
-QString ShibokenGenerator::getDefaultValue(const AbstractMetaFunction *func, const AbstractMetaArgument *arg)
-{
- if (!arg->defaultValueExpression().isEmpty())
- return arg->defaultValueExpression();
-
- //Check modifications
- const FunctionModificationList &mods = func->modifications();
- for (const FunctionModification &m : mods) {
- for (const ArgumentModification &am : m.argument_mods) {
- if (am.index == (arg->argumentIndex() + 1))
- return am.replacedDefaultExpression;
- }
- }
- return QString();
-}
-
void ShibokenGenerator::writeMinimalConstructorExpression(QTextStream &s, const AbstractMetaType *type, const QString &defaultCtor)
{
if (!defaultCtor.isEmpty()) {
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.h b/sources/shiboken2/generator/shiboken2/shibokengenerator.h
index 84b3137b8..7970ceb94 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.h
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.h
@@ -71,11 +71,6 @@ public:
const char *name() const override { return "Shiboken"; }
- /**
- * Helper function to find for argument default value
- */
- static QString getDefaultValue(const AbstractMetaFunction *func, const AbstractMetaArgument *arg);
-
/// Returns a list of all ancestor classes for the given class.
AbstractMetaClassList getAllAncestors(const AbstractMetaClass *metaClass) const;
diff --git a/sources/shiboken2/libshiboken/CMakeLists.txt b/sources/shiboken2/libshiboken/CMakeLists.txt
index 7cbb22978..a38da8d89 100644
--- a/sources/shiboken2/libshiboken/CMakeLists.txt
+++ b/sources/shiboken2/libshiboken/CMakeLists.txt
@@ -30,8 +30,8 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/embed/signature_bootstrap.py"
"${CMAKE_CURRENT_BINARY_DIR}/embed/signature_bootstrap.py" @ONLY)
add_custom_command(
- OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/embed/signature_bootstrap.inc"
- OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/embed/signature.inc"
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/embed/signature_bootstrap_inc.h"
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/embed/signature_inc.h"
COMMAND ${PYTHON_EXECUTABLE} -E
"${CMAKE_CURRENT_SOURCE_DIR}/embed/embedding_generator.py"
--cmake-dir "${CMAKE_CURRENT_BINARY_DIR}/embed"
@@ -53,6 +53,7 @@ sbkconverter.cpp
sbkenum.cpp
sbkmodule.cpp
sbkstring.cpp
+sbkstaticstrings.cpp
bindingmanager.cpp
threadstatesaver.cpp
shibokenbuffer.cpp
@@ -62,8 +63,8 @@ pep384impl.cpp
voidptr.cpp
typespec.cpp
bufferprocs_py37.cpp
-embed/signature_bootstrap.inc
-embed/signature.inc
+embed/signature_bootstrap_inc.h
+embed/signature_inc.h
)
get_numpy_location()
@@ -129,6 +130,7 @@ install(FILES
python25compat.h
sbkdbg.h
sbkstring.h
+ sbkstaticstrings.h
shiboken.h
shibokenmacros.h
threadstatesaver.h
diff --git a/sources/shiboken2/libshiboken/basewrapper.cpp b/sources/shiboken2/libshiboken/basewrapper.cpp
index 9d233b847..000035627 100644
--- a/sources/shiboken2/libshiboken/basewrapper.cpp
+++ b/sources/shiboken2/libshiboken/basewrapper.cpp
@@ -44,6 +44,7 @@
#include "sbkconverter.h"
#include "sbkenum.h"
#include "sbkstring.h"
+#include "sbkstaticstrings_p.h"
#include "autodecref.h"
#include "gilstate.h"
#include <string>
@@ -160,11 +161,10 @@ patch_tp_new_wrapper(PyTypeObject *type)
* The old tp_new_wrapper is added to all types that have tp_new.
* We patch that with a version that ignores the heaptype flag.
*/
- static PyObject *__new__ = nullptr;
+ auto newMethod = Shiboken::PyMagicName::new_();
if (old_tp_new_wrapper == nullptr) {
- if ((__new__ = Py_BuildValue("s", "__new__")) == nullptr)
- return -1;
- PyObject *func = PyDict_GetItem(PyType_Type.tp_dict, __new__);
+ PyObject *func = PyDict_GetItem(PyType_Type.tp_dict, newMethod);
+ assert(func);
PyCFunctionObject *pycf_ob = reinterpret_cast<PyCFunctionObject *>(func);
old_tp_new_wrapper = reinterpret_cast<ternaryfunc>(pycf_ob->m_ml->ml_meth);
}
@@ -172,7 +172,7 @@ patch_tp_new_wrapper(PyTypeObject *type)
Py_ssize_t i, n = PyTuple_GET_SIZE(mro);
for (i = 0; i < n; i++) {
type = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(mro, i));
- PyObject *existing = PyDict_GetItem(type->tp_dict, __new__);
+ PyObject *existing = PyDict_GetItem(type->tp_dict, newMethod);
if (existing && PyCFunction_Check(existing)
&& type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
auto *pycf_ob = reinterpret_cast<PyCFunctionObject *>(existing);
@@ -182,7 +182,7 @@ patch_tp_new_wrapper(PyTypeObject *type)
if (existing_wrapper == old_tp_new_wrapper) {
PyObject *ob_type = reinterpret_cast<PyObject *>(type);
Shiboken::AutoDecRef func(PyCFunction_New(tp_new_methoddef, ob_type));
- if (func.isNull() || PyDict_SetItem(type->tp_dict, __new__, func))
+ if (func.isNull() || PyDict_SetItem(type->tp_dict, newMethod, func))
return -1;
}
}
diff --git a/sources/shiboken2/libshiboken/embed/embedding_generator.py b/sources/shiboken2/libshiboken/embed/embedding_generator.py
index 77aa5c329..15f63649b 100644
--- a/sources/shiboken2/libshiboken/embed/embedding_generator.py
+++ b/sources/shiboken2/libshiboken/embed/embedding_generator.py
@@ -88,7 +88,7 @@ def create_zipfile(limited_api):
and make a chunked base64 encoded file from it.
"""
zip_name = "signature.zip"
- inc_name = "signature.inc"
+ inc_name = "signature_inc.h"
flag = '-b' if sys.version_info >= (3,) else ''
os.chdir(work_dir)
@@ -131,7 +131,7 @@ def create_zipfile(limited_api):
tmp.close()
# also generate a simple embeddable .pyc file for signature_bootstrap.pyc
boot_name = "signature_bootstrap.py" if limited_api else "signature_bootstrap.pyc"
- with open(boot_name, "rb") as ldr, open("signature_bootstrap.inc", "w") as inc:
+ with open(boot_name, "rb") as ldr, open("signature_bootstrap_inc.h", "w") as inc:
_embed_bytefile(ldr, inc, limited_api)
os.chdir(cur_dir)
diff --git a/sources/shiboken2/libshiboken/helper.cpp b/sources/shiboken2/libshiboken/helper.cpp
index fac72d56f..013080b6e 100644
--- a/sources/shiboken2/libshiboken/helper.cpp
+++ b/sources/shiboken2/libshiboken/helper.cpp
@@ -39,6 +39,7 @@
#include "helper.h"
#include "sbkstring.h"
+#include "sbkstaticstrings.h"
#include <stdarg.h>
#ifdef _WIN32
@@ -78,7 +79,7 @@ bool listToArgcArgv(PyObject *argList, int *argc, char ***argv, const char *defa
if (hasEmptyArgList) {
// Try to get the script name
PyObject *globals = PyEval_GetGlobals();
- PyObject *appName = PyDict_GetItemString(globals, "__file__");
+ PyObject *appName = PyDict_GetItem(globals, Shiboken::PyMagicName::file());
(*argv)[0] = strdup(appName ? Shiboken::String::toCString(appName) : defaultAppName);
} else {
for (int i = 0; i < numArgs; ++i) {
diff --git a/sources/shiboken2/libshiboken/pep384impl.cpp b/sources/shiboken2/libshiboken/pep384impl.cpp
index fe7157d24..5729100bf 100644
--- a/sources/shiboken2/libshiboken/pep384impl.cpp
+++ b/sources/shiboken2/libshiboken/pep384impl.cpp
@@ -39,6 +39,8 @@
#include "pep384impl.h"
#include "autodecref.h"
+#include "sbkstaticstrings.h"
+#include "sbkstaticstrings_p.h"
extern "C"
{
@@ -85,14 +87,15 @@ static PyGetSetDef probe_getseters[] = {
#define probe_tp_str make_dummy(2)
#define probe_tp_traverse make_dummy(3)
#define probe_tp_clear make_dummy(4)
+#define probe_tp_iternext make_dummy(5)
#define probe_tp_methods probe_methoddef
#define probe_tp_getset probe_getseters
-#define probe_tp_descr_get make_dummy(7)
-#define probe_tp_init make_dummy(8)
-#define probe_tp_alloc make_dummy(9)
-#define probe_tp_new make_dummy(10)
-#define probe_tp_free make_dummy(11)
-#define probe_tp_is_gc make_dummy(12)
+#define probe_tp_descr_get make_dummy(8)
+#define probe_tp_init make_dummy(9)
+#define probe_tp_alloc make_dummy(10)
+#define probe_tp_new make_dummy(11)
+#define probe_tp_free make_dummy(12)
+#define probe_tp_is_gc make_dummy(13)
#define probe_tp_name "type.probe"
#define probe_tp_basicsize make_dummy_int(42)
@@ -102,6 +105,7 @@ static PyType_Slot typeprobe_slots[] = {
{Py_tp_str, probe_tp_str},
{Py_tp_traverse, probe_tp_traverse},
{Py_tp_clear, probe_tp_clear},
+ {Py_tp_iternext, probe_tp_iternext},
{Py_tp_methods, probe_tp_methods},
{Py_tp_getset, probe_tp_getset},
{Py_tp_descr_get, probe_tp_descr_get},
@@ -125,16 +129,16 @@ check_PyTypeObject_valid()
{
auto *obtype = reinterpret_cast<PyObject *>(&PyType_Type);
auto *probe_tp_base = reinterpret_cast<PyTypeObject *>(
- PyObject_GetAttrString(obtype, "__base__"));
- PyObject *probe_tp_bases = PyObject_GetAttrString(obtype, "__bases__");
+ PyObject_GetAttr(obtype, Shiboken::PyMagicName::base()));
+ auto *probe_tp_bases = PyObject_GetAttr(obtype, Shiboken::PyMagicName::bases());
auto *check = reinterpret_cast<PyTypeObject *>(
PyType_FromSpecWithBases(&typeprobe_spec, probe_tp_bases));
auto *typetype = reinterpret_cast<PyTypeObject *>(obtype);
- PyObject *w = PyObject_GetAttrString(obtype, "__weakrefoffset__");
+ PyObject *w = PyObject_GetAttr(obtype, Shiboken::PyMagicName::weakrefoffset());
long probe_tp_weakrefoffset = PyLong_AsLong(w);
- PyObject *d = PyObject_GetAttrString(obtype, "__dictoffset__");
+ PyObject *d = PyObject_GetAttr(obtype, Shiboken::PyMagicName::dictoffset());
long probe_tp_dictoffset = PyLong_AsLong(d);
- PyObject *probe_tp_mro = PyObject_GetAttrString(obtype, "__mro__");
+ PyObject *probe_tp_mro = PyObject_GetAttr(obtype, Shiboken::PyMagicName::mro());
if (false
|| strcmp(probe_tp_name, check->tp_name) != 0
|| probe_tp_basicsize != check->tp_basicsize
@@ -143,6 +147,7 @@ check_PyTypeObject_valid()
|| probe_tp_traverse != check->tp_traverse
|| probe_tp_clear != check->tp_clear
|| probe_tp_weakrefoffset != typetype->tp_weaklistoffset
+ || probe_tp_iternext != check->tp_iternext
|| probe_tp_methods != check->tp_methods
|| probe_tp_getset != check->tp_getset
|| probe_tp_base != typetype->tp_base
@@ -416,9 +421,10 @@ PepRun_GetResult(const char *command, const char *resvar)
PyObject *d, *v, *res;
d = PyDict_New();
- if (d == NULL || PyDict_SetItemString(d, "__builtins__",
- PyEval_GetBuiltins()) < 0)
- return NULL;
+ if (d == nullptr
+ || PyDict_SetItem(d, Shiboken::PyMagicName::builtins(), PyEval_GetBuiltins()) < 0) {
+ return nullptr;
+ }
v = PyRun_String(command, Py_file_input, d, d);
res = v ? PyDict_GetItemString(d, resvar) : NULL;
Py_XDECREF(v);
@@ -457,7 +463,7 @@ PyMethod_New(PyObject *func, PyObject *self)
PyObject *
PyMethod_Function(PyObject *im)
{
- PyObject *ret = PyObject_GetAttrString(im, "__func__");
+ PyObject *ret = PyObject_GetAttr(im, Shiboken::PyMagicName::func());
// We have to return a borrowed reference.
Py_DECREF(ret);
@@ -467,7 +473,7 @@ PyMethod_Function(PyObject *im)
PyObject *
PyMethod_Self(PyObject *im)
{
- PyObject *ret = PyObject_GetAttrString(im, "__self__");
+ PyObject *ret = PyObject_GetAttr(im, Shiboken::PyMagicName::self());
// We have to return a borrowed reference.
// If we don't obey that here, then we get a test error!
@@ -620,8 +626,8 @@ _Pep_PrivateMangle(PyObject *self, PyObject *name)
return name;
}
#endif
- Shiboken::AutoDecRef privateobj(PyObject_GetAttrString(
- reinterpret_cast<PyObject *>(Py_TYPE(self)), "__name__"));
+ Shiboken::AutoDecRef privateobj(PyObject_GetAttr(
+ reinterpret_cast<PyObject *>(Py_TYPE(self)), Shiboken::PyMagicName::name()));
#ifndef Py_LIMITED_API
return _Py_Mangle(privateobj, name);
#else
diff --git a/sources/shiboken2/libshiboken/pep384impl.h b/sources/shiboken2/libshiboken/pep384impl.h
index 93f718988..1aa7e6fc0 100644
--- a/sources/shiboken2/libshiboken/pep384impl.h
+++ b/sources/shiboken2/libshiboken/pep384impl.h
@@ -110,7 +110,7 @@ typedef struct _typeobject {
void *X23; // richcmpfunc tp_richcompare;
Py_ssize_t tp_weaklistoffset;
void *X25; // getiterfunc tp_iter;
- void *X26; // iternextfunc tp_iternext;
+ iternextfunc tp_iternext;
struct PyMethodDef *tp_methods;
void *X28; // struct PyMemberDef *tp_members;
struct PyGetSetDef *tp_getset;
diff --git a/sources/shiboken2/libshiboken/sbkenum.cpp b/sources/shiboken2/libshiboken/sbkenum.cpp
index 2dc785884..71fcf5f64 100644
--- a/sources/shiboken2/libshiboken/sbkenum.cpp
+++ b/sources/shiboken2/libshiboken/sbkenum.cpp
@@ -412,13 +412,6 @@ PyTypeObject *createScopedEnum(SbkObjectType *scope, const char *name, const cha
static PyObject *createEnumItem(PyTypeObject *enumType, const char *itemName, long itemValue)
{
- char mangled[20];
- if (strcmp(itemName, "None") == 0
- || strcmp(itemName, "False") == 0 || strcmp(itemName, "True") == 0) {
- strcpy(mangled, itemName);
- strcat(mangled, "_");
- itemName = mangled;
- }
PyObject *enumItem = newItem(enumType, itemValue, itemName);
if (PyDict_SetItemString(enumType->tp_dict, itemName, enumItem) < 0)
return nullptr;
diff --git a/sources/shiboken2/libshiboken/sbkstaticstrings.cpp b/sources/shiboken2/libshiboken/sbkstaticstrings.cpp
new file mode 100644
index 000000000..3727eb494
--- /dev/null
+++ b/sources/shiboken2/libshiboken/sbkstaticstrings.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** 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-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "sbkstaticstrings.h"
+#include "sbkstaticstrings_p.h"
+#include "sbkstring.h"
+
+#define STATIC_STRING_IMPL(funcName, value) \
+PyObject *funcName() \
+{ \
+ static PyObject *const s = Shiboken::String::createStaticString(value); \
+ return s; \
+}
+
+namespace Shiboken
+{
+namespace PyName {
+// exported:
+STATIC_STRING_IMPL(dumps, "dumps")
+STATIC_STRING_IMPL(loads, "loads")
+
+// Internal:
+STATIC_STRING_IMPL(classmethod, "classmethod")
+STATIC_STRING_IMPL(compile, "compile");
+STATIC_STRING_IMPL(function, "function")
+STATIC_STRING_IMPL(marshal, "marshal")
+STATIC_STRING_IMPL(method, "method")
+STATIC_STRING_IMPL(overload, "overload")
+STATIC_STRING_IMPL(staticmethod, "staticmethod")
+} // namespace PyName
+
+namespace PyMagicName {
+// exported:
+STATIC_STRING_IMPL(class_, "__class__")
+STATIC_STRING_IMPL(ecf, "__ecf__")
+STATIC_STRING_IMPL(file, "__file__")
+STATIC_STRING_IMPL(module, "__module__")
+STATIC_STRING_IMPL(name, "__name__")
+
+// Internal:
+STATIC_STRING_IMPL(base, "__base__")
+STATIC_STRING_IMPL(bases, "__bases__")
+STATIC_STRING_IMPL(builtins, "__builtins__")
+STATIC_STRING_IMPL(code, "__code__")
+STATIC_STRING_IMPL(dictoffset, "__dictoffset__")
+STATIC_STRING_IMPL(func, "__func__")
+STATIC_STRING_IMPL(func_kind, "__func_kind__")
+STATIC_STRING_IMPL(iter, "__iter__")
+STATIC_STRING_IMPL(mro, "__mro__")
+STATIC_STRING_IMPL(new_, "__new__")
+STATIC_STRING_IMPL(objclass, "__objclass__")
+STATIC_STRING_IMPL(self, "__self__")
+STATIC_STRING_IMPL(signature, "__signature__")
+STATIC_STRING_IMPL(weakrefoffset, "__weakrefoffset__")
+} // namespace PyMagicName
+} // namespace Shiboken
diff --git a/sources/shiboken2/libshiboken/sbkstaticstrings.h b/sources/shiboken2/libshiboken/sbkstaticstrings.h
new file mode 100644
index 000000000..fa21a8e2c
--- /dev/null
+++ b/sources/shiboken2/libshiboken/sbkstaticstrings.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** 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-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SBKSTATICSTRINGS_H
+#define SBKSTATICSTRINGS_H
+
+#include "sbkpython.h"
+#include "shibokenmacros.h"
+
+namespace Shiboken
+{
+// Some often-used strings
+namespace PyName
+{
+LIBSHIBOKEN_API PyObject *dumps();
+LIBSHIBOKEN_API PyObject *loads();
+} // namespace PyName
+
+namespace PyMagicName
+{
+LIBSHIBOKEN_API PyObject *class_();
+LIBSHIBOKEN_API PyObject *ecf();
+LIBSHIBOKEN_API PyObject *file();
+LIBSHIBOKEN_API PyObject *module();
+LIBSHIBOKEN_API PyObject *name();
+} // namespace PyMagicName
+} // namespace Shiboken
+
+#endif // SBKSTATICSTRINGS_H
diff --git a/sources/shiboken2/libshiboken/sbkstaticstrings_p.h b/sources/shiboken2/libshiboken/sbkstaticstrings_p.h
new file mode 100644
index 000000000..42c5585fa
--- /dev/null
+++ b/sources/shiboken2/libshiboken/sbkstaticstrings_p.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** 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-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "sbkpython.h"
+#include "shibokenmacros.h"
+
+namespace Shiboken
+{
+namespace PyName
+{
+PyObject *classmethod();
+PyObject *compile();
+PyObject *function();
+PyObject *marshal();
+PyObject *method();
+PyObject *overload();
+PyObject *staticmethod();
+} // namespace PyName
+namespace PyMagicName
+{
+PyObject *base();
+PyObject *bases();
+PyObject *builtins();
+PyObject *code();
+PyObject *dictoffset();
+PyObject *func();
+PyObject *func_kind();
+PyObject *iter();
+PyObject *module();
+PyObject *mro();
+PyObject *new_();
+PyObject *objclass();
+PyObject *self();
+PyObject *signature();
+PyObject *weakrefoffset();
+} // namespace PyMagicName
+} // namespace Shiboken
diff --git a/sources/shiboken2/libshiboken/sbkstring.cpp b/sources/shiboken2/libshiboken/sbkstring.cpp
index 9ba5be281..4a441222f 100644
--- a/sources/shiboken2/libshiboken/sbkstring.cpp
+++ b/sources/shiboken2/libshiboken/sbkstring.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -38,14 +38,23 @@
****************************************************************************/
#include "sbkstring.h"
+#include "sbkstaticstrings_p.h"
#include "autodecref.h"
+#include <vector>
+
namespace Shiboken
{
namespace String
{
+// PYSIDE-795: Redirecting PySequence to Iterable
+bool checkIterable(PyObject *obj)
+{
+ return PyObject_HasAttr(obj, Shiboken::PyMagicName::iter());
+}
+
bool checkType(PyTypeObject *type)
{
return type == &PyUnicode_Type
@@ -200,6 +209,64 @@ Py_ssize_t len(PyObject *str)
return 0;
}
-} // namespace String
+///////////////////////////////////////////////////////////////////////
+//
+// Implementation of efficient Python strings
+// ------------------------------------------
+//
+// Instead of repetitively executing
+//
+// PyObject *attr = PyObject_GetAttrString(obj, "__name__");
+//
+// a helper of the form
+//
+// PyObject *name()
+// {
+// static PyObject *const s = Shiboken::String::createStaticString("__name__");
+// return result;
+// }
+//
+// can now be implemented, which registers the string into a static set avoiding
+// repetitive string creation. The resulting code looks like:
+//
+// PyObject *attr = PyObject_GetAttr(obj, name());
+//
+// Missing:
+// There is no finalization for the string structures, yet.
+// But this is a global fault in shiboken. We are missing a true
+// finalization like in all other modules.
+
+using StaticStrings = std::vector<PyObject *>;
+static StaticStrings &staticStrings()
+{
+ static StaticStrings result;
+ return result;
+}
+
+PyObject *createStaticString(const char *str)
+{
+#if PY_VERSION_HEX >= 0x03000000
+ PyObject *result = PyUnicode_InternFromString(str);
+#else
+ PyObject *result = PyString_InternFromString(str);
+#endif
+ if (result == nullptr) {
+ // This error is never checked, but also very unlikely. Report and exit.
+ PyErr_Print();
+ Py_FatalError("unexpected error in createStaticString()");
+ }
+ staticStrings().push_back(result);
+ return result;
+}
+
+void finalizeStaticStrings() // Currently unused
+{
+ auto &list = staticStrings();
+ for (auto s : list)
+ Py_DECREF(s);
+ list.clear();
+}
+
+} // namespace String
} // namespace Shiboken
diff --git a/sources/shiboken2/libshiboken/sbkstring.h b/sources/shiboken2/libshiboken/sbkstring.h
index 7f434e1b9..84d7768c5 100644
--- a/sources/shiboken2/libshiboken/sbkstring.h
+++ b/sources/shiboken2/libshiboken/sbkstring.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -43,17 +43,12 @@
#include "sbkpython.h"
#include "shibokenmacros.h"
-#if PY_MAJOR_VERSION >= 3
- #define SBK_BYTES_NAME "bytes"
-#else
- #define SBK_BYTES_NAME "str"
-#endif
-
namespace Shiboken
{
namespace String
{
LIBSHIBOKEN_API bool check(PyObject *obj);
+ LIBSHIBOKEN_API bool checkIterable(PyObject *obj);
LIBSHIBOKEN_API bool checkType(PyTypeObject *obj);
LIBSHIBOKEN_API bool checkChar(PyObject *obj);
LIBSHIBOKEN_API bool isConvertible(PyObject *obj);
@@ -65,6 +60,7 @@ namespace String
LIBSHIBOKEN_API PyObject *fromStringAndSize(const char *str, Py_ssize_t size);
LIBSHIBOKEN_API int compare(PyObject *val1, const char *val2);
LIBSHIBOKEN_API Py_ssize_t len(PyObject *str);
+ LIBSHIBOKEN_API PyObject *createStaticString(const char *str);
} // namespace String
} // namespace Shiboken
diff --git a/sources/shiboken2/libshiboken/shiboken.h b/sources/shiboken2/libshiboken/shiboken.h
index 1356670aa..0d2d6b0a6 100644
--- a/sources/shiboken2/libshiboken/shiboken.h
+++ b/sources/shiboken2/libshiboken/shiboken.h
@@ -52,6 +52,7 @@
#include "sbkenum.h"
#include "sbkmodule.h"
#include "sbkstring.h"
+#include "sbkstaticstrings.h"
#include "shibokenmacros.h"
#include "shibokenbuffer.h"
diff --git a/sources/shiboken2/libshiboken/signature.cpp b/sources/shiboken2/libshiboken/signature.cpp
index 0afdbcdc9..5430ab064 100644
--- a/sources/shiboken2/libshiboken/signature.cpp
+++ b/sources/shiboken2/libshiboken/signature.cpp
@@ -39,6 +39,8 @@
#include "basewrapper.h"
#include "autodecref.h"
+#include "sbkstaticstrings.h"
+#include "sbkstaticstrings_p.h"
extern "C"
{
@@ -51,11 +53,11 @@ extern "C"
// These constants were needed in former versions of the module:
#define PYTHON_HAS_QUALNAME (PY_VERSION_HEX >= 0x03030000)
-#define PYTHON_HAS_UNICODE (PY_VERSION_HEX >= 0x03000000)
#define PYTHON_HAS_WEAKREF_PYCFUNCTION (PY_VERSION_HEX >= 0x030500A0)
#define PYTHON_IS_PYTHON3 (PY_VERSION_HEX >= 0x03000000)
#define PYTHON_HAS_KEYWORDONLY (PYTHON_IS_PYTHON3)
#define PYTHON_USES_PERCENT_V_FORMAT (PYTHON_IS_PYTHON3)
+#define PYTHON_USES_D_COMMON (PY_VERSION_HEX >= 0x03020000)
#define PYTHON_HAS_DESCR_REDUCE (PY_VERSION_HEX >= 0x03040000)
#define PYTHON_HAS_METH_REDUCE (PYTHON_HAS_DESCR_REDUCE)
#define PYTHON_NEEDS_ITERATOR_FLAG (!PYTHON_IS_PYTHON3)
@@ -64,7 +66,7 @@ extern "C"
#define PYTHON_HAS_INT_AND_LONG (!PYTHON_IS_PYTHON3)
// These constants are still in use:
-#define PYTHON_USES_D_COMMON (PY_VERSION_HEX >= 0x03020000)
+#define PYTHON_USES_UNICODE (PY_VERSION_HEX >= 0x03000000)
typedef struct safe_globals_struc {
// init part 1: get arg_dict
@@ -77,17 +79,18 @@ typedef struct safe_globals_struc {
PyObject *create_signature_func;
PyObject *seterror_argument_func;
PyObject *make_helptext_func;
+ PyObject *finish_import_func;
} safe_globals_struc, *safe_globals;
static safe_globals pyside_globals = nullptr;
static PyObject *GetTypeKey(PyObject *ob);
-static PyObject *GetSignature_Function(PyObject *, const char *);
-static PyObject *GetSignature_TypeMod(PyObject *, const char *);
-static PyObject *GetSignature_Wrapper(PyObject *, const char *);
+static PyObject *GetSignature_Function(PyObject *, PyObject *);
+static PyObject *GetSignature_TypeMod(PyObject *, PyObject *);
+static PyObject *GetSignature_Wrapper(PyObject *, PyObject *);
static PyObject *get_signature(PyObject *self, PyObject *args);
-static PyObject *get_signature_intern(PyObject *ob, const char *modifier);
+static PyObject *get_signature_intern(PyObject *ob, PyObject *modifier);
static PyObject *PySide_BuildSignatureProps(PyObject *class_mod);
@@ -107,10 +110,10 @@ CreateSignature(PyObject *props, PyObject *key)
const_cast<char *>("(OO)"), props, key);
}
-typedef PyObject *(*signaturefunc)(PyObject *, const char *);
+typedef PyObject *(*signaturefunc)(PyObject *, PyObject *);
static PyObject *
-_get_written_signature(signaturefunc sf, PyObject *ob, const char *modifier)
+_get_written_signature(signaturefunc sf, PyObject *ob, PyObject *modifier)
{
/*
* Be a writable Attribute, but have a computed value.
@@ -133,19 +136,19 @@ _get_written_signature(signaturefunc sf, PyObject *ob, const char *modifier)
}
static PyObject *
-pyside_cf_get___signature__(PyObject *func, const char *modifier)
+pyside_cf_get___signature__(PyObject *func, PyObject *modifier)
{
init_module_2();
return _get_written_signature(GetSignature_Function, func, modifier);
}
static PyObject *
-pyside_sm_get___signature__(PyObject *sm, const char *modifier)
+pyside_sm_get___signature__(PyObject *sm, PyObject *modifier)
{
init_module_2();
- Shiboken::AutoDecRef func(PyObject_GetAttrString(sm, "__func__"));
+ Shiboken::AutoDecRef func(PyObject_GetAttr(sm, Shiboken::PyMagicName::func()));
if (Py_TYPE(func) == PepFunction_TypePtr)
- return PyObject_GetAttrString(func, "__signature__");
+ return PyObject_GetAttr(func, Shiboken::PyMagicName::signature());
return _get_written_signature(GetSignature_Function, func, modifier);
}
@@ -157,7 +160,7 @@ _get_class_of_cf(PyObject *ob_cf)
selftype = PyDict_GetItem(pyside_globals->map_dict, ob_cf);
if (selftype == nullptr) {
// This must be an overloaded function that we handled special.
- Shiboken::AutoDecRef special(Py_BuildValue("(Os)", ob_cf, "overload"));
+ Shiboken::AutoDecRef special(Py_BuildValue("(OO)", ob_cf, Shiboken::PyName::overload()));
selftype = PyDict_GetItem(pyside_globals->map_dict, special);
if (selftype == nullptr) {
// This is probably a module function. We will return type(None).
@@ -175,15 +178,15 @@ _get_class_of_cf(PyObject *ob_cf)
static PyObject *
_get_class_of_sm(PyObject *ob_sm)
{
- Shiboken::AutoDecRef func(PyObject_GetAttrString(ob_sm, "__func__"));
+ Shiboken::AutoDecRef func(PyObject_GetAttr(ob_sm, Shiboken::PyMagicName::func()));
return _get_class_of_cf(func);
}
static PyObject *
_get_class_of_descr(PyObject *ob)
{
- Shiboken::AutoDecRef func_name(PyObject_GetAttrString(ob, "__name__"));
- return PyObject_GetAttrString(ob, "__objclass__");
+ Shiboken::AutoDecRef func_name(PyObject_GetAttr(ob, Shiboken::PyMagicName::name()));
+ return PyObject_GetAttr(ob, Shiboken::PyMagicName::objclass());
}
static PyObject *
@@ -215,10 +218,10 @@ get_funcname(PyObject *ob)
{
PyObject *func = ob;
if (Py_TYPE(ob) == PepStaticMethod_TypePtr)
- func = PyObject_GetAttrString(ob, "__func__");
+ func = PyObject_GetAttr(ob, Shiboken::PyMagicName::func());
else
Py_INCREF(func);
- PyObject *func_name = PyObject_GetAttrString(func, "__name__");
+ PyObject *func_name = PyObject_GetAttr(func, Shiboken::PyMagicName::name());
Py_DECREF(func);
if (func_name == nullptr)
Py_FatalError("unexpected name problem in compute_name_key");
@@ -286,7 +289,7 @@ name_key_to_func(PyObject *ob)
}
static PyObject *
-pyside_md_get___signature__(PyObject *ob_md, const char *modifier)
+pyside_md_get___signature__(PyObject *ob_md, PyObject *modifier)
{
init_module_2();
Shiboken::AutoDecRef func(name_key_to_func(ob_md));
@@ -298,14 +301,14 @@ pyside_md_get___signature__(PyObject *ob_md, const char *modifier)
}
static PyObject *
-pyside_wd_get___signature__(PyObject *ob, const char *modifier)
+pyside_wd_get___signature__(PyObject *ob, PyObject *modifier)
{
init_module_2();
return _get_written_signature(GetSignature_Wrapper, ob, modifier);
}
static PyObject *
-pyside_tp_get___signature__(PyObject *obtype_mod, const char *modifier)
+pyside_tp_get___signature__(PyObject *obtype_mod, PyObject *modifier)
{
init_module_2();
return _get_written_signature(GetSignature_TypeMod, obtype_mod, modifier);
@@ -313,7 +316,7 @@ pyside_tp_get___signature__(PyObject *obtype_mod, const char *modifier)
// forward
static PyObject *
-GetSignature_Cached(PyObject *props, const char *func_kind, const char *modifier);
+GetSignature_Cached(PyObject *props, PyObject *func_kind, PyObject *modifier);
static PyObject *
GetTypeKey(PyObject *ob)
@@ -331,8 +334,8 @@ GetTypeKey(PyObject *ob)
*
* This is the PyCFunction behavior, as opposed to Python functions.
*/
- Shiboken::AutoDecRef class_name(PyObject_GetAttrString(ob, "__name__"));
- Shiboken::AutoDecRef module_name(PyObject_GetAttrString(ob, "__module__"));
+ Shiboken::AutoDecRef class_name(PyObject_GetAttr(ob, Shiboken::PyMagicName::name()));
+ Shiboken::AutoDecRef module_name(PyObject_GetAttr(ob, Shiboken::PyMagicName::module()));
if (module_name.isNull())
PyErr_Clear();
@@ -363,7 +366,7 @@ TypeKey_to_PropsDict(PyObject *type_key, PyObject *obtype)
}
static PyObject *
-GetSignature_Function(PyObject *obfunc, const char *modifier)
+GetSignature_Function(PyObject *obfunc, PyObject *modifier)
{
// make sure that we look into PyCFunction, only...
if (Py_TYPE(obfunc) == PepFunction_TypePtr)
@@ -375,29 +378,29 @@ GetSignature_Function(PyObject *obfunc, const char *modifier)
PyObject *dict = TypeKey_to_PropsDict(type_key, obtype_mod);
if (dict == nullptr)
return nullptr;
- Shiboken::AutoDecRef func_name(PyObject_GetAttrString(obfunc, "__name__"));
+ Shiboken::AutoDecRef func_name(PyObject_GetAttr(obfunc, Shiboken::PyMagicName::name()));
PyObject *props = !func_name.isNull() ? PyDict_GetItem(dict, func_name) : nullptr;
if (props == nullptr)
Py_RETURN_NONE;
int flags = PyCFunction_GET_FLAGS(obfunc);
- const char *func_kind;
+ PyObject *func_kind;
if (PyModule_Check(obtype_mod))
- func_kind = "function";
+ func_kind = Shiboken::PyName::function();
else if (flags & METH_CLASS)
- func_kind = "classmethod";
+ func_kind = Shiboken::PyName::classmethod();
else if (flags & METH_STATIC)
- func_kind = "staticmethod";
+ func_kind = Shiboken::PyName::staticmethod();
else
- func_kind = "method";
+ func_kind = Shiboken::PyName::method();
return GetSignature_Cached(props, func_kind, modifier);
}
static PyObject *
-GetSignature_Wrapper(PyObject *ob, const char *modifier)
+GetSignature_Wrapper(PyObject *ob, PyObject *modifier)
{
- Shiboken::AutoDecRef func_name(PyObject_GetAttrString(ob, "__name__"));
- Shiboken::AutoDecRef objclass(PyObject_GetAttrString(ob, "__objclass__"));
+ Shiboken::AutoDecRef func_name(PyObject_GetAttr(ob, Shiboken::PyMagicName::name()));
+ Shiboken::AutoDecRef objclass(PyObject_GetAttr(ob, Shiboken::PyMagicName::objclass()));
Shiboken::AutoDecRef class_key(GetTypeKey(objclass));
if (func_name.isNull() || objclass.isNull() || class_key.isNull())
@@ -408,13 +411,13 @@ GetSignature_Wrapper(PyObject *ob, const char *modifier)
PyObject *props = PyDict_GetItem(dict, func_name);
if (props == nullptr)
Py_RETURN_NONE;
- return GetSignature_Cached(props, "method", modifier);
+ return GetSignature_Cached(props, Shiboken::PyName::method(), modifier);
}
static PyObject *
-GetSignature_TypeMod(PyObject *ob, const char *modifier)
+GetSignature_TypeMod(PyObject *ob, PyObject *modifier)
{
- Shiboken::AutoDecRef ob_name(PyObject_GetAttrString(ob, "__name__"));
+ Shiboken::AutoDecRef ob_name(PyObject_GetAttr(ob, Shiboken::PyMagicName::name()));
Shiboken::AutoDecRef ob_key(GetTypeKey(ob));
PyObject *dict = TypeKey_to_PropsDict(ob_key, ob);
@@ -423,19 +426,26 @@ GetSignature_TypeMod(PyObject *ob, const char *modifier)
PyObject *props = PyDict_GetItem(dict, ob_name);
if (props == nullptr)
Py_RETURN_NONE;
- return GetSignature_Cached(props, "method", modifier);
+ return GetSignature_Cached(props, Shiboken::PyName::method(), modifier);
}
static PyObject *
-GetSignature_Cached(PyObject *props, const char *func_kind, const char *modifier)
+GetSignature_Cached(PyObject *props, PyObject *func_kind, PyObject *modifier)
{
// Special case: We want to know the func_kind.
- if (modifier && strcmp(modifier, "__func_kind__") == 0)
- return Py_BuildValue("s", func_kind);
+ if (modifier) {
+#if PYTHON_USES_UNICODE
+ PyUnicode_InternInPlace(&modifier);
+#else
+ PyString_InternInPlace(&modifier);
+#endif
+ if (modifier == Shiboken::PyMagicName::func_kind())
+ return Py_BuildValue("O", func_kind);
+ }
Shiboken::AutoDecRef key(modifier == nullptr
- ? Py_BuildValue("s", func_kind)
- : Py_BuildValue("(ss)", func_kind, modifier));
+ ? Py_BuildValue("O", func_kind)
+ : Py_BuildValue("(OO)", func_kind, modifier));
PyObject *value = PyDict_GetItem(props, key);
if (value == nullptr) {
// we need to compute a signature object
@@ -454,11 +464,11 @@ GetSignature_Cached(PyObject *props, const char *func_kind, const char *modifier
}
static const char *PySide_CompressedSignaturePackage[] = {
-#include "embed/signature.inc"
+#include "embed/signature_inc.h"
};
static const unsigned char PySide_SignatureLoader[] = {
-#include "embed/signature_bootstrap.inc"
+#include "embed/signature_bootstrap_inc.h"
};
static safe_globals_struc *
@@ -477,13 +487,10 @@ init_phase_1(void)
#ifdef Py_LIMITED_API
// We must work for multiple versions, so use source code.
#else
- Shiboken::AutoDecRef marshal_str(Py_BuildValue("s", "marshal"));
- if (marshal_str.isNull())
- goto error;
- Shiboken::AutoDecRef marshal_module(PyImport_Import(marshal_str));
+ Shiboken::AutoDecRef marshal_module(PyImport_Import(Shiboken::PyName::marshal()));
if (marshal_module.isNull())
goto error;
- Shiboken::AutoDecRef loads(PyObject_GetAttrString(marshal_module, "loads"));
+ Shiboken::AutoDecRef loads(PyObject_GetAttr(marshal_module, Shiboken::PyName::loads()));
if (loads.isNull())
goto error;
#endif
@@ -495,7 +502,7 @@ init_phase_1(void)
goto error;
#ifdef Py_LIMITED_API
PyObject *builtins = PyEval_GetBuiltins();
- PyObject *compile = PyDict_GetItemString(builtins, "compile");
+ PyObject *compile = PyDict_GetItem(builtins, Shiboken::PyName::compile());
if (compile == nullptr)
goto error;
Shiboken::AutoDecRef code_obj(PyObject_CallFunction(compile, "Oss",
@@ -512,7 +519,7 @@ init_phase_1(void)
goto error;
// Initialize the module
PyObject *mdict = PyModule_GetDict(p->helper_module);
- if (PyDict_SetItemString(mdict, "__builtins__", PyEval_GetBuiltins()) < 0)
+ if (PyDict_SetItem(mdict, Shiboken::PyMagicName::builtins(), PyEval_GetBuiltins()) < 0)
goto error;
/*
* Unpack an embedded ZIP file with more signature modules.
@@ -551,11 +558,14 @@ init_phase_1(void)
if (p->value_dict == nullptr)
goto error;
+ // This function will be disabled until phase 2 is done.
+ p->finish_import_func = nullptr;
+
return p;
}
error:
PyErr_Print();
- PyErr_SetString(PyExc_SystemError, "could not initialize part 1");
+ Py_FatalError("could not initialize part 1");
return nullptr;
}
@@ -593,11 +603,14 @@ init_phase_2(safe_globals_struc *p, PyMethodDef *methods)
p->make_helptext_func = PyObject_GetAttrString(loader, "make_helptext");
if (p->make_helptext_func == nullptr)
goto error;
+ p->finish_import_func = PyObject_GetAttrString(loader, "finish_import");
+ if (p->finish_import_func == nullptr)
+ goto error;
return 0;
}
error:
PyErr_Print();
- PyErr_SetString(PyExc_SystemError, "could not initialize part 2");
+ Py_FatalError("could not initialize part 2");
return -1;
}
@@ -795,7 +808,7 @@ static PyGetSetDef new_PyWrapperDescr_getsets[] = {
//
static PyObject *
-get_signature_intern(PyObject *ob, const char *modifier)
+get_signature_intern(PyObject *ob, PyObject *modifier)
{
if (PyType_IsSubtype(Py_TYPE(ob), &PyCFunction_Type))
return pyside_cf_get___signature__(ob, modifier);
@@ -814,11 +827,11 @@ static PyObject *
get_signature(PyObject * /* self */, PyObject *args)
{
PyObject *ob;
- const char *modifier = nullptr;
+ PyObject *modifier = nullptr;
init_module_1();
- if (!PyArg_ParseTuple(args, "O|s", &ob, &modifier))
+ if (!PyArg_ParseTuple(args, "O|O", &ob, &modifier))
return nullptr;
if (Py_TYPE(ob) == PepFunction_TypePtr)
Py_RETURN_NONE;
@@ -1030,7 +1043,16 @@ PySide_FinishSignatures(PyObject *module, const char *signatures[])
return -1;
if (_finish_nested_classes(obdict) < 0)
return -1;
- return 0;
+ // The finish_import function will not work the first time since phase 2
+ // was not yet run. But that is ok, because the first import is always for
+ // the shiboken module (or a test module).
+ if (pyside_globals->finish_import_func == nullptr) {
+ assert(strncmp(name, "PySide2.", 8) != 0);
+ return 0;
+ }
+ Shiboken::AutoDecRef ret(PyObject_CallFunction(
+ pyside_globals->finish_import_func, const_cast<char *>("(O)"), module));
+ return ret.isNull() ? -1 : 0;
}
static int
@@ -1093,13 +1115,14 @@ _build_func_to_type(PyObject *obtype)
* "{name}.overload".
*/
PyObject *descr = PyDict_GetItemString(dict, meth->ml_name);
- const char *look_attr = meth->ml_flags & METH_STATIC ? "__func__" : "__name__";
+ PyObject *look_attr = meth->ml_flags & METH_STATIC
+ ? Shiboken::PyMagicName::func() : Shiboken::PyMagicName::name();
int check_name = meth->ml_flags & METH_STATIC ? 0 : 1;
if (descr == nullptr)
return -1;
// We first check all methods if one is hidden by something else.
- Shiboken::AutoDecRef look(PyObject_GetAttrString(descr, look_attr));
+ Shiboken::AutoDecRef look(PyObject_GetAttr(descr, look_attr));
Shiboken::AutoDecRef given(Py_BuildValue("s", meth->ml_name));
if (look.isNull()
|| (check_name && PyObject_RichCompareBool(look, given, Py_EQ) != 1)) {
@@ -1206,7 +1229,7 @@ SetError_Argument(PyObject *args, const char *func_name)
*/
PyObject *
-Sbk_TypeGet___signature__(PyObject *ob, const char *modifier)
+Sbk_TypeGet___signature__(PyObject *ob, PyObject *modifier)
{
return pyside_tp_get___signature__(ob, modifier);
}
diff --git a/sources/shiboken2/libshiboken/signature.h b/sources/shiboken2/libshiboken/signature.h
index 57fd4047a..b22a78497 100644
--- a/sources/shiboken2/libshiboken/signature.h
+++ b/sources/shiboken2/libshiboken/signature.h
@@ -48,7 +48,7 @@ extern "C"
LIBSHIBOKEN_API int SbkSpecial_Type_Ready(PyObject *, PyTypeObject *, const char *[]);
LIBSHIBOKEN_API void FinishSignatureInitialization(PyObject *, const char *[]);
LIBSHIBOKEN_API void SetError_Argument(PyObject *, const char *);
-LIBSHIBOKEN_API PyObject *Sbk_TypeGet___signature__(PyObject *, const char *);
+LIBSHIBOKEN_API PyObject *Sbk_TypeGet___signature__(PyObject *, PyObject *);
LIBSHIBOKEN_API PyObject *Sbk_TypeGet___doc__(PyObject *);
} // extern "C"
diff --git a/sources/shiboken2/libshiboken/signature_doc.rst b/sources/shiboken2/libshiboken/signature_doc.rst
index 9c42c5976..cb9041d0c 100644
--- a/sources/shiboken2/libshiboken/signature_doc.rst
+++ b/sources/shiboken2/libshiboken/signature_doc.rst
@@ -73,8 +73,8 @@ It calls ``GetSignature_Function`` which returns the signature if it is found.
Why this Code is Fast
---------------------
-It costs a little time (maybe 4 seconds) to run througs every single signature
-object, since these are more than 15000 Python objects. But all the signature
+It costs a little time (maybe 6 seconds) to run througs every single signature
+object, since these are more than 25000 Python objects. But all the signature
objects will be rarely accessed but in special applications.
The normal case are only a few accesses, and these are working pretty fast.
@@ -111,10 +111,6 @@ the ``signature`` Python package. It has the following structure::
shiboken2/files.dir/shibokensupport/
backport_inspect.py
- python_minilib_2_7.py
- python_minilib_3_5.py
- python_minilib_3_6.py
- python_minilib_3_7.py
signature/
loader.py
@@ -125,6 +121,8 @@ the ``signature`` Python package. It has the following structure::
lib/
enum_sig.py
+ tool.py
+
Really important are the **parser**, **mapping**, **errorhandler**, **enum_sig**,
@@ -267,6 +265,17 @@ we can now capture the error output of COIN and check the generated module
in.
+Explicitly Enforcing Recreation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The former way to regenerate the registry files was to remove the files
+and check that in. This has the desired effect, but creates huge deltas.
+As a more efficient way, we have prepared a comment in the first line
+that contains the word "recreate".
+By uncommenting this line, a NameError is triggered, which has the same
+effect.
+
+
init_platform.py
~~~~~~~~~~~~~~~~
diff --git a/sources/shiboken2/libshiboken/typespec.cpp b/sources/shiboken2/libshiboken/typespec.cpp
index 6dc5b00bc..510ed51e6 100644
--- a/sources/shiboken2/libshiboken/typespec.cpp
+++ b/sources/shiboken2/libshiboken/typespec.cpp
@@ -39,6 +39,7 @@
#include "sbkpython.h"
#include "typespec.h"
+#include "sbkstaticstrings.h"
#include <structmember.h>
#if PY_MAJOR_VERSION < 3
@@ -730,7 +731,7 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
}
// no PyId_ things in Python 2
// err = _PyDict_SetItemId(type->tp_dict, &PyId___module__, modname);
- err = PyDict_SetItemString(type->tp_dict, "__module__", modname);
+ err = PyDict_SetItem(type->tp_dict, Shiboken::PyMagicName::module(), modname);
Py_DECREF(modname);
if (err != 0)
goto fail;
diff --git a/sources/shiboken2/shiboken_version.py b/sources/shiboken2/shiboken_version.py
index 0d5681cc5..78ea0019d 100644
--- a/sources/shiboken2/shiboken_version.py
+++ b/sources/shiboken2/shiboken_version.py
@@ -1,6 +1,6 @@
#############################################################################
##
-## Copyright (C) 2018 The Qt Company Ltd.
+## Copyright (C) 2019 The Qt Company Ltd.
## Contact: https://www.qt.io/licensing/
##
## This file is part of Qt for Python.
@@ -38,9 +38,8 @@
#############################################################################
major_version = "5"
-minor_version = "13"
-patch_version = "3"
-
+minor_version = "14"
+patch_version = "0"
# For example: "a", "b", "rc"
# (which means "alpha", "beta", "release candidate").
diff --git a/sources/shiboken2/shibokenmodule/CMakeLists.txt b/sources/shiboken2/shibokenmodule/CMakeLists.txt
index bbf2677e4..e1eafa12f 100644
--- a/sources/shiboken2/shibokenmodule/CMakeLists.txt
+++ b/sources/shiboken2/shibokenmodule/CMakeLists.txt
@@ -52,6 +52,8 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/
"${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/layout.py" COPYONLY)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/loader.py"
"${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/loader.py" COPYONLY)
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/importhandler.py"
+ "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/importhandler.py" COPYONLY)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/mapping.py"
"${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/mapping.py" COPYONLY)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/parser.py"
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/backport_inspect.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/backport_inspect.py
index c690493b6..1f6d70b31 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/backport_inspect.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/backport_inspect.py
@@ -113,7 +113,9 @@ CO_NOFREE = 0x0040
# We use '__builtin__' and '__name__' instead.
def formatannotation(annotation, base_module=None):
if getattr(annotation, '__module__', None) == 'typing':
- return repr(annotation).replace('typing.', '')
+ # The replace must not be done on Python 2.7 because it
+ # already happens somewhere else.
+ return repr(annotation) ##.replace('typing.', '')
if isinstance(annotation, type):
if annotation.__module__ in ('__builtin__', base_module):
return annotation.__name__
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/importhandler.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/importhandler.py
new file mode 100644
index 000000000..0417f132a
--- /dev/null
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/importhandler.py
@@ -0,0 +1,103 @@
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## 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 Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 3 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL3 included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 3 requirements
+## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 2.0 or (at your option) the GNU General
+## Public license version 3 or any later version approved by the KDE Free
+## Qt Foundation. The licenses are as published by the Free Software
+## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+## 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-2.0.html and
+## https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+from __future__ import print_function, absolute_import
+
+"""
+importhandler.py
+
+This module handles special actions after the import of PySide modules.
+The reason for this was the wish to replace some deprecated functions
+by a Python implementation that gives a warning.
+
+It provides a framework to safely call functions outside of files.dir,
+because the implementation of deprecated functions should be visible
+to the users (in the hope they don't use it any longer <wink>).
+
+As a first approach, the function finish_import redirects to
+PySide2/support/deprecated.py . There can come other extensions as well.
+"""
+
+try:
+ from PySide2.support import deprecated
+ have_deprecated = True
+except ImportError:
+ have_deprecated = False
+
+
+# called by loader.py from signature.cpp
+def finish_import(module):
+ if have_deprecated and module.__name__.startswith("PySide2."):
+ try:
+ name = "fix_for_" + module.__name__.split(".")[1]
+ func = getattr(deprecated, name, None)
+ if func:
+ func(module)
+ except Exception as e:
+ name = e.__class__.__name__
+ print(72 * "*")
+ print("Error in deprecated.py, ignored:")
+ print(" {name}: {e}".format(**locals()))
+
+"""
+A note for people who might think this could be written in pure Python:
+
+Sure, by an explicit import of the modules to patch, this is no problem.
+But in the general case, a module should only be imported on user
+request and not because we want to patch it. So I started over.
+
+I then tried to do it on demand by redirection of the __import__ function.
+Things worked quite nicely as it seemed, but at second view this solution
+was much less appealing.
+
+Reason:
+If someone executes as the first PySide statement
+
+ from PySide2 import QtGui
+
+then this import is already running. We can see the other imports like the
+diverse initializations and QtCore, because it is triggered by import of
+QtGui. But the QtGui import can not be seen at all!
+
+With a lot of effort, sys.setprofile() and stack inspection with the inspect
+module, it is *perhaps* possible to solve that. I tried for a day and then
+gave up, since the solution is anyway not too nice when __import__ must
+be overridden.
+"""
+#eof
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py
index a5e3247b1..f11f3cf3d 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py
@@ -52,11 +52,6 @@ by producing a lot of clarity.
import sys
from shibokensupport.signature import inspect
from shibokensupport.signature import get_signature
-try:
- from PySide2.QtCore import Qt
- EnumType = type(Qt.Key)
-except ImportError:
- EnumType = None
class ExactEnumerator(object):
@@ -69,6 +64,14 @@ class ExactEnumerator(object):
"""
def __init__(self, formatter, result_type=dict):
+ global EnumType
+ try:
+ # Lazy import
+ from PySide2.QtCore import Qt
+ EnumType = type(Qt.Key)
+ except ImportError:
+ EnumType = None
+
self.fmt = formatter
self.result_type = result_type
self.fmt.level = 0
@@ -81,6 +84,7 @@ class ExactEnumerator(object):
def module(self, mod_name):
__import__(mod_name)
+ self.fmt.mod_name = mod_name
with self.fmt.module(mod_name):
module = sys.modules[mod_name]
members = inspect.getmembers(module, inspect.isclass)
@@ -90,7 +94,7 @@ class ExactEnumerator(object):
for class_name, klass in members:
ret.update(self.klass(class_name, klass))
if isinstance(klass, EnumType):
- self.enum(klass)
+ raise SystemError("implement enum instances at module level")
for func_name, func in functions:
ret.update(self.function(func_name, func))
return ret
@@ -106,26 +110,47 @@ class ExactEnumerator(object):
name = modname + "." + base.__name__
bases_list.append(name)
class_str = "{}({})".format(class_name, ", ".join(bases_list))
- with self.fmt.klass(class_name, class_str):
- ret = self.result_type()
- # class_members = inspect.getmembers(klass)
- # gives us also the inherited things.
- class_members = sorted(list(klass.__dict__.items()))
- subclasses = []
- functions = []
- for thing_name, thing in class_members:
- if inspect.isclass(thing):
- subclass_name = ".".join((class_name, thing_name))
- subclasses.append((subclass_name, thing))
- elif inspect.isroutine(thing):
- func_name = thing_name.split(".")[0] # remove ".overload"
+ ret = self.result_type()
+ # class_members = inspect.getmembers(klass)
+ # gives us also the inherited things.
+ class_members = sorted(list(klass.__dict__.items()))
+ subclasses = []
+ functions = []
+ enums = []
+
+ for thing_name, thing in class_members:
+ if inspect.isclass(thing):
+ subclass_name = ".".join((class_name, thing_name))
+ subclasses.append((subclass_name, thing))
+ elif inspect.isroutine(thing):
+ func_name = thing_name.split(".")[0] # remove ".overload"
+ signature = getattr(thing, "__signature__", None)
+ if signature is not None:
functions.append((func_name, thing))
+ elif type(type(thing)) is EnumType:
+ enums.append((thing_name, thing))
+ init_signature = getattr(klass, "__signature__", None)
+ enums.sort(key=lambda tup: tup[1]) # sort by enum value
+ self.fmt.have_body = bool(subclasses or functions or enums or init_signature)
+
+ with self.fmt.klass(class_name, class_str):
self.fmt.level += 1
+ self.fmt.class_name = class_name
+ if hasattr(self.fmt, "enum"):
+ # this is an optional feature
+ for enum_name, value in enums:
+ with self.fmt.enum(class_name, enum_name, int(value)):
+ pass
for subclass_name, subclass in subclasses:
+ if klass == subclass:
+ # this is a side effect of the typing module for Python 2.7
+ # via the "._gorg" property, which we can safely ignore.
+ print("Warning: {class_name} points to itself via {subclass_name}, skipped!"
+ .format(**locals()))
+ continue
ret.update(self.klass(subclass_name, subclass))
- if isinstance(subclass, EnumType):
- self.enum(subclass)
- ret = self.function("__init__", klass)
+ self.fmt.class_name = class_name
+ ret.update(self.function("__init__", klass))
for func_name, func in functions:
func_kind = get_signature(func, "__func_kind__")
modifier = func_kind if func_kind in (
@@ -137,24 +162,13 @@ class ExactEnumerator(object):
def function(self, func_name, func, modifier=None):
self.fmt.level += 1
ret = self.result_type()
- signature = getattr(func, '__signature__', None)
+ signature = func.__signature__
if signature is not None:
with self.fmt.function(func_name, signature, modifier) as key:
ret[key] = signature
self.fmt.level -= 1
return ret
- def enum(self, subclass):
- if not hasattr(self.fmt, "enum"):
- # this is an optional feature
- return
- class_name = subclass.__name__
- for enum_name, value in subclass.__dict__.items():
- if type(type(value)) is EnumType:
- with self.fmt.enum(class_name, enum_name, int(value)):
- pass
- self._after_enum = True
-
def stringify(signature):
if isinstance(signature, list):
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
index 8eff19d77..a0367883a 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
@@ -89,6 +89,10 @@ def formatannotation(annotation, base_module=None):
# break the Python license decorated files without an encoding line.
# name used in signature.cpp
+def pyside_type_init(type_key, sig_strings):
+ return parser.pyside_type_init(type_key, sig_strings)
+
+# name used in signature.cpp
def create_signature(props, key):
return layout.create_signature(props, key)
@@ -100,6 +104,11 @@ def seterror_argument(args, func_name):
def make_helptext(func):
return errorhandler.make_helptext(func)
+# name used in signature.cpp
+def finish_import(module):
+ return importhandler.finish_import(module)
+
+
import signature_bootstrap
from shibokensupport import signature
signature.get_signature = signature_bootstrap.get_signature
@@ -185,6 +194,7 @@ def move_into_pyside_package():
put_into_package(PySide2.support.signature, layout)
put_into_package(PySide2.support.signature, lib)
put_into_package(PySide2.support.signature, parser)
+ put_into_package(PySide2.support.signature, importhandler)
put_into_package(PySide2.support.signature.lib, enum_sig)
put_into_package(None if orig_typing else PySide2.support.signature, typing)
@@ -195,8 +205,8 @@ from shibokensupport.signature import errorhandler
from shibokensupport.signature import layout
from shibokensupport.signature import lib
from shibokensupport.signature import parser
+from shibokensupport.signature import importhandler
from shibokensupport.signature.lib import enum_sig
-from shibokensupport.signature.parser import pyside_type_init
if "PySide2" in sys.modules:
# We publish everything under "PySide2.support.signature", again.
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
index 163aac851..2110ebe7a 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
@@ -66,7 +66,6 @@ Point = typing.Tuple[float, float]
Variant = typing.Any
ModelIndexList = typing.List[int]
QImageCleanupFunction = typing.Callable
-StringList = typing.List[str]
# unfortunately, typing.Optional[t] expands to typing.Union[t, NoneType]
# Until we can force it to create Optional[t] again, we use this.
@@ -184,6 +183,27 @@ class Default(_NotCalled):
class Instance(_NotCalled):
pass
+# Parameterized primitive variables
+class _Parameterized(object):
+ def __init__(self, type):
+ self.type = type
+ self.__name__ = self.__class__.__name__
+
+ def __repr__(self):
+ return "{}({})".format(
+ type(self).__name__, self.type.__name__)
+
+# Mark the primitive variables to be moved into the result.
+class ResultVariable(_Parameterized):
+ pass
+
+# Mark the primitive variables to become Sequence, Iterable or List
+# (decided in the parser).
+class ArrayLikeVariable(_Parameterized):
+ pass
+
+StringList = ArrayLikeVariable(str)
+
class Reloader(object):
"""
@@ -244,6 +264,7 @@ type_map = {}
namespace = globals() # our module's __dict__
type_map.update({
+ "...": ellipsis,
"bool": bool,
"char": Char,
"char*": str,
@@ -251,7 +272,7 @@ type_map.update({
"double": float,
"float": float,
"int": int,
- "List": typing.List,
+ "List": ArrayLikeVariable,
"long": int,
"PyCallable": typing.Callable,
"PyObject": object,
@@ -264,7 +285,7 @@ type_map.update({
"qint64": int,
"qint8": int,
"qintptr": int,
- "QList": typing.List,
+ "QList": ArrayLikeVariable,
"qlonglong": int,
"QMap": typing.Dict,
"QPair": typing.Tuple,
@@ -286,17 +307,28 @@ type_map.update({
"short": int,
"signed char": Char,
"signed long": int,
+ "std.list": typing.List,
+ "std.map": typing.Dict,
+ "std.pair": typing.Tuple,
+ "std.vector": typing.List,
"str": str,
"true": True,
+ "Tuple": typing.Tuple,
+ "uchar": Char,
+ "uchar*": str,
+ "uint": int,
+ "ulong": int,
"ULONG_MAX": ulong_max,
- "unsigned char": Char,
- "unsigned int": int, # should we define an unsigned type?
+ "unsigned char": Char, # 5.9
+ "unsigned char*": str,
+ "unsigned int": int,
"unsigned long int": int, # 5.6, RHEL 6.6
"unsigned long long": int,
"unsigned long": int,
"unsigned short int": int, # 5.6, RHEL 6.6
"unsigned short": int,
- "UnsignedShortType": int, # 5.9
+ "Unspecified": None,
+ "ushort": int,
"void": int, # be more specific?
"WId": WId,
"zero(bytes)": b"",
@@ -305,7 +337,51 @@ type_map.update({
"zero(int)": 0,
"zero(object)": None,
"zero(str)": "",
- "...": "...",
+ "zero(typing.Any)": None,
+ })
+
+type_map.update({
+ # Handling variables declared as array:
+ "array double*" : ArrayLikeVariable(float),
+ "array float*" : ArrayLikeVariable(float),
+ "array GLint*" : ArrayLikeVariable(int),
+ "array GLuint*" : ArrayLikeVariable(int),
+ "array int*" : ArrayLikeVariable(int),
+ "array long long*" : ArrayLikeVariable(int),
+ "array long*" : ArrayLikeVariable(int),
+ "array short*" : ArrayLikeVariable(int),
+ "array signed char*" : bytes,
+ "array unsigned char*" : bytes,
+ "array unsigned int*" : ArrayLikeVariable(int),
+ "array unsigned short*" : ArrayLikeVariable(int),
+ })
+
+type_map.update({
+ # Special cases:
+ "char*" : bytes,
+ "QChar*" : bytes,
+ "quint32*" : int, # only for QRandomGenerator
+ "quint8*" : bytearray, # only for QCborStreamReader and QCborValue
+ "uchar*" : bytes,
+ "unsigned char*": bytes,
+ })
+
+type_map.update({
+ # Handling variables that are returned, eventually as Tuples:
+ "bool*" : ResultVariable(bool),
+ "float*" : ResultVariable(float),
+ "int*" : ResultVariable(int),
+ "long long*" : ResultVariable(int),
+ "long*" : ResultVariable(int),
+ "PStr*" : ResultVariable(str), # module sample
+ "qint32*" : ResultVariable(int),
+ "qint64*" : ResultVariable(int),
+ "qreal*" : ResultVariable(float),
+ "QString*" : ResultVariable(str),
+ "quint16*" : ResultVariable(int),
+ "uint*" : ResultVariable(int),
+ "unsigned int*" : ResultVariable(int),
+ "QStringList*" : ResultVariable(StringList),
})
@@ -330,6 +406,7 @@ def init_sample():
import datetime
type_map.update({
"char": Char,
+ "char**": typing.List[str],
"Complex": complex,
"double": float,
"Foo.HANDLE": int,
@@ -346,7 +423,8 @@ def init_sample():
"sample.int": int,
"sample.ObjectType": object,
"sample.OddBool": bool,
- "sample.Photon.TemplateBase": Missing("sample.Photon.TemplateBase"),
+ "sample.Photon.TemplateBase[Photon.DuplicatorType]": sample.Photon.ValueDuplicator,
+ "sample.Photon.TemplateBase[Photon.IdentityType]": sample.Photon.ValueIdentity,
"sample.Point": Point,
"sample.PStr": str,
"sample.unsigned char": Char,
@@ -381,6 +459,7 @@ def init_smart():
})
return locals()
+
# The PySide Part
def init_PySide2_QtCore():
from PySide2.QtCore import Qt, QUrl, QDir
@@ -402,50 +481,18 @@ def init_PySide2_QtCore():
"list of QAbstractAnimation": typing.List[PySide2.QtCore.QAbstractAnimation],
"list of QAbstractState": typing.List[PySide2.QtCore.QAbstractState],
"long long": int,
- "long": int,
"NULL": None, # 5.6, MSVC
"nullptr": None, # 5.9
"PyByteArray": bytearray,
"PyBytes": bytes,
- "PyCallable": typing.Callable,
- "PyObject": object,
- "PySequence": typing.Iterable, # important for numpy
- "PySide2.QtCore.bool": bool,
- "PySide2.QtCore.char": StringList, # A 'char **' is a list of strings.
- "PySide2.QtCore.double": float,
- "PySide2.QtCore.float": float,
- "PySide2.QtCore.int": int,
- "PySide2.QtCore.int32_t": int, # 5.9
- "PySide2.QtCore.int64_t": int, # 5.9
- "PySide2.QtCore.long long": int, # 5.9, MSVC 15
- "PySide2.QtCore.long": int,
- "PySide2.QtCore.QCborStreamReader.StringResult": typing.AnyStr,
- "PySide2.QtCore.QChar": Char,
- "PySide2.QtCore.qint16": int,
- "PySide2.QtCore.qint32": int,
- "PySide2.QtCore.qint64": int,
- "PySide2.QtCore.qint8": int,
- "PySide2.QtCore.qreal": float,
- "PySide2.QtCore.QString": str,
- "PySide2.QtCore.QStringList": StringList,
- "PySide2.QtCore.quint16": int,
- "PySide2.QtCore.quint32": int,
- "PySide2.QtCore.quint64": int,
- "PySide2.QtCore.quint8": int,
+ "PySide2.QtCore.QCborStreamReader.StringResult[PySide2.QtCore.QByteArray]":
+ PySide2.QtCore.QCborStringResultByteArray,
+ "PySide2.QtCore.QCborStreamReader.StringResult[QString]":
+ PySide2.QtCore.QCborStringResultString,
"PySide2.QtCore.QUrl.ComponentFormattingOptions":
PySide2.QtCore.QUrl.ComponentFormattingOption, # mismatch option/enum, why???
- "PySide2.QtCore.QVariant": Variant,
- "PySide2.QtCore.short": int,
- "PySide2.QtCore.signed char": Char,
- "PySide2.QtCore.uchar": Char,
- "PySide2.QtCore.uint32_t": int, # 5.9
- "PySide2.QtCore.unsigned char": Char, # 5.9
- "PySide2.QtCore.unsigned int": int, # 5.9 Ubuntu
- "PySide2.QtCore.unsigned short": int,
- "PyTypeObject": type,
"PyUnicode": typing.Text,
"Q_NULLPTR": None,
- "QChar": Char,
"QDir.Filters(AllEntries | NoDotAndDotDot)": Instance(
"QDir.Filters(QDir.AllEntries | QDir.NoDotAndDotDot)"),
"QDir.SortFlags(Name | IgnoreCase)": Instance(
@@ -456,24 +503,21 @@ def init_PySide2_QtCore():
"QGenericArgument(NULL)": ellipsis, # 5.6, MSVC
"QGenericArgument(nullptr)": ellipsis, # 5.10
"QGenericArgument(Q_NULLPTR)": ellipsis,
- "QHash": typing.Dict,
"QJsonObject": typing.Dict[str, PySide2.QtCore.QJsonValue],
"QModelIndex()": Invalid("PySide2.QtCore.QModelIndex"), # repr is btw. very wrong, fix it?!
"QModelIndexList": ModelIndexList,
- "qptrdiff": int,
- "QString": str,
+ "QModelIndexList": ModelIndexList,
"QString()": "",
- "QStringList": StringList,
"QStringList()": [],
"QStringRef": str,
- "Qt.HANDLE": int, # be more explicit with some consts?
- "quintptr": int,
+ "QStringRef": str,
+ "Qt.HANDLE": int, # be more explicit with some constants?
"QUrl.FormattingOptions(PrettyDecoded)": Instance(
"QUrl.FormattingOptions(QUrl.PrettyDecoded)"),
- "QVariant": Variant,
"QVariant()": Invalid(Variant),
"QVariant.Type": type, # not so sure here...
"QVariantMap": typing.Dict[str, Variant],
+ "QVariantMap": typing.Dict[str, Variant],
})
try:
type_map.update({
@@ -493,16 +537,12 @@ def init_PySide2_QtGui():
"GL_COLOR_BUFFER_BIT": GL_COLOR_BUFFER_BIT,
"GL_NEAREST": GL_NEAREST,
"int32_t": int,
- "PySide2.QtCore.uint8_t": int, # macOS 5.9
- "PySide2.QtGui.QGenericMatrix": Missing("PySide2.QtGui.QGenericMatrix"),
- "PySide2.QtGui.QPlatformSurface": int, # a handle
- "QList< QTouchEvent.TouchPoint >()": [], # XXX improve?
"QPixmap()": Default("PySide2.QtGui.QPixmap"), # can't create without qApp
+ "QPlatformSurface*": int, # a handle
"QVector< QTextLayout.FormatRange >()": [], # do we need more structure?
"uint32_t": int,
"uint8_t": int,
"USHRT_MAX": ushort_max,
- "WId": WId,
})
return locals()
@@ -513,7 +553,6 @@ def init_PySide2_QtWidgets():
type_map.update({
"QMessageBox.StandardButtons(Yes | No)": Instance(
"QMessageBox.StandardButtons(QMessageBox.Yes | QMessageBox.No)"),
- "QVector< int >()": [],
"QWidget.RenderFlags(DrawWindowBackground | DrawChildren)": Instance(
"QWidget.RenderFlags(QWidget.DrawWindowBackground | QWidget.DrawChildren)"),
"SH_Default": QStyleHintReturn.SH_Default,
@@ -536,9 +575,12 @@ def init_PySide2_QtSql():
def init_PySide2_QtNetwork():
+ best_structure = typing.OrderedDict if getattr(typing, "OrderedDict", None) else typing.Dict
type_map.update({
- "QMultiMap": MultiMap,
+ "QMultiMap[PySide2.QtNetwork.QSsl.AlternativeNameEntryType, QString]":
+ best_structure[PySide2.QtNetwork.QSsl.AlternativeNameEntryType, typing.List[str]],
})
+ del best_structure
return locals()
@@ -557,6 +599,7 @@ def init_PySide2_QtMultimedia():
check_module(PySide2.QtMultimediaWidgets)
type_map.update({
"QGraphicsVideoItem": PySide2.QtMultimediaWidgets.QGraphicsVideoItem,
+ "qint64": int,
"QVideoWidget": PySide2.QtMultimediaWidgets.QVideoWidget,
})
return locals()
@@ -569,26 +612,23 @@ def init_PySide2_QtOpenGL():
"GLfloat": float, # 5.6, MSVC 15
"GLint": int,
"GLuint": int,
- "PySide2.QtOpenGL.GLint": int,
- "PySide2.QtOpenGL.GLuint": int,
})
return locals()
def init_PySide2_QtQml():
type_map.update({
- "PySide2.QtQml.bool volatile": bool,
"QJSValueList()": [],
- "QVariantHash()": typing.Dict[str, Variant], # XXX sorted?
+ "QVariantHash()": typing.Dict[str, Variant], # from 5.9
})
return locals()
def init_PySide2_QtQuick():
type_map.update({
- "PySide2.QtCore.uint": int,
- "PySide2.QtQuick.QSharedPointer": int,
- "T": int,
+ "PySide2.QtQuick.QSharedPointer[PySide2.QtQuick.QQuickItemGrabResult]":
+ PySide2.QtQuick.QQuickItemGrabResult,
+ "UnsignedShortType": int,
})
return locals()
@@ -602,6 +642,7 @@ def init_PySide2_QtScript():
def init_PySide2_QtTest():
type_map.update({
+ "PySide2.QtTest.QTest.PySideQTouchEventSequence": PySide2.QtTest.QTest.QTouchEventSequence,
"PySide2.QtTest.QTouchEventSequence": PySide2.QtTest.QTest.QTouchEventSequence,
})
return locals()
@@ -622,6 +663,10 @@ def init_PySide2_QtDataVisualization():
QtDataVisualization.QSurfaceDataArray = typing.List[QtDataVisualization.QSurfaceDataRow]
type_map.update({
"100.0f": 100.0,
+ "QtDataVisualization.QBarDataArray": QtDataVisualization.QBarDataArray,
+ "QtDataVisualization.QBarDataArray*": QtDataVisualization.QBarDataArray,
+ "QtDataVisualization.QSurfaceDataArray": QtDataVisualization.QSurfaceDataArray,
+ "QtDataVisualization.QSurfaceDataArray*": QtDataVisualization.QSurfaceDataArray,
})
return locals()
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
index 0081a07ba..8d970956b 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
@@ -46,7 +46,7 @@ import types
import keyword
import functools
from shibokensupport.signature.mapping import (type_map, update_mapping,
- namespace, typing, _NotCalled)
+ namespace, typing, _NotCalled, ResultVariable, ArrayLikeVariable)
from shibokensupport.signature.lib.tool import (SimpleNamespace,
build_brace_pattern)
@@ -170,9 +170,9 @@ def _resolve_value(thing, valtype, line):
if thing in ("0", "None") and valtype:
if valtype.startswith("PySide2.") or valtype.startswith("typing."):
return None
- mapped = type_map[valtype]
+ map = type_map[valtype]
# typing.Any: '_SpecialForm' object has no attribute '__name__'
- name = mapped.__name__ if hasattr(mapped, "__name__") else str(mapped)
+ name = map.__name__ if hasattr(map, "__name__") else str(map)
thing = "zero({})".format(name)
if thing in type_map:
return type_map[thing]
@@ -219,8 +219,6 @@ def to_string(thing):
matrix_pattern = "PySide2.QtGui.QGenericMatrix"
-# The matrix patch is borrowed from the future (extracted).
-# It will work when the parser recognizes matrices.
def handle_matrix(arg):
n, m, typstr = tuple(map(lambda x:x.strip(), arg.split(",")))
assert typstr == "float"
@@ -238,7 +236,7 @@ def lno(level):
"""
-def _resolve_type(thing, line, level):
+def _resolve_type(thing, line, level, var_handler):
# Capture total replacements, first. Happens in
# "PySide2.QtCore.QCborStreamReader.StringResult[PySide2.QtCore.QByteArray]"
if thing in type_map:
@@ -253,13 +251,13 @@ def _resolve_type(thing, line, level):
# Special case: Handle the generic matrices.
if contr == matrix_pattern:
return handle_matrix(thing)
- contr = _resolve_type(contr, line, level+1)
+ contr = var_handler(_resolve_type(contr, line, level+1, var_handler))
if isinstance(contr, _NotCalled):
raise SystemError("Container types must exist:", repr(contr))
contr = to_string(contr)
pieces = []
for part in _parse_arglist(thing):
- part = _resolve_type(part, line, level+1)
+ part = var_handler(_resolve_type(part, line, level+1, var_handler))
if isinstance(part, _NotCalled):
# fix the tag (i.e. "Missing") by repr
part = repr(part)
@@ -270,6 +268,46 @@ def _resolve_type(thing, line, level):
return _resolve_value(thing, None, line)
+def _handle_generic(obj, repl):
+ """
+ Assign repl if obj is an ArrayLikeVariable
+
+ This is a neat trick. Example:
+
+ obj repl result
+ ---------------------- -------- ---------
+ ArrayLikeVariable List List
+ ArrayLikeVariable(str) List List[str]
+ ArrayLikeVariable Sequence Sequence
+ ArrayLikeVariable(str) Sequence Sequence[str]
+ """
+ if isinstance(obj, ArrayLikeVariable):
+ return repl[obj.type]
+ if isinstance(obj, type) and issubclass(obj, ArrayLikeVariable):
+ # was "if obj is ArrayLikeVariable"
+ return repl
+ return obj
+
+
+def handle_argvar(obj):
+ """
+ Decide how array-like variables are resolved in arguments
+
+ Currently, the best approximation is types.Sequence.
+ We want to change that to types.Iterable in the near future.
+ """
+ return _handle_generic(obj, typing.Sequence)
+
+
+def handle_retvar(obj):
+ """
+ Decide how array-like variables are resolved in results
+
+ This will probably stay typing.List forever.
+ """
+ return _handle_generic(obj, typing.List)
+
+
def calculate_props(line):
parsed = SimpleNamespace(**_parse_line(line.strip()))
arglist = parsed.arglist
@@ -283,14 +321,14 @@ def calculate_props(line):
ann = 'nullptr' # maps to None
tup = name, ann
arglist[idx] = tup
- annotations[name] = _resolve_type(ann, line, 0)
+ annotations[name] = _resolve_type(ann, line, 0, handle_argvar)
if len(tup) == 3:
default = _resolve_value(tup[2], ann, line)
_defaults.append(default)
defaults = tuple(_defaults)
returntype = parsed.returntype
if returntype is not None:
- annotations["return"] = _resolve_type(returntype, line, 0)
+ annotations["return"] = _resolve_type(returntype, line, 0, handle_retvar)
props = SimpleNamespace()
props.defaults = defaults
props.kwdefaults = {}
@@ -301,9 +339,61 @@ def calculate_props(line):
shortname = funcname[funcname.rindex(".")+1:]
props.name = shortname
props.multi = parsed.multi
+ fix_variables(props, line)
return vars(props)
+def fix_variables(props, line):
+ annos = props.annotations
+ if not any(isinstance(ann, (ResultVariable, ArrayLikeVariable))
+ for ann in annos.values()):
+ return
+ retvar = annos.get("return", None)
+ if retvar and isinstance(retvar, (ResultVariable, ArrayLikeVariable)):
+ # Special case: a ResultVariable which is the result will always be an array!
+ annos["return"] = retvar = typing.List[retvar.type]
+ fullname = props.fullname
+ varnames = list(props.varnames)
+ defaults = list(props.defaults)
+ diff = len(varnames) - len(defaults)
+
+ safe_annos = annos.copy()
+ retvars = [retvar] if retvar else []
+ deletions = []
+ for idx, name in enumerate(varnames):
+ ann = safe_annos[name]
+ if isinstance(ann, ArrayLikeVariable):
+ ann = typing.Sequence[ann.type]
+ annos[name] = ann
+ if not isinstance(ann, ResultVariable):
+ continue
+ # We move the variable to the end and remove it.
+ retvars.append(ann.type)
+ deletions.append(idx)
+ del annos[name]
+ for idx in reversed(deletions):
+ # varnames: 0 1 2 3 4 5 6 7
+ # defaults: 0 1 2 3 4
+ # diff: 3
+ del varnames[idx]
+ if idx >= diff:
+ del defaults[idx - diff]
+ else:
+ diff -= 1
+ if retvars:
+ rvs = []
+ retvars = list(handle_retvar(rv) if isinstance(rv, ArrayLikeVariable) else rv
+ for rv in retvars)
+ if len(retvars) == 1:
+ returntype = retvars[0]
+ else:
+ typestr = "typing.Tuple[{}]".format(", ".join(map(to_string, retvars)))
+ returntype = eval(typestr, namespace)
+ props.annotations["return"] = returntype
+ props.varnames = tuple(varnames)
+ props.defaults = tuple(defaults)
+
+
def fixup_multilines(lines):
"""
Multilines can collapse when certain distinctions between C++ types
diff --git a/sources/shiboken2/tests/libsmart/smart.cpp b/sources/shiboken2/tests/libsmart/smart.cpp
index 8d85d67a1..6a4deb50a 100644
--- a/sources/shiboken2/tests/libsmart/smart.cpp
+++ b/sources/shiboken2/tests/libsmart/smart.cpp
@@ -28,10 +28,52 @@
#include "smart.h"
-bool shouldPrint() {
+#include <algorithm>
+#include <iostream>
+
+static inline bool shouldPrint()
+{
return Registry::getInstance()->shouldPrint();
}
+void SharedPtrBase::logDefaultConstructor(const void *t)
+{
+ if (shouldPrint())
+ std::cout << "shared_ptr default constructor " << t << '\n';
+}
+
+void SharedPtrBase::logConstructor(const void *t, const void *pointee)
+{
+ if (shouldPrint()) {
+ std::cout << "shared_ptr constructor " << t << " with pointer "
+ << pointee << '\n';
+ }
+}
+
+void SharedPtrBase::logCopyConstructor(const void *t, const void *refData)
+{
+ if (shouldPrint()) {
+ std::cout << "shared_ptr copy constructor " << t << " with pointer "
+ << refData << '\n';
+ }
+}
+
+void SharedPtrBase::logAssignment(const void *t, const void *refData)
+{
+ if (shouldPrint()) {
+ std::cout << "shared_ptr assignment operator " << t << " with pointer "
+ << refData << "\n";
+ }
+}
+
+void SharedPtrBase::logDestructor(const void *t, int remainingRefCount)
+{
+ if (shouldPrint()) {
+ std::cout << "shared_ptr destructor " << t << " remaining refcount "
+ << remainingRefCount << '\n';
+ }
+}
+
Obj::Obj() : m_integer(123), m_internalInteger(new Integer)
{
Registry::getInstance()->add(this);
@@ -143,10 +185,9 @@ Registry *Registry::getInstance()
return &registry;
}
-Registry::Registry() : m_printStuff(false)
-{
+Registry::Registry() = default;
-}
+Registry::~Registry() = default;
void Registry::add(Obj *p)
{
diff --git a/sources/shiboken2/tests/libsmart/smart.h b/sources/shiboken2/tests/libsmart/smart.h
index 3347b22c1..6238f27d5 100644
--- a/sources/shiboken2/tests/libsmart/smart.h
+++ b/sources/shiboken2/tests/libsmart/smart.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** 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.
@@ -29,193 +29,9 @@
#ifndef SMART_H
#define SMART_H
-#include <algorithm>
-#include <iostream>
-#include <vector>
-
-#include "libsmartmacros.h"
-
-// Forward declarations.
-template <class T>
-class SharedPtr;
-class Integer;
-class Obj;
-
-LIB_SMART_API bool shouldPrint();
-
-// Used to track which C++ objects are alive.
-class LIB_SMART_API Registry {
-public:
- static Registry *getInstance();
-
- void add(Obj *p);
- void add(Integer *p);
- void remove(Obj *p);
- void remove(Integer *p);
- int countObjects() const;
- int countIntegers() const;
- bool shouldPrint() const;
- void setShouldPrint(bool flag);
-
-protected:
- Registry();
-
-private:
- bool m_printStuff;
- std::vector<Obj *> m_objects;
- std::vector<Integer *> m_integers;
-};
-
-template <class T>
-class RefData {
-public:
- RefData(T *ptr) : m_refCount(1), m_heldPtr(ptr) {}
- ~RefData() { delete m_heldPtr; }
- int inc() { return ++m_refCount; }
- int dec() { return --m_refCount; }
- int useCount() { return m_refCount; }
- int m_refCount;
- T *m_heldPtr;
-};
-
-template <class T>
-class SharedPtr {
-public:
- SharedPtr() : m_refData(nullptr) {
- if (shouldPrint())
- std::cout << "shared_ptr default constructor " << this << "\n";
- }
-
- SharedPtr(T *v)
- {
- if (shouldPrint())
- std::cout << "shared_ptr constructor " << this << " with pointer " << v << "\n";
- if (v)
- m_refData = new RefData<T>(v);
- }
-
- SharedPtr(const SharedPtr<T> &other) : m_refData(other.m_refData)
- {
- if (shouldPrint())
- std::cout << "shared_ptr copy constructor " << this << " with pointer "
- << other.m_refData << "\n";
- if (m_refData)
- m_refData->inc();
- }
-
- SharedPtr<T> &operator=(const SharedPtr<T>& other)
- {
- if (this != &other) {
- if (shouldPrint())
- std::cout << "shared_ptr assignment operator " << this << " with pointer "
- << other.m_refData << "\n";
- if (m_refData && m_refData->dec() == 0)
- delete m_refData;
- m_refData = other.m_refData;
- if (m_refData)
- m_refData->inc();
- }
- return *this;
- }
-
- T *data() const
- {
- if (m_refData)
- return m_refData->m_heldPtr;
- return nullptr;
- }
-
- int useCount() const
- {
- if (m_refData)
- return m_refData->useCount();
- return 0;
- }
-
- void dummyMethod1()
- {
-
- }
-
- T& operator*() const
- {
- // Crashes if smart pointer is empty (just like std::shared_ptr).
- return *(m_refData->m_heldPtr);
- }
-
- T *operator->() const
- {
- if (m_refData)
- return m_refData->m_heldPtr;
- return nullptr;
- }
-
- bool operator!() const
- {
- return !m_refData || !m_refData->m_heldPtr;
- }
-
- bool isNull() const
- {
- return !m_refData || !m_refData->m_heldPtr;
- }
-
- operator bool() const
- {
- return m_refData && m_refData->m_heldPtr;
- }
-
- ~SharedPtr()
- {
- if (m_refData) {
- if (shouldPrint())
- std::cout << "shared_ptr destructor " << this << " remaining refcount "
- << m_refData->useCount() - 1 << "\n";
- }
- if (m_refData && m_refData->dec() == 0)
- delete m_refData;
- }
-
- RefData<T> *m_refData;
-};
-
-class LIB_SMART_API Integer {
-public:
- Integer();
- Integer(const Integer &other);
- Integer &operator=(const Integer &other);
- ~Integer();
- void printInteger();
- int m_int;
-};
-
-namespace Smart {
-class LIB_SMART_API Integer2 : public Integer {
-public:
- Integer2();
- Integer2(const Integer2 &other);
-};
-}
-
-
-// Couldn't name it Object because it caused some namespace clashes.
-class LIB_SMART_API Obj {
-public:
- Obj();
- virtual ~Obj();
-
- void printObj();
- Integer takeInteger(Integer val);
- SharedPtr<Obj> giveSharedPtrToObj();
- std::vector<SharedPtr<Obj> > giveSharedPtrToObjList(int size);
- SharedPtr<Integer> giveSharedPtrToInteger();
- SharedPtr<Smart::Integer2> giveSharedPtrToInteger2();
- int takeSharedPtrToObj(SharedPtr<Obj> pObj);
- int takeSharedPtrToInteger(SharedPtr<Integer> pInt);
-
- int m_integer;
- Integer *m_internalInteger;
-};
+#include "smart_sharedptr.h"
+#include "smart_integer.h"
+#include "smart_obj.h"
+#include "smart_registry.h"
#endif // SMART_H
-
diff --git a/sources/shiboken2/tests/libsmart/smart_integer.h b/sources/shiboken2/tests/libsmart/smart_integer.h
new file mode 100644
index 000000000..3756f68b0
--- /dev/null
+++ b/sources/shiboken2/tests/libsmart/smart_integer.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** 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 SMART_INTEGER_H
+#define SMART_INTEGER_H
+
+#include "libsmartmacros.h"
+
+class LIB_SMART_API Integer {
+public:
+ Integer();
+ Integer(const Integer &other);
+ Integer &operator=(const Integer &other);
+ ~Integer();
+ void printInteger();
+ int m_int;
+};
+
+namespace Smart {
+class LIB_SMART_API Integer2 : public Integer {
+public:
+ Integer2();
+ Integer2(const Integer2 &other);
+};
+} // namespace Smart
+
+#endif // SMART_INTEGER_H
diff --git a/sources/shiboken2/tests/libsmart/smart_obj.h b/sources/shiboken2/tests/libsmart/smart_obj.h
new file mode 100644
index 000000000..12425366e
--- /dev/null
+++ b/sources/shiboken2/tests/libsmart/smart_obj.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** 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 SMART_OBJ_H
+#define SMART_OBJ_H
+
+#include "libsmartmacros.h"
+#include "smart_sharedptr.h"
+
+#include <vector>
+
+class Integer;
+class Obj;
+namespace Smart { class Integer2; }
+
+// Couldn't name it Object because it caused some namespace clashes.
+class LIB_SMART_API Obj {
+public:
+ Obj();
+ virtual ~Obj();
+
+ void printObj();
+ Integer takeInteger(Integer val);
+ SharedPtr<Obj> giveSharedPtrToObj();
+ std::vector<SharedPtr<Obj> > giveSharedPtrToObjList(int size);
+ SharedPtr<Integer> giveSharedPtrToInteger();
+ SharedPtr<Smart::Integer2> giveSharedPtrToInteger2();
+ int takeSharedPtrToObj(SharedPtr<Obj> pObj);
+ int takeSharedPtrToInteger(SharedPtr<Integer> pInt);
+
+ int m_integer;
+ Integer *m_internalInteger;
+};
+
+#endif // SMART_OBJ_H
diff --git a/sources/shiboken2/tests/libsmart/smart_registry.h b/sources/shiboken2/tests/libsmart/smart_registry.h
new file mode 100644
index 000000000..6171ddb59
--- /dev/null
+++ b/sources/shiboken2/tests/libsmart/smart_registry.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** 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 SMART_REGISTRY_H
+#define SMART_REGISTRY_H
+
+#include <vector>
+
+#include "libsmartmacros.h"
+
+class Obj;
+class Integer;
+
+// Used to track which C++ objects are alive.
+class LIB_SMART_API Registry {
+public:
+ static Registry *getInstance();
+ ~Registry();
+
+ Registry(const Registry &) = delete;
+ Registry &operator=(const Registry &) = delete;
+ Registry(Registry &&) = delete;
+ Registry &operator=(Registry &&) = delete;
+
+ void add(Obj *p);
+ void add(Integer *p);
+ void remove(Obj *p);
+ void remove(Integer *p);
+ int countObjects() const;
+ int countIntegers() const;
+ bool shouldPrint() const;
+ void setShouldPrint(bool flag);
+
+protected:
+ Registry();
+
+private:
+ std::vector<Obj *> m_objects;
+ std::vector<Integer *> m_integers;
+ bool m_printStuff = false;
+};
+
+#endif // SMART_REGISTRY_H
diff --git a/sources/shiboken2/tests/libsmart/smart_sharedptr.h b/sources/shiboken2/tests/libsmart/smart_sharedptr.h
new file mode 100644
index 000000000..84184e1f8
--- /dev/null
+++ b/sources/shiboken2/tests/libsmart/smart_sharedptr.h
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** 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 SMART_SHARED_PTR_H
+#define SMART_SHARED_PTR_H
+
+#include "libsmartmacros.h"
+
+template <class T>
+class RefData {
+public:
+ RefData(T *ptr) : m_refCount(1), m_heldPtr(ptr) {}
+ ~RefData() { delete m_heldPtr; }
+ int inc() { return ++m_refCount; }
+ int dec() { return --m_refCount; }
+ int useCount() { return m_refCount; }
+ int m_refCount;
+ T *m_heldPtr;
+};
+
+struct SharedPtrBase
+{
+ LIB_SMART_API static void logDefaultConstructor(const void *t);
+ LIB_SMART_API static void logConstructor(const void *t, const void *pointee);
+ LIB_SMART_API static void logCopyConstructor(const void *t, const void *refData);
+ LIB_SMART_API static void logAssignment(const void *t, const void *refData);
+ LIB_SMART_API static void logDestructor(const void *t, int remainingRefCount);
+};
+
+template <class T>
+class SharedPtr : public SharedPtrBase {
+public:
+ SharedPtr() { logDefaultConstructor(this); }
+
+ SharedPtr(T *v)
+ {
+ logConstructor(this, v);
+ if (v)
+ m_refData = new RefData<T>(v);
+ }
+
+ SharedPtr(const SharedPtr<T> &other) : m_refData(other.m_refData)
+ {
+ logCopyConstructor(this, other.m_refData);
+ if (m_refData)
+ m_refData->inc();
+ }
+
+ SharedPtr<T> &operator=(const SharedPtr<T>& other)
+ {
+ if (this != &other) {
+ logAssignment(this, other.m_refData);
+ if (m_refData && m_refData->dec() == 0)
+ delete m_refData;
+ m_refData = other.m_refData;
+ if (m_refData)
+ m_refData->inc();
+ }
+ return *this;
+ }
+
+ T *data() const
+ {
+ return m_refData ? m_refData->m_heldPtr : nullptr;
+ }
+
+ int useCount() const
+ {
+ return m_refData ? m_refData->useCount() : 0;
+ }
+
+ void dummyMethod1()
+ {
+
+ }
+
+ T& operator*() const
+ {
+ // Crashes if smart pointer is empty (just like std::shared_ptr).
+ return *(m_refData->m_heldPtr);
+ }
+
+ T *operator->() const
+ {
+ return m_refData ? m_refData->m_heldPtr : nullptr;
+ }
+
+ bool operator!() const
+ {
+ return !m_refData || !m_refData->m_heldPtr;
+ }
+
+ bool isNull() const
+ {
+ return !m_refData || !m_refData->m_heldPtr;
+ }
+
+ operator bool() const
+ {
+ return m_refData && m_refData->m_heldPtr;
+ }
+
+ ~SharedPtr()
+ {
+ if (m_refData)
+ logDestructor(this, m_refData->useCount() - 1);
+ if (m_refData && m_refData->dec() == 0)
+ delete m_refData;
+ }
+
+private:
+ RefData<T> *m_refData = nullptr;
+};
+
+#endif // SMART_SHARED_PTR_H
diff --git a/sources/shiboken2/tests/samplebinding/pointerprimitivetype_test.py b/sources/shiboken2/tests/samplebinding/pointerprimitivetype_test.py
new file mode 100644
index 000000000..c40770862
--- /dev/null
+++ b/sources/shiboken2/tests/samplebinding/pointerprimitivetype_test.py
@@ -0,0 +1,79 @@
+#!/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$
+##
+#############################################################################
+
+"""
+pointerprimitivetype_test.py
+
+check that the primitive types are correctly mapped by the signature module.
+
+Mapping
+-------
+IntArray2(const int*) -- <Signature (self, data: typing.Sequence)>
+getMargins(int*,int*,int*,int*)const -- <Signature (self) -> typing.Tuple[int, int, int, int]>
+
+We explicitly check only against typing.Iterable in the first test,
+because typing.Sequence is a subclass, but we will generalize this
+to typing.Iterable in the future.
+"""
+
+import unittest
+from sample import IntArray2, VirtualMethods
+
+import shiboken2
+type.__signature__ # trigger init, which does not happen in tests
+from shibokensupport.signature import typing
+
+
+class PointerPrimitiveTypeTest(unittest.TestCase):
+
+ def testArraySignature(self):
+ # signature="IntArray2(const int*)"
+ found = False
+ for sig in IntArray2.__signature__:
+ if "data" in sig.parameters:
+ found = True
+ break
+ self.assertTrue(found)
+ ann = sig.parameters["data"].annotation
+ self.assertEqual(ann.__args__, (int,))
+ # un-specify this class (forget "int") by setting the _special
+ # flag, so we can check using issubclass (undocumented feature).
+ ann._special = True
+ self.assertTrue(issubclass(ann, typing.Iterable))
+
+ def testReturnVarSignature(self):
+ # signature="getMargins(int*,int*,int*,int*)const">
+ ann = VirtualMethods.getMargins.__signature__.return_annotation
+ self.assertEqual(ann, typing.Tuple[int, int, int, int])
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
index 4d624f952..30ad5def7 100644
--- a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
+++ b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
@@ -227,7 +227,6 @@
</modify-argument>
<modify-argument index="1">
<replace-type modified-type="PStr"/>
- <remove-default-expression/>
<replace-default-expression with="PStr()"/>
</modify-argument>
<inject-code class="target" position="end">