Add QJSValue::call() overload
authorKent Hansen <kent.hansen@nokia.com>
Fri, 20 Jan 2012 07:00:27 +0000 (08:00 +0100)
committerQt by Nokia <qt-info@nokia.com>
Fri, 20 Jan 2012 22:35:18 +0000 (23:35 +0100)
This overload takes only an argument list, not a this-object, since
that is a very common way of calling stand-alone ("non-member")
functions. Now there is no longer a need to pass a dummy value for
the this-object.

Task-number: QTBUG-23604
Change-Id: Iae952d91fce5bcaa62a05b9978c15f32802da90a
Reviewed-by: Simon Hausmann <simon.hausmann@nokia.com>
Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@nokia.com>
src/declarative/qml/v8/qjsvalue.cpp
src/declarative/qml/v8/qjsvalue.h
tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp
tests/auto/declarative/qjsengine/tst_qjsengine.cpp
tests/auto/declarative/qjsvalue/tst_qjsvalue.cpp

index a43dd33..623e24b 100644 (file)
@@ -696,6 +696,28 @@ QVariant QJSValue::toVariant() const
     return d->toVariant();
 }
 
+/*!
+  Calls this QJSValue as a function, passing \a args as arguments
+  to the function, and using the globalObject() as the "this"-object.
+  Returns the value returned from the function.
+
+  If this QJSValue is not callable, call() does nothing and
+  returns an undefined QJSValue.
+
+  Calling call() can cause an exception to occur in the script engine;
+  in that case, call() returns the value that was thrown (typically an
+  \c{Error} object). You can call
+  QJSEngine::hasUncaughtException() to determine if an exception
+  occurred.
+
+  \sa isCallable()
+*/
+QJSValue QJSValue::call(const QJSValueList &args)
+{
+    Q_D(QJSValue);
+    QScriptIsolate api(d->engine());
+    return d->call(/*thisObject=*/0, args);
+}
 
 /*!
   Calls this QJSValue as a function, using \a thisObject as
index 8a15c4e..b9278c5 100644 (file)
@@ -141,6 +141,7 @@ public:
     QJSValue::PropertyFlags propertyFlags(const QString &name) const;
 
     bool isCallable() const;
+    QJSValue call(const QJSValueList &args);
     QJSValue call(const QJSValue &thisObject = QJSValue(),
                       const QJSValueList &args = QJSValueList());
     QJSValue construct(const QJSValueList &args = QJSValueList());
index 5d4f579..ccfdfdb 100644 (file)
@@ -127,7 +127,7 @@ static QJSValue readonly_script_api(QDeclarativeEngine *engine, QJSEngine *scrip
 
     // now freeze it so that it's read-only
     QJSValue freezeFunction = scriptEngine->evaluate("(function(obj) { return Object.freeze(obj); })");
-    v = freezeFunction.call(QJSValue(), (QJSValueList() << v));
+    v = freezeFunction.call(QJSValueList() << v);
 
     return v;
 }
index 7aa5bbc..13c5884 100644 (file)
@@ -830,15 +830,15 @@ void tst_QJSEngine::jsRegExp()
     QCOMPARE(r.toString(), QString::fromLatin1("/foo/gim"));
 
     QJSValue rxCtor = eng.globalObject().property("RegExp");
-    QJSValue r2 = rxCtor.call(QJSValue(), QJSValueList() << r);
+    QJSValue r2 = rxCtor.call(QJSValueList() << r);
     QVERIFY(r2.isRegExp());
     QVERIFY(r2.strictlyEquals(r));
 
-    QJSValue r3 = rxCtor.call(QJSValue(), QJSValueList() << r << "gim");
+    QJSValue r3 = rxCtor.call(QJSValueList() << r << "gim");
     QVERIFY(r3.isError());
     QVERIFY(r3.toString().contains(QString::fromLatin1("TypeError"))); // Cannot supply flags when constructing one RegExp from another
 
-    QJSValue r4 = rxCtor.call(QJSValue(), QJSValueList() << "foo" << "gim");
+    QJSValue r4 = rxCtor.call(QJSValueList() << "foo" << "gim");
     QVERIFY(r4.isRegExp());
 
     QJSValue r5 = rxCtor.construct(QJSValueList() << r);
@@ -1179,7 +1179,7 @@ static QScriptValue myConstructor(QScriptContext *ctx, QScriptEngine *eng)
 static QScriptValue instanceofJS(const QScriptValue &inst, const QScriptValue &ctor)
 {
     return inst.engine()->evaluate("(function(inst, ctor) { return inst instanceof ctor; })")
-        .call(QScriptValue(), QScriptValueList() << inst << ctor);
+        .call(QScriptValueList() << inst << ctor);
 }
 
 void tst_QJSEngine::newQMetaObject()
@@ -4343,7 +4343,7 @@ void tst_QJSEngine::jsFunctionDeclarationAsStatement()
     {
         QJSValue ret = eng.evaluate("foo('bar')");
         QVERIFY(ret.isCallable());
-        QJSValue ret2 = ret.call(QJSValue());
+        QJSValue ret2 = ret.call();
         QCOMPARE(ret2.toString(), QString::fromLatin1("bar"));
         QVERIFY(!eng.globalObject().property("bar").isValid());
         QVERIFY(!eng.globalObject().property("baz").isValid());
@@ -4351,7 +4351,7 @@ void tst_QJSEngine::jsFunctionDeclarationAsStatement()
     {
         QJSValue ret = eng.evaluate("foo('baz')");
         QVERIFY(ret.isCallable());
-        QJSValue ret2 = ret.call(QJSValue());
+        QJSValue ret2 = ret.call();
         QCOMPARE(ret2.toString(), QString::fromLatin1("baz"));
         QVERIFY(!eng.globalObject().property("bar").isValid());
         QVERIFY(!eng.globalObject().property("baz").isValid());
@@ -5459,7 +5459,7 @@ void tst_QJSEngine::translateScript_callQsTrFromCpp()
 
     // There is no context, but it shouldn't crash
     QCOMPARE(engine.globalObject().property("qsTr").call(
-             QScriptValue(), QScriptValueList() << "One").toString(), QString::fromLatin1("One"));
+             QScriptValueList() << "One").toString(), QString::fromLatin1("One"));
 }
 
 void tst_QJSEngine::translateWithInvalidArgs_data()
@@ -5769,7 +5769,7 @@ void tst_QJSEngine::nativeFunctionScopes()
     QScriptEngine eng;
     {
         QScriptValue fun = eng.newFunction(counter);
-        QScriptValue cnt = fun.call(QScriptValue(), QScriptValueList() << 123);
+        QScriptValue cnt = fun.call(QScriptValueList() << 123);
         QVERIFY(cnt.isCallable());
         {
             QScriptValue ret = cnt.call();
@@ -5780,7 +5780,7 @@ void tst_QJSEngine::nativeFunctionScopes()
     }
     {
         QScriptValue fun = eng.newFunction(counter_hybrid);
-        QScriptValue cnt = fun.call(QScriptValue(), QScriptValueList() << 123);
+        QScriptValue cnt = fun.call(QScriptValueList() << 123);
         QVERIFY(cnt.isCallable());
         {
             QScriptValue ret = cnt.call();
@@ -5941,7 +5941,7 @@ void tst_QJSEngine::evaluateProgram_executeLater()
     {
         QScriptValue fun = eng.newFunction(createProgram);
         QScriptProgram program = qscriptvalue_cast<QScriptProgram>(
-            fun.call(QScriptValue(), QScriptValueList() << "a + 1"));
+            fun.call(QScriptValueList() << "a + 1"));
         QVERIFY(!program.isNull());
         eng.globalObject().setProperty("a", QScriptValue());
         {
@@ -6092,7 +6092,7 @@ void tst_QJSEngine::qRegExpInport()
     QVERIFY(rexp.isCallable());
 
     QJSValue func = eng.evaluate("(function(string, regexp) { return string.match(regexp); })");
-    QJSValue result = func.call(QJSValue(),  QJSValueList() << string << rexp);
+    QJSValue result = func.call(QJSValueList() << string << rexp);
 
     rx.indexIn(string);
     for (int i = 0; i <= rx.captureCount(); i++)  {
index 7fd2eaa..48a65dc 100644 (file)
@@ -2985,7 +2985,7 @@ void tst_QJSValue::call_invalidArguments()
         {
             QJSValueList args;
             args << QJSValue();
-            QJSValue ret = fun.call(QJSValue(), args);
+            QJSValue ret = fun.call(args);
             QVERIFY(!eng.hasUncaughtException());
             QCOMPARE(ret.isValid(), true);
             QCOMPARE(ret.isUndefined(), true);
@@ -2996,7 +2996,7 @@ void tst_QJSValue::call_invalidArguments()
         {
             QJSValueList args;
             args << QJSValue();
-            QJSValue ret = fun.call(QJSValue(), args);
+            QJSValue ret = fun.call(args);
             QCOMPARE(ret.isValid(), true);
             QCOMPARE(ret.isUndefined(), true);
         }
@@ -3006,7 +3006,7 @@ void tst_QJSValue::call_invalidArguments()
         {
             QJSValueList args;
             args << QJSValue() << QJSValue();
-            QJSValue ret = fun.call(QJSValue(), args);
+            QJSValue ret = fun.call(args);
             QCOMPARE(ret.isValid(), true);
             QCOMPARE(ret.isNumber(), true);
             QCOMPARE(qIsNaN(ret.toNumber()), true);
@@ -3044,7 +3044,7 @@ void tst_QJSValue::call_twoEngines()
     QTest::ignoreMessage(QtWarningMsg, "QJSValue::call() failed: "
                          "cannot call function with argument created in "
                          "a different engine");
-    QCOMPARE(fun.call(QJSValue(), QJSValueList() << QJSValue(&eng, 123)).isValid(), false);
+    QCOMPARE(fun.call(QJSValueList() << QJSValue(&eng, 123)).isValid(), false);
     {
         QJSValue fun = eng.evaluate("Object");
         QVERIFY(fun.isCallable());
@@ -3053,7 +3053,7 @@ void tst_QJSValue::call_twoEngines()
         QJSValueList args;
         args << objectInDifferentEngine;
         QTest::ignoreMessage(QtWarningMsg, "QJSValue::call() failed: cannot call function with argument created in a different engine");
-        fun.call(QJSValue(), args);
+        fun.call(args);
     }
 }
 
@@ -3540,15 +3540,15 @@ void tst_QJSValue::equals()
     QJSValue compareFun = eng.evaluate("(function(a, b) { return a == b; })");
     QVERIFY(compareFun.isCallable());
     {
-        QJSValue ret = compareFun.call(QJSValue(), QJSValueList() << qobj1 << qobj2);
+        QJSValue ret = compareFun.call(QJSValueList() << qobj1 << qobj2);
         QVERIFY(ret.isBool());
-        ret = compareFun.call(QJSValue(), QJSValueList() << qobj1 << qobj3);
+        ret = compareFun.call(QJSValueList() << qobj1 << qobj3);
         QVERIFY(ret.isBool());
         QVERIFY(!ret.toBool());
-        ret = compareFun.call(QJSValue(), QJSValueList() << qobj1 << qobj4);
+        ret = compareFun.call(QJSValueList() << qobj1 << qobj4);
         QVERIFY(ret.isBool());
         QVERIFY(!ret.toBool());
-        ret = compareFun.call(QJSValue(), QJSValueList() << qobj1 << obj1);
+        ret = compareFun.call(QJSValueList() << qobj1 << obj1);
         QVERIFY(ret.isBool());
         QVERIFY(!ret.toBool());
     }