diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2023-01-12 10:06:35 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2023-01-17 21:58:32 +0100 |
commit | bda7b2a444562ca41ef54910163b74b034fab81c (patch) | |
tree | 56d4aa7dd9c61d99a217ddc3bad369e326b7618a /src | |
parent | 5bc63de8819448e7342f3cb0ac08af667ccc81e5 (diff) | |
download | qtdeclarative-bda7b2a444562ca41ef54910163b74b034fab81c.tar.gz |
QmlCompiler: Handle various date and time conversions correctly
We can coerce QDateTime, QDate and QTime into each other because they
would all be represented by a Date object in JavaScript. Furthermore we
can coerce them all to QString. Technically, we could also coerce
strings to all of them, but we don't want to because that is terrible.
Fixes: QTBUG-109380
Change-Id: I176bfb5b715a6a6750cb5918c44261fa23fb8832
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qmlcompiler/qqmljscodegenerator.cpp | 19 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljscompiler.cpp | 1 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljstyperesolver.cpp | 15 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljstyperesolver_p.h | 4 |
4 files changed, 39 insertions, 0 deletions
diff --git a/src/qmlcompiler/qqmljscodegenerator.cpp b/src/qmlcompiler/qqmljscodegenerator.cpp index 686338c1a6..8d8a7c9118 100644 --- a/src/qmlcompiler/qqmljscodegenerator.cpp +++ b/src/qmlcompiler/qqmljscodegenerator.cpp @@ -3100,6 +3100,25 @@ QString QQmlJSCodeGenerator::conversion(const QQmlJSScope::ConstPtr &from, return variable + u".toUtf8()"_s; } + for (const auto &originType : { + m_typeResolver->dateTimeType(), + m_typeResolver->dateType(), + m_typeResolver->timeType()}) { + if (m_typeResolver->equals(from, originType)) { + for (const auto &targetType : { + m_typeResolver->dateTimeType(), + m_typeResolver->dateType(), + m_typeResolver->timeType(), + m_typeResolver->stringType()}) { + if (m_typeResolver->equals(to, targetType)) { + return u"aotContext->engine->coerceValue<%1, %2>(%3)"_s.arg( + originType->internalName(), targetType->internalName(), variable); + } + } + break; + } + } + const auto retrieveFromPrimitive = [&]( const QQmlJSScope::ConstPtr &type, const QString &expression) -> QString { diff --git a/src/qmlcompiler/qqmljscompiler.cpp b/src/qmlcompiler/qqmljscompiler.cpp index 5ee7ec90b6..964c01c1a2 100644 --- a/src/qmlcompiler/qqmljscompiler.cpp +++ b/src/qmlcompiler/qqmljscompiler.cpp @@ -752,6 +752,7 @@ QQmlJSAotFunction QQmlJSAotCompiler::globalCode() const u"QtQml/qqmllist.h"_s, u"QtCore/qdatetime.h"_s, + u"QtCore/qtimezone.h"_s, u"QtCore/qobject.h"_s, u"QtCore/qstring.h"_s, u"QtCore/qstringlist.h"_s, diff --git a/src/qmlcompiler/qqmljstyperesolver.cpp b/src/qmlcompiler/qqmljstyperesolver.cpp index 6999a1e2a3..4495f9fce6 100644 --- a/src/qmlcompiler/qqmljstyperesolver.cpp +++ b/src/qmlcompiler/qqmljstyperesolver.cpp @@ -36,6 +36,8 @@ QQmlJSTypeResolver::QQmlJSTypeResolver(QQmlJSImporter *importer) m_byteArrayType = builtinTypes.type(u"QByteArray"_s).scope; m_urlType = builtinTypes.type(u"QUrl"_s).scope; m_dateTimeType = builtinTypes.type(u"QDateTime"_s).scope; + m_dateType = builtinTypes.type(u"QDate"_s).scope; + m_timeType = builtinTypes.type(u"QTime"_s).scope; m_variantListType = builtinTypes.type(u"QVariantList"_s).scope; m_varType = builtinTypes.type(u"QVariant"_s).scope; m_jsValueType = builtinTypes.type(u"QJSValue"_s).scope; @@ -710,6 +712,7 @@ QQmlJSScope::ConstPtr QQmlJSTypeResolver::genericType( if (isPrimitive(type) || equals(type, m_jsValueType) || equals(type, m_urlType) || equals(type, m_dateTimeType) + || equals(type, m_dateType) || equals(type, m_timeType) || equals(type, m_variantListType) || equals(type, m_varType) || equals(type, m_stringListType) || equals(type, m_emptyListType) || equals(type, m_byteArrayType)) { @@ -948,6 +951,18 @@ bool QQmlJSTypeResolver::canPrimitivelyConvertFromTo( if (equals(from, m_stringType) && equals(to, m_dateTimeType)) return true; + for (const auto &originType : {m_dateTimeType, m_dateType, m_timeType}) { + if (!equals(from, originType)) + continue; + + for (const auto &targetType : {m_dateTimeType, m_dateType, m_timeType, m_stringType}) { + if (equals(to, targetType)) + return true; + } + + break;; + } + if (equals(from, m_nullType) && to->accessSemantics() == QQmlJSScope::AccessSemantics::Reference) { return true; diff --git a/src/qmlcompiler/qqmljstyperesolver_p.h b/src/qmlcompiler/qqmljstyperesolver_p.h index 12063075bc..453e06ac52 100644 --- a/src/qmlcompiler/qqmljstyperesolver_p.h +++ b/src/qmlcompiler/qqmljstyperesolver_p.h @@ -53,6 +53,8 @@ public: QQmlJSScope::ConstPtr byteArrayType() const { return m_byteArrayType; } QQmlJSScope::ConstPtr urlType() const { return m_urlType; } QQmlJSScope::ConstPtr dateTimeType() const { return m_dateTimeType; } + QQmlJSScope::ConstPtr dateType() const { return m_dateType; } + QQmlJSScope::ConstPtr timeType() const { return m_timeType; } QQmlJSScope::ConstPtr variantListType() const { return m_variantListType; } QQmlJSScope::ConstPtr varType() const { return m_varType; } QQmlJSScope::ConstPtr jsValueType() const { return m_jsValueType; } @@ -195,6 +197,8 @@ protected: QQmlJSScope::ConstPtr m_byteArrayType; QQmlJSScope::ConstPtr m_urlType; QQmlJSScope::ConstPtr m_dateTimeType; + QQmlJSScope::ConstPtr m_dateType; + QQmlJSScope::ConstPtr m_timeType; QQmlJSScope::ConstPtr m_variantListType; QQmlJSScope::ConstPtr m_varType; QQmlJSScope::ConstPtr m_jsValueType; |