aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp10
-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
5 files changed, 210 insertions, 1 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index 2dbf288cd3..29cb8e33d7 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -1172,7 +1172,15 @@ void IRBuilder::setBindingValue(QV4::CompiledData::Binding *binding, QQmlJS::AST
binding->value.compiledScriptIndex = index;
// We don't need to store the binding script as string, except for script strings
// and types with custom parsers. Those will be added later in the compilation phase.
- binding->stringIndex = emptyStringIndex;
+ // Except that we cannot recover the string when cachegen runs; we need to therefore retain
+ // "undefined". Any other "special" strings (for the various literals) are already handled above
+ QQmlJS::AST::Node *nodeForString = statement;
+ if (exprStmt)
+ nodeForString = exprStmt->expression;
+ if (asStringRef(nodeForString) == u"undefined")
+ binding->stringIndex = registerString(u"undefined"_qs);
+ else
+ binding->stringIndex = emptyStringIndex;
}
}
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"