aboutsummaryrefslogtreecommitdiffstats
path: root/sources
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2017-07-05 14:22:05 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2017-08-03 06:21:14 +0000
commit1578d14d1693122d4bcacede0d77527d8e898629 (patch)
treecb758cad0ab46f1884ecb44dc463a9f482be73dd /sources
parentda3afed804d47d25b5078103d400b5889e67915b (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')
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp52
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h5
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.cpp3
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.h1
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.cpp13
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.h5
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem_p.h1
-rw-r--r--sources/shiboken2/tests/libsample/functions.cpp9
-rw-r--r--sources/shiboken2/tests/libsample/functions.h7
-rw-r--r--sources/shiboken2/tests/samplebinding/CMakeLists.txt1
-rw-r--r--sources/shiboken2/tests/samplebinding/array_sequence_test.py5
-rw-r--r--sources/shiboken2/tests/samplebinding/typesystem_sample.xml6
12 files changed, 97 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
};
diff --git a/sources/shiboken2/tests/libsample/functions.cpp b/sources/shiboken2/tests/libsample/functions.cpp
index 7a91a7b62..9fa4efc37 100644
--- a/sources/shiboken2/tests/libsample/functions.cpp
+++ b/sources/shiboken2/tests/libsample/functions.cpp
@@ -209,6 +209,15 @@ double sumDoubleArray(double array[4])
return std::accumulate(array, array + 4, double(0));
}
+ArrayModifyTest::ArrayModifyTest()
+{
+}
+
+int ArrayModifyTest::sumIntArray(int n, int *array)
+{
+ return std::accumulate(array, array + n, 0);
+}
+
ClassWithFunctionPointer::ClassWithFunctionPointer()
{
callFunctionPointer(0, &ClassWithFunctionPointer::doNothing);
diff --git a/sources/shiboken2/tests/libsample/functions.h b/sources/shiboken2/tests/libsample/functions.h
index 69d4cdceb..5289d7ce0 100644
--- a/sources/shiboken2/tests/libsample/functions.h
+++ b/sources/shiboken2/tests/libsample/functions.h
@@ -84,6 +84,13 @@ LIBSAMPLE_API OddBool acceptOddBoolReference(OddBool& x);
LIBSAMPLE_API int sumIntArray(int array[4]);
LIBSAMPLE_API double sumDoubleArray(double array[4]);
+class LIBSAMPLE_API ArrayModifyTest
+{
+public:
+ ArrayModifyTest();
+ int sumIntArray(int n, int *array);
+};
+
class LIBSAMPLE_API ClassWithFunctionPointer
{
public:
diff --git a/sources/shiboken2/tests/samplebinding/CMakeLists.txt b/sources/shiboken2/tests/samplebinding/CMakeLists.txt
index 1b97bd0e8..b3c9df0dd 100644
--- a/sources/shiboken2/tests/samplebinding/CMakeLists.txt
+++ b/sources/shiboken2/tests/samplebinding/CMakeLists.txt
@@ -7,6 +7,7 @@ ${CMAKE_CURRENT_SOURCE_DIR}/typesystem_sample.xml
set(sample_SRC
${CMAKE_CURRENT_BINARY_DIR}/sample/abstractmodifications_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/abstract_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/arraymodifytest_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/base1_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/base2_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/base3_wrapper.cpp
diff --git a/sources/shiboken2/tests/samplebinding/array_sequence_test.py b/sources/shiboken2/tests/samplebinding/array_sequence_test.py
index 3c6a23845..0fd2ec636 100644
--- a/sources/shiboken2/tests/samplebinding/array_sequence_test.py
+++ b/sources/shiboken2/tests/samplebinding/array_sequence_test.py
@@ -40,6 +40,11 @@ class ArrayTester(unittest.TestCase):
intList = [1, 2, 3, 4]
self.assertEqual(sample.sumIntArray(intList), 10)
+ def testIntArrayModified(self):
+ intList = [1, 2, 3, 4]
+ tester = sample.ArrayModifyTest()
+ self.assertEqual(tester.sumIntArray(4, intList), 10)
+
def testDoubleArray(self):
doubleList = [1.2, 2.3, 3.4, 4.5]
self.assertEqual(sample.sumDoubleArray(doubleList), 11.4)
diff --git a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
index 9db4a7928..32fbd8ced 100644
--- a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
+++ b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
@@ -508,6 +508,12 @@
<function signature="overloadedFunc(double)" />
<function signature="overloadedFunc(int)" />
+ <value-type name="ArrayModifyTest">
+ <modify-function signature="sumIntArray(int, int*)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ </value-type>
+
<value-type name="ClassWithFunctionPointer">
<suppress-warning text="skipping function 'ClassWithFunctionPointer::callFunctionPointer', unmatched parameter type 'void (*)(void*)'" />
</value-type>