diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2017-07-05 14:22:05 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2017-08-03 06:21:14 +0000 |
commit | 1578d14d1693122d4bcacede0d77527d8e898629 (patch) | |
tree | cb758cad0ab46f1884ecb44dc463a9f482be73dd /sources/shiboken2/ApiExtractor | |
parent | da3afed804d47d25b5078103d400b5889e67915b (diff) |
Add new <array> argument modification indicating array usage
The modification can be used to indicate that for example
int* is meant to be used as int[].
This is reflected in the NativePointerAsArrayPattern
usage pattern of AbstractMetaType.
Task-number: PYSIDE-354
Task-number: PYSIDE-516
Change-Id: Icaeb3cce4be9ce06caa2cab628d4e8fc1b684819
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'sources/shiboken2/ApiExtractor')
7 files changed, 69 insertions, 11 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp index 6032b788e..95d700110 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp @@ -1990,7 +1990,8 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu } metaFunction->setOriginalAttributes(metaFunction->attributes()); - fixArgumentNames(metaFunction); + if (!metaArguments.isEmpty()) + fixArgumentNames(metaFunction, metaFunction->modifications(m_currentClass)); if (metaClass) { const AbstractMetaArgumentList fargs = metaFunction->arguments(); @@ -2018,11 +2019,8 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu return metaFunction; } -void AbstractMetaBuilderPrivate::fixArgumentNames(AbstractMetaFunction *func) +void AbstractMetaBuilderPrivate::fixArgumentNames(AbstractMetaFunction *func, const FunctionModificationList &mods) { - if (func->arguments().isEmpty()) - return; - const FunctionModificationList &mods = func->modifications(m_currentClass); for (const FunctionModification &mod : mods) { for (const ArgumentModification &argMod : mod.argument_mods) { if (!argMod.renamed_to.isEmpty()) { @@ -2108,6 +2106,39 @@ static inline AbstractMetaFunction::FunctionType functionTypeFromCodeModel(CodeM return result; } +static inline QString msgCannotSetArrayUsage(const QString &function, int i, const QString &reason) +{ + return function + QLatin1String(": Cannot use parameter ") + QString::number(i + 1) + + QLatin1String(" as an array: ") + reason; +} + +bool AbstractMetaBuilderPrivate::setArrayArgumentType(AbstractMetaFunction *func, + const FunctionModelItem &functionItem, + int i) +{ + + AbstractMetaType *metaType = func->arguments().at(i)->type(); + if (metaType->indirections() == 0) { + qCWarning(lcShiboken).noquote() + << msgCannotSetArrayUsage(func->minimalSignature(), i, + QLatin1String("Type does not have indirections.")); + return false; + } + TypeInfo elementType = functionItem->arguments().at(i)->type(); + elementType.setIndirections(elementType.indirections() - 1); + bool ok; + AbstractMetaType *element = translateType(elementType, &ok); + if (element == nullptr || !ok) { + qCWarning(lcShiboken).noquote() + << msgCannotSetArrayUsage(func->minimalSignature(), i, + QLatin1String("Cannot translate element type ") + elementType.toString()); + return false; + } + metaType->setArrayElementType(element); + metaType->setTypeUsagePattern(AbstractMetaType::NativePointerAsArrayPattern); + return true; +} + AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModelItem functionItem) { if (!functionItem->templateParameters().isEmpty()) @@ -2322,7 +2353,16 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel } - fixArgumentNames(metaFunction); + if (!metaArguments.isEmpty()) { + const FunctionModificationList &mods = metaFunction->modifications(m_currentClass); + fixArgumentNames(metaFunction, mods); + for (const FunctionModification &mod : mods) { + for (const ArgumentModification &argMod : mod.argument_mods) { + if (argMod.array) + setArrayArgumentType(metaFunction, functionItem, argMod.index - 1); + } + } + } // Determine class special functions if (m_currentClass && metaFunction->arguments().size() == 1) { diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h index 8c4e4b185..71b69473e 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h @@ -155,7 +155,10 @@ public: void sortLists(); AbstractMetaArgumentList reverseList(const AbstractMetaArgumentList &list); void setInclude(TypeEntry *te, const QString &fileName) const; - void fixArgumentNames(AbstractMetaFunction *func); + void fixArgumentNames(AbstractMetaFunction *func, const FunctionModificationList &mods); + bool setArrayArgumentType(AbstractMetaFunction *func, + const FunctionModelItem &functionItem, int i); + void fillAddedFunctions(AbstractMetaClass *metaClass); AbstractMetaBuilder *q; diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp index 7cd9c371e..d38eb8587 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp @@ -158,6 +158,9 @@ AbstractMetaTypeCList AbstractMetaType::nestedArrayTypes() const t = elt; } break; + case NativePointerAsArrayPattern: + result.append(m_arrayElementType); + break; default: break; } diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h index c838f97e2..0529bed24 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.h +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h @@ -326,6 +326,7 @@ public: QObjectPattern, ValuePointerPattern, NativePointerPattern, + NativePointerAsArrayPattern, // "int*" as "int[]" ContainerPattern, SmartPointerPattern, VariantPattern, diff --git a/sources/shiboken2/ApiExtractor/typesystem.cpp b/sources/shiboken2/ApiExtractor/typesystem.cpp index 9adc5107b..13664c336 100644 --- a/sources/shiboken2/ApiExtractor/typesystem.cpp +++ b/sources/shiboken2/ApiExtractor/typesystem.cpp @@ -176,6 +176,7 @@ Handler::Handler(TypeDatabase* database, bool generate) tagNames.insert(QLatin1String("no-null-pointer"), StackElement::NoNullPointers); tagNames.insert(QLatin1String("reference-count"), StackElement::ReferenceCount); tagNames.insert(QLatin1String("parent"), StackElement::ParentOwner); + tagNames.insert(QLatin1String("array"), StackElement::Array); tagNames.insert(QLatin1String("inject-documentation"), StackElement::InjectDocumentation); tagNames.insert(QLatin1String("modify-documentation"), StackElement::ModifyDocumentation); tagNames.insert(QLatin1String("add-function"), StackElement::AddFunction); @@ -1283,6 +1284,9 @@ bool Handler::startElement(const QStringRef &n, const QXmlStreamAttributes &atts case StackElement::ParentOwner: attributes.insert(QLatin1String("index"), QString()); attributes.insert(QLatin1String("action"), QString()); + break; + case StackElement::Array: + break; default: { }; }; @@ -1875,8 +1879,13 @@ bool Handler::startElement(const QStringRef &n, const QXmlStreamAttributes &atts m_contextStack.top()->functionMods.last().argument_mods.last().owner = ao; } break; - - + case StackElement::Array: + if (topElement.type != StackElement::ModifyArgument) { + m_error = QLatin1String("array must be child of modify-argument"); + return false; + } + m_contextStack.top()->functionMods.last().argument_mods.last().array = true; + break; case StackElement::InjectCode: { if (!(topElement.type & StackElement::ComplexTypeEntryMask) && (topElement.type != StackElement::AddFunction) diff --git a/sources/shiboken2/ApiExtractor/typesystem.h b/sources/shiboken2/ApiExtractor/typesystem.h index b75da48ba..6c65adbe1 100644 --- a/sources/shiboken2/ApiExtractor/typesystem.h +++ b/sources/shiboken2/ApiExtractor/typesystem.h @@ -211,16 +211,17 @@ public: struct ArgumentModification { ArgumentModification() : removedDefaultExpression(false), removed(false), - noNullPointers(false), index(-1), version(0) {} + noNullPointers(false), array(false), index(-1), version(0) {} ArgumentModification(int idx, double vr) : removedDefaultExpression(false), removed(false), - noNullPointers(false), index(idx), version(vr) {} + noNullPointers(false), array(false), index(idx), version(vr) {} // Should the default expression be removed? uint removedDefaultExpression : 1; uint removed : 1; uint noNullPointers : 1; uint resetAfterUse : 1; + uint array : 1; // consider "int*" to be "int[]" // The index of this argument int index; diff --git a/sources/shiboken2/ApiExtractor/typesystem_p.h b/sources/shiboken2/ApiExtractor/typesystem_p.h index f2105a631..d485aad42 100644 --- a/sources/shiboken2/ApiExtractor/typesystem_p.h +++ b/sources/shiboken2/ApiExtractor/typesystem_p.h @@ -107,6 +107,7 @@ class StackElement NoNullPointers = 0x40000000, ReferenceCount = 0x80000000, ParentOwner = 0x90000000, + Array = 0xA0000000, ArgumentModifiers = 0xff000000 }; |