summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt1
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/dateConversions.qml25
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/druggeljug.h12
-rw-r--r--tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp37
8 files changed, 114 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;
diff --git a/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt b/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt
index fa06745d34..e66af303ca 100644
--- a/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt
+++ b/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt
@@ -79,6 +79,7 @@ set(qml_files
conversions2.qml
curlygrouped.qml
cycleHead.qml
+ dateConversions.qml
deadShoeSize.qml
deadStoreLoop.qml
dialog.qml
diff --git a/tests/auto/qml/qmlcppcodegen/data/dateConversions.qml b/tests/auto/qml/qmlcppcodegen/data/dateConversions.qml
new file mode 100644
index 0000000000..38a34f7487
--- /dev/null
+++ b/tests/auto/qml/qmlcppcodegen/data/dateConversions.qml
@@ -0,0 +1,25 @@
+pragma Strict
+import QtQml
+import TestTypes
+
+QtObject {
+ property date date: Druggeljug.myDate
+ property date time: Druggeljug.myTime
+
+ property string dateString: date
+ property string timeString: time
+
+ function shuffle() {
+ Druggeljug.myDate = date;
+ Druggeljug.myTime = time;
+
+ dateString = Druggeljug.myDate;
+ timeString = Druggeljug.myTime;
+ }
+
+ function fool() {
+ var tmp = Druggeljug.myTime;
+ Druggeljug.myTime = Druggeljug.myDate;
+ Druggeljug.myDate = tmp;
+ }
+}
diff --git a/tests/auto/qml/qmlcppcodegen/data/druggeljug.h b/tests/auto/qml/qmlcppcodegen/data/druggeljug.h
index 70553e9b71..04f8301718 100644
--- a/tests/auto/qml/qmlcppcodegen/data/druggeljug.h
+++ b/tests/auto/qml/qmlcppcodegen/data/druggeljug.h
@@ -2,6 +2,7 @@
#define DRUGGELJUG_H
#include <QtCore/qobject.h>
+#include <QtCore/qdatetime.h>
#include <qqmlregistration.h>
#define STORE_FUNCTION(type, name, member, signal) \
@@ -29,6 +30,9 @@ class Druggeljug : public QObject
Q_PROPERTY(qint64 myInt64 MEMBER m_myInt64 NOTIFY myInt64Changed FINAL)
Q_PROPERTY(quint64 myUint64 MEMBER m_myUint64 NOTIFY myUint64Changed FINAL)
+ Q_PROPERTY(QTime myTime MEMBER m_myTime NOTIFY myTimeChanged)
+ Q_PROPERTY(QDate myDate MEMBER m_myDate NOTIFY myDateChanged)
+
public:
Druggeljug(QObject* parent = nullptr) : QObject(parent) {}
@@ -43,6 +47,9 @@ public:
STORE_FUNCTION(qint64, storeMyInt64, m_myInt64, myInt64Changed)
STORE_FUNCTION(quint64, storeMyUint64, m_myUint64, myUint64Changed)
+ QTime myTime() const { return m_myTime; }
+ QDate myDate() const { return m_myDate; }
+
private:
int m_myInt = 0;
uint m_myUint = 0;
@@ -55,6 +62,9 @@ private:
qint64 m_myInt64 = 0;
quint64 m_myUint64 = 0;
+ QTime m_myTime = QTime(11, 55, 0);
+ QDate m_myDate = QDate(2017, 9, 3);
+
signals:
void myIntChanged(int);
void myUintChanged(uint);
@@ -66,6 +76,8 @@ signals:
void myUint32Changed(quint32);
void myInt64Changed(qint64);
void myUint64Changed(quint64);
+ void myTimeChanged();
+ void myDateChanged();
};
#endif
diff --git a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
index 65e882a089..1e88ecd7b7 100644
--- a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
+++ b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
@@ -1,5 +1,6 @@
// Copyright (C) 2021 The Qt Company Ltd.
+#include "data/druggeljug.h"
#include <data/birthdayparty.h>
#include <data/cppbaseclass.h>
#include <data/enumproblems.h>
@@ -160,6 +161,7 @@ private slots:
void infinitiesToInt();
void equalityVarAndNonStorable();
void equalityQObjects();
+ void dateConversions();
};
void tst_QmlCppCodegen::initTestCase()
@@ -3088,6 +3090,41 @@ void tst_QmlCppCodegen::equalityQObjects()
QVERIFY(object->property("compareObjectWithNullObject").toBool());
}
+void tst_QmlCppCodegen::dateConversions()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, QUrl(u"qrc:/qt/qml/TestTypes/dateConversions.qml"_s));
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ QScopedPointer<QObject> o(c.create());
+
+ Druggeljug *ref = engine.singletonInstance<Druggeljug *>("TestTypes", "Druggeljug");
+
+ const QDateTime refDate = engine.coerceValue<QDate, QDateTime>(ref->myDate());
+ const QDateTime refTime = engine.coerceValue<QTime, QDateTime>(ref->myTime());
+
+ QCOMPARE(o->property("date").value<QDateTime>(), refDate);
+ QCOMPARE(o->property("time").value<QDateTime>(), refTime);
+
+ QCOMPARE(o->property("dateString").toString(), (engine.coerceValue<QDateTime, QString>(refDate)));
+ QCOMPARE(o->property("timeString").toString(), (engine.coerceValue<QDateTime, QString>(refTime)));
+
+ QMetaObject::invokeMethod(o.data(), "shuffle");
+
+ QCOMPARE(ref->myDate(), (engine.coerceValue<QDateTime, QDate>(refDate)));
+ QCOMPARE(ref->myTime(), (engine.coerceValue<QDateTime, QTime>(refTime)));
+
+ const QDate date = ref->myDate();
+ const QTime time = ref->myTime();
+
+ QCOMPARE(o->property("dateString").toString(), (engine.coerceValue<QDate, QString>(date)));
+ QCOMPARE(o->property("timeString").toString(), (engine.coerceValue<QTime, QString>(time)));
+
+ QMetaObject::invokeMethod(o.data(), "fool");
+
+ QCOMPARE(ref->myDate(), (engine.coerceValue<QTime, QDate>(time)));
+ QCOMPARE(ref->myTime(), (engine.coerceValue<QDate, QTime>(date)));
+}
+
QTEST_MAIN(tst_QmlCppCodegen)
#include "tst_qmlcppcodegen.moc"