aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml/qmlcachegen
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2021-07-26 15:25:08 +0200
committerFabian Kosmale <fabian.kosmale@qt.io>2021-08-09 16:53:44 +0200
commitdd86881520dde6c1487e5397f10b82584e6b9eaa (patch)
tree6cbcb2685eeded05b2068d5177db9d6a25b3522d /tests/auto/qml/qmlcachegen
parent35f948a1add8a46d85c6383971e9ebff3e0dada7 (diff)
QQmlIRBuilder: Always preserve "undefined" string
QQmlIRBuilder skips storing binding scripts as a string to save memory. However, for QQmlScriptString, we need the string to be available. This is solved by running QQmlScriptStringScanner in the type compiler at runtime, which sets the correct stringIndex for script string bindings. However, that one does not run when we already have a compilation unit from cachegen (and if we would run it unconditionally, we still would miss the source code to recover the string). We work around this issue by noting that QQmlScriptString only cares about a very limited set of strings: Namely the various literals and undefined. The literals are already correctly handled, as IRBuilder has specific optimizations for them anyway. We now check in the generic case whether the bindings string equals "undefined", and if so, ensure that the string is registered. Fixes: QTBUG-91165 Pick-to: 6.2 Change-Id: I4c4696952a082d1e69e0c9e5a0b9bf2470d59187 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Diffstat (limited to 'tests/auto/qml/qmlcachegen')
-rw-r--r--tests/auto/qml/qmlcachegen/CMakeLists.txt2
-rw-r--r--tests/auto/qml/qmlcachegen/data/scriptstring.qml9
-rw-r--r--tests/auto/qml/qmlcachegen/scriptstringprops.h80
-rw-r--r--tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp110
4 files changed, 201 insertions, 0 deletions
diff --git a/tests/auto/qml/qmlcachegen/CMakeLists.txt b/tests/auto/qml/qmlcachegen/CMakeLists.txt
index b32441dc4f..53cd86404d 100644
--- a/tests/auto/qml/qmlcachegen/CMakeLists.txt
+++ b/tests/auto/qml/qmlcachegen/CMakeLists.txt
@@ -14,6 +14,7 @@ qt_internal_add_test(tst_qmlcachegen
SOURCES
../../shared/util.cpp ../../shared/util.h
tst_qmlcachegen.cpp
+ scriptstringprops.h
INCLUDE_DIRECTORIES
../../shared
PUBLIC_LIBRARIES
@@ -101,6 +102,7 @@ set(qmake_immediate_qml_files
"data/script.mjs"
"data/utils.mjs"
"data/versionchecks.qml"
+ "data/scriptstring.qml"
)
qt6_target_qml_sources(tst_qmlcachegen
diff --git a/tests/auto/qml/qmlcachegen/data/scriptstring.qml b/tests/auto/qml/qmlcachegen/data/scriptstring.qml
new file mode 100644
index 0000000000..64c73ccdbc
--- /dev/null
+++ b/tests/auto/qml/qmlcachegen/data/scriptstring.qml
@@ -0,0 +1,9 @@
+import cachegentest
+
+ScriptStringProps {
+ undef: undefined
+ nul: null
+ str: "hello"
+ num: 42
+ bol: true
+}
diff --git a/tests/auto/qml/qmlcachegen/scriptstringprops.h b/tests/auto/qml/qmlcachegen/scriptstringprops.h
new file mode 100644
index 0000000000..e471da92b5
--- /dev/null
+++ b/tests/auto/qml/qmlcachegen/scriptstringprops.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef SCRIPT_STRING_PROPS_H
+#define SCRIPT_STRING_PROPS_H
+
+#include <QObject>
+#include <QQmlScriptString>
+#include <qqml.h>
+
+class ScriptStringProps :public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+
+ Q_PROPERTY(QQmlScriptString undef READ undef WRITE setUndef NOTIFY undefChanged)
+ Q_PROPERTY(QQmlScriptString nul READ nul WRITE setNul NOTIFY nulChanged)
+ Q_PROPERTY(QQmlScriptString str READ str WRITE setStr NOTIFY strChanged)
+ Q_PROPERTY(QQmlScriptString num READ num WRITE setNum NOTIFY numChanged)
+ Q_PROPERTY(QQmlScriptString bol READ bol WRITE setBol NOTIFY bolChanged)
+
+public:
+ const QQmlScriptString &undef() const;
+ void setUndef(const QQmlScriptString &newUndef);
+
+ const QQmlScriptString &nul() const;
+ void setNul(const QQmlScriptString &newNul);
+
+ const QQmlScriptString &str() const;
+ void setStr(const QQmlScriptString &newStr);
+
+ const QQmlScriptString &num() const;
+ void setNum(const QQmlScriptString &newNum);
+
+ const QQmlScriptString &bol() const;
+ void setBol(const QQmlScriptString &newBol);
+signals:
+ void undefChanged();
+
+ void nulChanged();
+
+ void strChanged();
+
+ void numChanged();
+
+ void bolChanged();
+
+public:
+ QQmlScriptString m_undef;
+ QQmlScriptString m_nul;
+ QQmlScriptString m_str;
+ QQmlScriptString m_num;
+ QQmlScriptString m_bol;
+};
+
+#endif
diff --git a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
index 8fdfecb379..51faab982c 100644
--- a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
+++ b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
@@ -38,8 +38,11 @@
#include <private/qqmlcomponent_p.h>
#include <private/qqmlscriptdata_p.h>
#include <qtranslator.h>
+#include <qqmlscriptstring.h>
+#include <QString>
#include "../../shared/util.h"
+#include "scriptstringprops.h"
class tst_qmlcachegen: public QQmlDataTest
{
@@ -78,6 +81,8 @@ private slots:
void parameterAdjustment();
void inlineComponent();
void posthocRequired();
+
+ void scriptStringCachegenInteraction();
};
// A wrapper around QQmlComponent to ensure the temporary reference counts
@@ -718,6 +723,111 @@ void tst_qmlcachegen::posthocRequired()
QVERIFY(component.errorString().contains(QStringLiteral("Required property x was not initialized")));
}
+void tst_qmlcachegen::scriptStringCachegenInteraction()
+{
+ bool ok = generateCache(testFile("scriptstring.qml"));
+ QVERIFY(ok);
+ QQmlEngine engine;
+ CleanlyLoadingComponent component(&engine, testFileUrl("scriptstring.qml"));
+ QScopedPointer<QObject> root(component.create());
+ QVERIFY2(!root.isNull(), qPrintable(component.errorString()));
+ auto scripty = qobject_cast<ScriptStringProps *>(root.get());
+ QVERIFY(scripty);
+
+ QVERIFY(scripty->m_undef.isUndefinedLiteral());
+ QVERIFY(scripty->m_nul.isNullLiteral());
+ QCOMPARE(scripty->m_str.stringLiteral(), u"hello"_qs);
+ QCOMPARE(scripty->m_num.numberLiteral(&ok), 42);
+ ok = false;
+ scripty->m_bol.booleanLiteral(&ok);
+ QVERIFY(ok);
+}
+
+
+
+const QQmlScriptString &ScriptStringProps::undef() const
+{
+ return m_undef;
+}
+
+
+
+void ScriptStringProps::setUndef(const QQmlScriptString &newUndef)
+{
+ if (m_undef == newUndef)
+ return;
+ m_undef = newUndef;
+ emit undefChanged();
+}
+
+
+
+const QQmlScriptString &ScriptStringProps::nul() const
+{
+ return m_nul;
+}
+
+
+
+void ScriptStringProps::setNul(const QQmlScriptString &newNul)
+{
+ if (m_nul == newNul)
+ return;
+ m_nul = newNul;
+ emit nulChanged();
+}
+
+
+
+const QQmlScriptString &ScriptStringProps::str() const
+{
+ return m_str;
+}
+
+
+
+void ScriptStringProps::setStr(const QQmlScriptString &newStr)
+{
+ if (m_str == newStr)
+ return;
+ m_str = newStr;
+ emit strChanged();
+}
+
+
+
+const QQmlScriptString &ScriptStringProps::num() const
+{
+ return m_num;
+}
+
+
+
+void ScriptStringProps::setNum(const QQmlScriptString &newNum)
+{
+ if (m_num == newNum)
+ return;
+ m_num = newNum;
+ emit numChanged();
+}
+
+
+
+const QQmlScriptString &ScriptStringProps::bol() const
+{
+ return m_bol;
+}
+
+
+
+void ScriptStringProps::setBol(const QQmlScriptString &newBol)
+{
+ if (m_bol == newBol)
+ return;
+ m_bol = newBol;
+ emit bolChanged();
+}
+
QTEST_GUILESS_MAIN(tst_qmlcachegen)
#include "tst_qmlcachegen.moc"