aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2021-09-23 11:56:43 +0200
committerUlf Hermann <ulf.hermann@qt.io>2021-09-29 13:39:41 +0200
commitb3fe31a0ff129bb87f81901f2f50c0041b8f4a80 (patch)
tree14c79359f968ab8918eb805e73ab693c5330a3ab /tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
parent6fa72b1fb78267633812d56d1bcda76e327025c9 (diff)
Fix scoping of JavaScript function names
Function declarations add their name to the outer scope, but not the inner scope. Function expressions add their name to the inner scope, unless the name is actually picked from the outer scope rather than given after the function token. We don't add the name to any scope in the case of functions declared in QML elements because the QML element will receive the function as appropriately named, and typed, property. It is always better to use that one than to use a JavaScript local. This causes some additional ecmascript tests to pass. Pick-to: 6.2 Fixes: QTBUG-96625 Change-Id: I0b8ee98917d102a99fb6b9bd918037c71867a4a5 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp')
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp76
1 files changed, 76 insertions, 0 deletions
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index f42086ea9f..83d7a5ee03 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -424,6 +424,8 @@ private slots:
void optionalChainNull();
void asCast();
+ void functionNameInFunctionScope();
+
private:
// static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter);
static void verifyContextLifetime(const QQmlRefPointer<QQmlContextData> &ctxt);
@@ -9874,6 +9876,80 @@ void tst_qqmlecmascript::asCast()
QCOMPARE(qvariant_cast<QObject *>(root->property("rectangleAsRectangle")), rectangle);
}
+void tst_qqmlecmascript::functionNameInFunctionScope()
+{
+ QJSEngine engine;
+ QJSValue result = engine.evaluate(R"(
+ var a = {};
+ var foo = function foo() {
+ return foo;
+ }
+ a.foo = foo();
+
+ function bar() {
+ bar = 2;
+ }
+ bar()
+ a.bar = bar;
+
+ var baz = function baz() {
+ baz = 3;
+ }
+ baz()
+ a.baz = baz;
+
+ var foo2 = function() {
+ return foo2;
+ }
+ a.foo2 = foo2();
+
+ var baz2 = function() {
+ baz2 = 3;
+ }
+ baz2()
+ a.baz2 = baz2;
+ a
+
+ )");
+
+ QVERIFY(!result.isError());
+ const QJSManagedValue m(result, &engine);
+
+ QVERIFY(m.property("foo").isCallable());
+ QCOMPARE(m.property("bar").toInt(), 2);
+ QVERIFY(m.property("baz").isCallable());
+ QVERIFY(m.property("foo2").isCallable());
+ QCOMPARE(m.property("baz2").toInt(), 3);
+
+ const QJSValue getterInClass = engine.evaluate(R"(
+ class Tester {
+ constructor () {
+ this.a = 1;
+ this.b = 1;
+ }
+
+ get sum() {
+ const sum = this.a + this.b;
+ return sum;
+ }
+ }
+ )");
+
+ QVERIFY(!getterInClass.isError());
+
+ const QJSValue innerName = engine.evaluate(R"(
+ const a = 2;
+ var b = function a() { return a };
+ ({a: a, b: b, c: b()})
+ )");
+
+ QVERIFY(!innerName.isError());
+ const QJSManagedValue m2(innerName, &engine);
+ QCOMPARE(m2.property("a").toInt(), 2);
+ QVERIFY(m2.property("b").isCallable());
+ QVERIFY(m2.property("c").isCallable());
+}
+
QTEST_MAIN(tst_qqmlecmascript)
#include "tst_qqmlecmascript.moc"