aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSami Shalayel <[email protected]>2025-09-03 10:42:24 +0200
committerSami Shalayel <[email protected]>2025-09-10 11:56:48 +0200
commitaef089a81d83b883470036cc510949249d64aeb6 (patch)
treec9c8b7dcf0fc484169ee0e01618657e77108a9fe
parent7232c76aebc2875a19d7caa1abad7343458fb1fa (diff)
QQmlCodeModel: populate files after loading them
Populate the QML file after loading it, to avoid crashes later on. UpdateItemInSnapshot would write the DomItem of the qml file inside the snapshot, and then populate the lazy parts of the qml file while checking whether the file should be added to the valid snapshot too. This leaves the snapshot in an invalid state where the main thread responding to requests might access and use the only-partially-populated snapshot and crash, for example in the case of the document symbols that expect the Qml file to not be empty. Therefore, make sure that the qml file is populated by the qml file loading thread before writing it inside the snapshot. Note that addFileWatches() populates the file, so the crashes only happened when the CMake feature is disabled. Add a test to make sure that we don't load unpopulated files when the CMake feature is disabled. Task-number: QTBUG-119163 Change-Id: I6e73420f750e873898b7b426fe333edaf4d6a7c0 Reviewed-by: Ulf Hermann <[email protected]>
-rw-r--r--src/qmlls/qqmlcodemodel.cpp4
-rw-r--r--tests/auto/qmlls/qqmlcodemodel/tst_qmlls_qqmlcodemodel.cpp14
-rw-r--r--tests/auto/qmlls/qqmlcodemodel/tst_qmlls_qqmlcodemodel.h1
3 files changed, 19 insertions, 0 deletions
diff --git a/src/qmlls/qqmlcodemodel.cpp b/src/qmlls/qqmlcodemodel.cpp
index 82182f5ec7..2c7b531254 100644
--- a/src/qmlls/qqmlcodemodel.cpp
+++ b/src/qmlls/qqmlcodemodel.cpp
@@ -565,6 +565,10 @@ void QQmlCodeModel::newDocForOpenFile(const QByteArray &url, int version, const
[&p, this](Path, const DomItem &, const DomItem &newValue) {
const DomItem file = newValue.fileObject();
p = file.canonicalPath();
+ // Force population of the file by accessing isValid field. We
+ // don't want to populate the file after adding the file to the
+ // snapshot in updateItemInSnapshot.
+ file.field(Fields::isValid);
if (cmakeStatus() == HasCMake)
addFileWatches(file);
});
diff --git a/tests/auto/qmlls/qqmlcodemodel/tst_qmlls_qqmlcodemodel.cpp b/tests/auto/qmlls/qqmlcodemodel/tst_qmlls_qqmlcodemodel.cpp
index a1c18ddcb2..3150d1f02f 100644
--- a/tests/auto/qmlls/qqmlcodemodel/tst_qmlls_qqmlcodemodel.cpp
+++ b/tests/auto/qmlls/qqmlcodemodel/tst_qmlls_qqmlcodemodel.cpp
@@ -165,10 +165,24 @@ QString tst_qmlls_qqmlcodemodel::readFile(const QString &filename) const
return f.readAll();
}
+void tst_qmlls_qqmlcodemodel::openFiles_data()
+{
+ QTest::addColumn<bool>("cmakeEnabled");
+
+ QTest::addRow("withCMake") << true;
+ QTest::addRow("withoutCMake") << false;
+}
+
void tst_qmlls_qqmlcodemodel::openFiles()
{
+ QFETCH(bool, cmakeEnabled);
+
QmlLsp::QQmlCodeModel model;
+ // disabling CMake should not make the test fail!
+ if (!cmakeEnabled)
+ model.disableCMakeCalls();
+
const QByteArray fileAUrl = testFileUrl(u"FileA.qml"_s).toEncoded();
const QString fileAPath = testFile(u"FileA.qml"_s);
diff --git a/tests/auto/qmlls/qqmlcodemodel/tst_qmlls_qqmlcodemodel.h b/tests/auto/qmlls/qqmlcodemodel/tst_qmlls_qqmlcodemodel.h
index 6f3865d98d..80ad61ed57 100644
--- a/tests/auto/qmlls/qqmlcodemodel/tst_qmlls_qqmlcodemodel.h
+++ b/tests/auto/qmlls/qqmlcodemodel/tst_qmlls_qqmlcodemodel.h
@@ -31,6 +31,7 @@ private slots:
void fileNamesToWatch();
void findFilePathsFromFileNames_data();
void findFilePathsFromFileNames();
+ void openFiles_data();
void openFiles();
void importPathViaSettings();
void reloadLotsOfFiles();