summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2023-01-12 10:06:35 +0100
committerUlf Hermann <ulf.hermann@qt.io>2023-01-17 21:58:32 +0100
commitbda7b2a444562ca41ef54910163b74b034fab81c (patch)
tree56d4aa7dd9c61d99a217ddc3bad369e326b7618a /src
parent5bc63de8819448e7342f3cb0ac08af667ccc81e5 (diff)
downloadqtdeclarative-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.cpp19
-rw-r--r--src/qmlcompiler/qqmljscompiler.cpp1
-rw-r--r--src/qmlcompiler/qqmljstyperesolver.cpp15
-rw-r--r--src/qmlcompiler/qqmljstyperesolver_p.h4
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;