diff options
author | Andrei Golubev <andrei.golubev@qt.io> | 2022-05-25 15:18:56 +0200 |
---|---|---|
committer | Andrei Golubev <andrei.golubev@qt.io> | 2022-06-02 10:07:40 +0200 |
commit | e5251efe97fd66431f8badeb3cdcb67586b2e015 (patch) | |
tree | f1e7d97f5fbdc49cd6b0e19b284ba1c7cdfb948f /tests | |
parent | 87053c5422bdaeb8bc0052bf818b31d1ae49c5a5 (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.qml | 15 | ||||
-rw-r--r-- | tests/auto/qml/qqmljsscope/tst_qqmljsscope.cpp | 43 |
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" |