From 95837745e4123a9ba49948daefcc0d87969d1cec Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 26 Apr 2022 10:34:31 +0200 Subject: [PATCH] QQmlTypeCompiler: Find implicit components for inline component roots Pick-to: 6.2 6.3 Fixes: QTBUG-102719 Change-Id: Ia6654f617d9d0922c94a5e204f9559e95c529641 Reviewed-by: Andrei Golubev Reviewed-by: Fabian Kosmale --- src/qml/qml/qqmltypecompiler.cpp | 28 +++++++++++-------- .../qml/qqmllanguage/data/componentMix.qml | 5 ++++ .../qml/qqmllanguage/tst_qqmllanguage.cpp | 5 ++++ 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/qml/qml/qqmltypecompiler.cpp b/src/qml/qml/qqmltypecompiler.cpp index 11498c0f37..57ab0c2314 100644 --- a/src/qml/qml/qqmltypecompiler.cpp +++ b/src/qml/qml/qqmltypecompiler.cpp @@ -876,7 +876,7 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents( } } -// resolve ignores everything relating to inline components +// Resolve ignores everything relating to inline components, except for implicit components. bool QQmlComponentAndAliasResolver::resolve(int root) { // Detect real Component {} objects as well as implicitly defined components, such as @@ -891,25 +891,31 @@ bool QQmlComponentAndAliasResolver::resolve(int root) = obj->flags & QV4::CompiledData::Object::IsInlineComponentRoot; const bool isPartOfInlineComponent = obj->flags & QV4::CompiledData::Object::IsPartOfInlineComponent; - if (root == 0) { - // normal component root, skip over anything inline component related - if (isInlineComponentRoot || isPartOfInlineComponent) - continue; - } else if (!isPartOfInlineComponent || isInlineComponentRoot) { - break; // left current inline component (potentially entered a new one) - } QQmlPropertyCache::ConstPtr cache = propertyCaches.at(i); - if (obj->inheritedTypeNameIndex == 0 && !cache) - continue; bool isExplicitComponent = false; - if (obj->inheritedTypeNameIndex) { auto *tref = resolvedType(obj->inheritedTypeNameIndex); Q_ASSERT(tref); if (tref->type().metaObject() == &QQmlComponent::staticMetaObject) isExplicitComponent = true; } + + if (root == 0) { + // normal component root, skip over anything inline component related + if (isInlineComponentRoot || isPartOfInlineComponent) + continue; + } else if (!isPartOfInlineComponent || isInlineComponentRoot) { + // We've left the current inline component (potentially entered a new one), + // but we still need to resolve implicit components which are part of inline components. + if (cache && !isExplicitComponent) + findAndRegisterImplicitComponents(obj, cache); + break; + } + + if (obj->inheritedTypeNameIndex == 0 && !cache) + continue; + if (!isExplicitComponent) { if (cache) findAndRegisterImplicitComponents(obj, cache); diff --git a/tests/auto/qml/qqmllanguage/data/componentMix.qml b/tests/auto/qml/qqmllanguage/data/componentMix.qml index d745ec5564..0edc997484 100644 --- a/tests/auto/qml/qqmllanguage/data/componentMix.qml +++ b/tests/auto/qml/qqmllanguage/data/componentMix.qml @@ -9,5 +9,10 @@ QtObject { property QtObject view: View { delegate: QtObject {} } } + component Delegated : View { + delegate: QtObject {} + } + property Things things: Things {} + property Delegated delegated: Delegated {} } diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 44d46d9963..f20cae7e59 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -6923,11 +6923,16 @@ void tst_qqmllanguage::componentMix() QVERIFY(!o.isNull()); QObject *things = qvariant_cast(o->property("things")); QVERIFY(things); + QObject *delegated = qvariant_cast(o->property("delegated")); + QVERIFY(delegated); QObject *view = qvariant_cast(things->property("view")); QVERIFY(view); QObject *delegate = qvariant_cast(view->property("delegate")); QVERIFY(delegate); QCOMPARE(delegate->metaObject(), &QQmlComponent::staticMetaObject); + QObject *delegate2 = qvariant_cast(delegated->property("delegate")); + QVERIFY(delegate2); + QCOMPARE(delegate2->metaObject(), &QQmlComponent::staticMetaObject); } QTEST_MAIN(tst_qqmllanguage)