diff options
-rw-r--r-- | src/qml/qml/v8/qv8qobjectwrapper.cpp | 6 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8sequencewrapper.cpp | 11 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8sequencewrapper_p.h | 2 | ||||
-rw-r--r-- | tests/auto/qml/qqmlecmascript/data/sequenceConversion.copy.qml | 23 | ||||
-rw-r--r-- | tests/auto/qml/qqmlecmascript/testtypes.cpp | 30 | ||||
-rw-r--r-- | tests/auto/qml/qqmlecmascript/testtypes.h | 1 | ||||
-rw-r--r-- | tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 4 |
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; } |