aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorAndrei Golubev <andrei.golubev@qt.io>2022-05-25 15:18:56 +0200
committerAndrei Golubev <andrei.golubev@qt.io>2022-06-02 10:07:40 +0200
commite5251efe97fd66431f8badeb3cdcb67586b2e015 (patch)
treef1e7d97f5fbdc49cd6b0e19b284ba1c7cdfb948f /tests
parent87053c5422bdaeb8bc0052bf818b31d1ae49c5a5 (diff)
Set bindings on QQmlJSScope after AST traversal
We can get into situations when binding creation is problematic due to the relevant scopes being yet unresolved. In particular, this happens when processing attached/group properties script bindings Avoid having this situation by postponing the actual binding setting until after the relavant scopes are resolved (mainly, the binding owner). However, do relevant AST order dependent operations beforehand to avoid accidental errors This commit amends 25098b7a4fdb8920874a817956f659e6393548d2 Fixes: QTBUG-103897 Change-Id: I671955dbe321d03e5f1ab9891cc79dc0a936deda Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/qml/qqmljsscope/data/resolvedNonUniqueScope.qml15
-rw-r--r--tests/auto/qml/qqmljsscope/tst_qqmljsscope.cpp43
2 files changed, 58 insertions, 0 deletions
diff --git a/tests/auto/qml/qqmljsscope/data/resolvedNonUniqueScope.qml b/tests/auto/qml/qqmljsscope/data/resolvedNonUniqueScope.qml
new file mode 100644
index 0000000000..dfe103c881
--- /dev/null
+++ b/tests/auto/qml/qqmljsscope/data/resolvedNonUniqueScope.qml
@@ -0,0 +1,15 @@
+import QtQuick
+
+Item {
+ Component.onCompleted: {} // `Component` must be resolved
+ Component.onDestruction: {}
+
+ property IC p
+ p.onXChanged: {
+ console.log("hooray");
+ }
+
+ component IC : Text {
+ property string x
+ }
+}
diff --git a/tests/auto/qml/qqmljsscope/tst_qqmljsscope.cpp b/tests/auto/qml/qqmljsscope/tst_qqmljsscope.cpp
index e50afcda99..0686fd22ac 100644
--- a/tests/auto/qml/qqmljsscope/tst_qqmljsscope.cpp
+++ b/tests/auto/qml/qqmljsscope/tst_qqmljsscope.cpp
@@ -131,6 +131,7 @@ private Q_SLOTS:
void extensions();
void emptyBlockBinding();
void qualifiedName();
+ void resolvedNonUniqueScopes();
public:
tst_qqmljsscope()
@@ -702,5 +703,47 @@ void tst_qqmljsscope::qualifiedName()
QCOMPARE(qualifiedImportTimerInItemInComponent->baseType()->moduleName(), "QtQml");
}
+void tst_qqmljsscope::resolvedNonUniqueScopes()
+{
+ QQmlJSScope::ConstPtr root = run(u"resolvedNonUniqueScope.qml"_s);
+ QVERIFY(root);
+
+ const auto value = [](const QMultiHash<QString, QQmlJSMetaPropertyBinding> &bindings,
+ const QString &key) {
+ return bindings.value(key, QQmlJSMetaPropertyBinding(QQmlJS::SourceLocation {}));
+ };
+
+ {
+ auto topLevelBindings = root->propertyBindings(u"Component"_s);
+ QCOMPARE(topLevelBindings.size(), 1);
+ QCOMPARE(topLevelBindings[0].bindingType(), QQmlJSMetaPropertyBinding::AttachedProperty);
+ auto componentScope = topLevelBindings[0].attachingType();
+ auto componentBindings = componentScope->ownPropertyBindings();
+ QCOMPARE(componentBindings.size(), 2);
+ auto onCompletedBinding = value(componentBindings, u"onCompleted"_s);
+ QVERIFY(onCompletedBinding.isValid());
+ QCOMPARE(onCompletedBinding.bindingType(), QQmlJSMetaPropertyBinding::Script);
+ QCOMPARE(onCompletedBinding.scriptKind(), QQmlJSMetaPropertyBinding::Script_SignalHandler);
+ auto onDestructionBinding = value(componentBindings, u"onDestruction"_s);
+ QVERIFY(onDestructionBinding.isValid());
+ QCOMPARE(onDestructionBinding.bindingType(), QQmlJSMetaPropertyBinding::Script);
+ QCOMPARE(onDestructionBinding.scriptKind(),
+ QQmlJSMetaPropertyBinding::Script_SignalHandler);
+ }
+
+ {
+ auto topLevelBindings = root->propertyBindings(u"p"_s);
+ QCOMPARE(topLevelBindings.size(), 1);
+ QCOMPARE(topLevelBindings[0].bindingType(), QQmlJSMetaPropertyBinding::GroupProperty);
+ auto pScope = topLevelBindings[0].groupType();
+ auto pBindings = pScope->ownPropertyBindings();
+ QCOMPARE(pBindings.size(), 1);
+ auto onXChangedBinding = value(pBindings, u"onXChanged"_s);
+ QVERIFY(onXChangedBinding.isValid());
+ QCOMPARE(onXChangedBinding.bindingType(), QQmlJSMetaPropertyBinding::Script);
+ QCOMPARE(onXChangedBinding.scriptKind(), QQmlJSMetaPropertyBinding::Script_SignalHandler);
+ }
+}
+
QTEST_MAIN(tst_qqmljsscope)
#include "tst_qqmljsscope.moc"