diff options
-rw-r--r-- | src/qml/compiler/qqmlirbuilder.cpp | 10 | ||||
-rw-r--r-- | tests/auto/qml/qmlcachegen/CMakeLists.txt | 2 | ||||
-rw-r--r-- | tests/auto/qml/qmlcachegen/data/scriptstring.qml | 9 | ||||
-rw-r--r-- | tests/auto/qml/qmlcachegen/scriptstringprops.h | 80 | ||||
-rw-r--r-- | tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp | 110 |
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" |