aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/qml/v8/qv8qobjectwrapper.cpp6
-rw-r--r--src/qml/qml/v8/qv8sequencewrapper.cpp11
-rw-r--r--src/qml/qml/v8/qv8sequencewrapper_p.h2
-rw-r--r--tests/auto/qml/qqmlecmascript/data/sequenceConversion.copy.qml23
-rw-r--r--tests/auto/qml/qqmlecmascript/testtypes.cpp30
-rw-r--r--tests/auto/qml/qqmlecmascript/testtypes.h1
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp4
7 files changed, 52 insertions, 25 deletions
diff --git a/src/qml/qml/v8/qv8qobjectwrapper.cpp b/src/qml/qml/v8/qv8qobjectwrapper.cpp
index 5fce03aa0f..01ab252d7b 100644
--- a/src/qml/qml/v8/qv8qobjectwrapper.cpp
+++ b/src/qml/qml/v8/qv8qobjectwrapper.cpp
@@ -2160,13 +2160,17 @@ void CallArgument::fromValue(int callType, QV8Engine *engine, v8::Handle<v8::Val
type = -1;
QQmlEnginePrivate *ep = engine->engine() ? QQmlEnginePrivate::get(engine->engine()) : 0;
- QVariant v = engine->toVariant(value, -1);
+ QVariant v = engine->toVariant(value, -1); // why -1 instead of callType?
if (v.userType() == callType) {
*qvariantPtr = v;
} else if (v.canConvert(callType)) {
*qvariantPtr = v;
qvariantPtr->convert(callType);
+ } else if (engine->sequenceWrapper()->isSequenceType(callType) && v.userType() == qMetaTypeId<QVariantList>()) {
+ // convert the JS array to a sequence of the correct type.
+ QVariant seqV = engine->toVariant(value, callType);
+ *qvariantPtr = seqV;
} else {
QQmlMetaObject mo = ep ? ep->rawMetaObjectForType(callType) : QQmlMetaObject();
if (!mo.isNull()) {
diff --git a/src/qml/qml/v8/qv8sequencewrapper.cpp b/src/qml/qml/v8/qv8sequencewrapper.cpp
index c4b4e662f5..03aeb85d73 100644
--- a/src/qml/qml/v8/qv8sequencewrapper.cpp
+++ b/src/qml/qml/v8/qv8sequencewrapper.cpp
@@ -110,6 +110,17 @@ void QV8SequenceWrapper::destroy()
qPersistentDispose(m_constructor);
}
+#define IS_SEQUENCE(unused1, unused2, SequenceType, unused3) \
+ if (sequenceTypeId == qMetaTypeId<SequenceType>()) { \
+ return true; \
+ } else
+
+bool QV8SequenceWrapper::isSequenceType(int sequenceTypeId) const
+{
+ FOREACH_QML_SEQUENCE_TYPE(IS_SEQUENCE) { /* else */ return false; }
+}
+#undef IS_SEQUENCE
+
bool QV8SequenceWrapper::isEqual(QV8ObjectResource *lhs, QV8ObjectResource *rhs)
{
Q_ASSERT(lhs && rhs && lhs->resourceType() == QV8ObjectResource::SequenceType && rhs->resourceType() == QV8ObjectResource::SequenceType);
diff --git a/src/qml/qml/v8/qv8sequencewrapper_p.h b/src/qml/qml/v8/qv8sequencewrapper_p.h
index 141d6f4428..111cea9085 100644
--- a/src/qml/qml/v8/qv8sequencewrapper_p.h
+++ b/src/qml/qml/v8/qv8sequencewrapper_p.h
@@ -71,6 +71,8 @@ public:
void init(QV8Engine *);
void destroy();
+ bool isSequenceType(int sequenceTypeId) const;
+
bool isEqual(QV8ObjectResource *lhs, const QVariant &rhs);
bool isEqual(QV8ObjectResource *lhs, QV8ObjectResource *rhs);
quint32 sequenceLength(QV8ObjectResource *);
diff --git a/tests/auto/qml/qqmlecmascript/data/sequenceConversion.copy.qml b/tests/auto/qml/qqmlecmascript/data/sequenceConversion.copy.qml
index f6614dad0c..088e240ad4 100644
--- a/tests/auto/qml/qqmlecmascript/data/sequenceConversion.copy.qml
+++ b/tests/auto/qml/qqmlecmascript/data/sequenceConversion.copy.qml
@@ -157,4 +157,27 @@ Item {
if (jsIntList == jsIntList2) success = false;
if (jsIntList != jsIntList) success = false;
}
+
+ // this test ensures that copy resource sequences can be passed as parameters
+ function testCopyParameters() {
+ success = false;
+
+ var jsIntList = msco.generateIntSequence();
+ success = msco.parameterEqualsGeneratedIntSequence(jsIntList);
+ if (success == false) return;
+
+ // here we construct something which should be converted to a copy sequence automatically.
+ success = msco.parameterEqualsGeneratedIntSequence([1,2,3]);
+ }
+
+ // this test ensures that reference resource sequences are converted
+ // to copy resource sequences when passed as parameters.
+ function testReferenceParameters() {
+ success = false;
+
+ msco.intListProperty = msco.generateIntSequence();
+ var jsIntList = msco.intListProperty
+ success = msco.parameterEqualsGeneratedIntSequence(jsIntList);
+ if (success == false) return;
+ }
}
diff --git a/tests/auto/qml/qqmlecmascript/testtypes.cpp b/tests/auto/qml/qqmlecmascript/testtypes.cpp
index 9669e371de..a0bdbb6156 100644
--- a/tests/auto/qml/qqmlecmascript/testtypes.cpp
+++ b/tests/auto/qml/qqmlecmascript/testtypes.cpp
@@ -225,35 +225,17 @@ public:
{
return stringList;
}
- Q_INVOKABLE QList<int> integers(QVariant v) const
+ Q_INVOKABLE QList<int> integers(QList<int> v) const
{
- QList<int> intList;
- QList<QVariant> vList = v.toList();
- for (int i=0 ; i < vList.size() ; ++i) {
- int iv = vList[i].toInt();
- intList.append(iv);
- }
- return intList;
+ return v;
}
- Q_INVOKABLE QList<qreal> reals(QVariant v) const
+ Q_INVOKABLE QList<qreal> reals(QList<qreal> v) const
{
- QList<qreal> realList;
- QList<QVariant> vList = v.toList();
- for (int i=0 ; i < vList.size() ; ++i) {
- qreal fv = vList[i].toReal();
- realList.append(fv);
- }
- return realList;
+ return v;
}
- Q_INVOKABLE QList<bool> bools(QVariant v) const
+ Q_INVOKABLE QList<bool> bools(QList<bool> v) const
{
- QList<bool> boolList;
- QList<QVariant> vList = v.toList();
- for (int i=0 ; i < vList.size() ; ++i) {
- bool bv = vList[i].toBool();
- boolList.append(bv);
- }
- return boolList;
+ return v;
}
};
diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h
index c05405ab53..da6baa4e6c 100644
--- a/tests/auto/qml/qqmlecmascript/testtypes.h
+++ b/tests/auto/qml/qqmlecmascript/testtypes.h
@@ -1393,6 +1393,7 @@ public:
Q_INVOKABLE QList<QString> generateStringSequence() const { QList<QString> retn; retn << "one" << "two" << "three"; return retn; }
Q_INVOKABLE QList<QUrl> generateUrlSequence() const { QList<QUrl> retn; retn << QUrl("http://www.example1.com") << QUrl("http://www.example2.com") << QUrl("http://www.example3.com"); return retn; }
Q_INVOKABLE QStringList generateQStringSequence() const { QStringList retn; retn << "one" << "two" << "three"; return retn; }
+ Q_INVOKABLE bool parameterEqualsGeneratedIntSequence(const QList<int>& param) const { return (param == generateIntSequence()); }
// "reference resource" underlying qobject deletion test:
Q_INVOKABLE MySequenceConversionObject *generateTestObject() const { return new MySequenceConversionObject; }
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index 6fa6c3b49e..55b76f1d20 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -5569,6 +5569,10 @@ void tst_qqmlecmascript::sequenceConversionCopy()
QCOMPARE(object->property("success").toBool(), true);
QMetaObject::invokeMethod(object, "testEqualitySemantics");
QCOMPARE(object->property("success").toBool(), true);
+ QMetaObject::invokeMethod(object, "testCopyParameters");
+ QCOMPARE(object->property("success").toBool(), true);
+ QMetaObject::invokeMethod(object, "testReferenceParameters");
+ QCOMPARE(object->property("success").toBool(), true);
delete object;
}