aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/qml/qqmlcomponent.cpp13
-rw-r--r--tests/auto/qml/qqmlcomponent/CMakeLists.txt2
-rw-r--r--tests/auto/qml/qqmlcomponent/lifecyclewatcher.h24
-rw-r--r--tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp31
4 files changed, 69 insertions, 1 deletions
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 1b6bac5d0e..73e523fec6 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -1092,8 +1092,15 @@ QObject *QQmlComponentPrivate::beginCreate(QQmlRefPointer<QQmlContextData> conte
state.appendCreatorErrors();
enginePriv->dereferenceScarceResources();
} else {
+ // TODO: extract into function
rv = loadedType.createWithQQmlData();
QQmlPropertyCache::ConstPtr propertyCache = QQmlData::ensurePropertyCache(rv);
+ QQmlParserStatus *parserStatus = nullptr;
+ const int parserStatusCast = loadedType.parserStatusCast();
+ if (parserStatusCast != -1) {
+ parserStatus = reinterpret_cast<QQmlParserStatus*>(reinterpret_cast<char *>(rv) + parserStatusCast);
+ parserStatus->classBegin();
+ }
for (int i = 0, propertyCount = propertyCache->propertyCount(); i < propertyCount; ++i) {
if (const QQmlPropertyData *propertyData = propertyCache->property(i); propertyData->isRequired()) {
state.ensureRequiredPropertyStorage();
@@ -1102,6 +1109,12 @@ QObject *QQmlComponentPrivate::beginCreate(QQmlRefPointer<QQmlContextData> conte
state.addPendingRequiredProperty(rv, propertyData, info);
}
}
+ if (parserStatus)
+ parserStatus->componentComplete();
+ if (const int finalizerCast = loadedType.finalizerCast(); finalizerCast != -1) {
+ auto* hook = reinterpret_cast<QQmlFinalizerHook *>(reinterpret_cast<char *>(rv) + finalizerCast);
+ hook->componentFinalized();
+ }
}
if (rv) {
diff --git a/tests/auto/qml/qqmlcomponent/CMakeLists.txt b/tests/auto/qml/qqmlcomponent/CMakeLists.txt
index 771d81709d..874c7f0cc3 100644
--- a/tests/auto/qml/qqmlcomponent/CMakeLists.txt
+++ b/tests/auto/qml/qqmlcomponent/CMakeLists.txt
@@ -46,6 +46,8 @@ qt_policy(SET QTP0001 NEW)
qt_add_qml_module(
tst_qqmlcomponent
+ SOURCES
+ lifecyclewatcher.h
URI test
QML_FILES
"data/TestComponentWithIC.qml"
diff --git a/tests/auto/qml/qqmlcomponent/lifecyclewatcher.h b/tests/auto/qml/qqmlcomponent/lifecyclewatcher.h
new file mode 100644
index 0000000000..738fd86942
--- /dev/null
+++ b/tests/auto/qml/qqmlcomponent/lifecyclewatcher.h
@@ -0,0 +1,24 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef LIFECYCLEWATCHER_H
+#define LIFECYCLEWATCHER_H
+
+#include <QtQml/qqmlparserstatus.h>
+#include <private/qqmlfinalizer_p.h>
+#include <QtCore/qobject.h>
+#include <QtQml/qqml.h>
+
+class LifeCycleWatcher : public QObject, public QQmlParserStatus, public QQmlFinalizerHook
+{
+ Q_OBJECT
+ QML_ELEMENT
+ Q_INTERFACES(QQmlParserStatus)
+ Q_INTERFACES(QQmlFinalizerHook)
+public:
+ void classBegin() override {states.push_back(1); }
+ void componentComplete() override {states.push_back(2);};
+ void componentFinalized() override { states.push_back(3); }
+ QList<int> states;
+};
+#endif
diff --git a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp
index d8dbf0ede7..31dcea25b7 100644
--- a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp
+++ b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp
@@ -21,7 +21,7 @@
#include <private/qv4executablecompilationunit_p.h>
#include <qcolor.h>
#include <qsignalspy.h>
-
+#include "lifecyclewatcher.h"
#include <algorithm>
using namespace Qt::StringLiterals;
@@ -133,6 +133,7 @@ private slots:
void boundComponent();
void loadFromModule_data();
void loadFromModule();
+ void loadFromModuleLifecycle();
void loadFromModuleThenCreateWithIncubator();
void loadFromModuleFailures_data();
void loadFromModuleFailures();
@@ -1345,6 +1346,34 @@ void tst_qqmlcomponent::loadFromModule()
name);
}
+void tst_qqmlcomponent::loadFromModuleLifecycle()
+{
+ QQmlEngine engine;
+ QList<int> loadFromModuleOrder;
+ QList<int> plainLoadOrder;
+ const QList<int> expected {1, 2, 3};
+ {
+ QQmlComponent component(&engine);
+ component.loadFromModule("test", "LifeCycleWatcher");
+ QVERIFY2(component.isReady(), qPrintable(component.errorString()));
+ std::unique_ptr<QObject> root{ component.create() };
+ LifeCycleWatcher *watcher = qobject_cast<LifeCycleWatcher *>(root.get());
+ QVERIFY(watcher);
+ loadFromModuleOrder = watcher->states;
+ QCOMPARE(loadFromModuleOrder, expected);
+ }
+ {
+ QQmlComponent component(&engine);
+ component.setData("import test; LifeCycleWatcher {}", {});
+ QVERIFY2(component.isReady(), qPrintable(component.errorString()));
+ std::unique_ptr<QObject> root{ component.create() };
+ LifeCycleWatcher *watcher = qobject_cast<LifeCycleWatcher *>(root.get());
+ QVERIFY(watcher);
+ plainLoadOrder = watcher->states;
+ }
+ QCOMPARE(loadFromModuleOrder, plainLoadOrder);
+}
+
struct CallVerifyingIncubtor : QQmlIncubator
{
void setInitialState(QObject *) override { setInitialStateCalled = true; }