diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2022-02-16 10:47:04 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2022-02-18 12:13:47 +0100 |
commit | d0f4e0c037cf61eb5bb559755ee7c9ce6cf6b7dc (patch) | |
tree | df0ded3ef90e50a5c384d15b6120b0012cc4bbb2 /src/qml/jsapi/qjsengine.h | |
parent | bd968fa6ff07cda5d96dd5c9851bb1c98ee4f318 (diff) |
QmlCompiler: Perform QVariant conversion in JavaScript semantics
In JavaScript we have a number of extra conversions not covered by
qvariant_cast. Therefore, add a method to perform a QVariant conversion
in JavaScript semantics to QJSEngine, and use that in the compiler.
Pick-to: 6.3
Fixes: QTBUG-100883
Change-Id: I8b0bfa0974bc6b339d2601fb373859bc710788c8
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Reviewed-by: Jarkko Koivikko <jarkko.koivikko@code-q.fi>
Diffstat (limited to 'src/qml/jsapi/qjsengine.h')
-rw-r--r-- | src/qml/jsapi/qjsengine.h | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/src/qml/jsapi/qjsengine.h b/src/qml/jsapi/qjsengine.h index 23578a63b6..700b00bcf6 100644 --- a/src/qml/jsapi/qjsengine.h +++ b/src/qml/jsapi/qjsengine.h @@ -113,6 +113,33 @@ public: return qjsvalue_cast<T>(value); } + template <typename T> + inline T fromVariant(const QVariant &value) + { + if constexpr (std::is_same_v<T, QVariant>) + return value; + + const QMetaType targetType = QMetaType::fromType<T>(); + if (value.metaType() == targetType) + return *reinterpret_cast<const T *>(value.constData()); + + if constexpr (std::is_same_v<T,std::remove_const_t<std::remove_pointer_t<T>> const *>) { + using nonConstT = std::remove_const_t<std::remove_pointer_t<T>> *; + const QMetaType nonConstTargetType = QMetaType::fromType<nonConstT>(); + if (value.metaType() == nonConstTargetType) + return *reinterpret_cast<const nonConstT *>(value.constData()); + } + + { + T t{}; + if (convertVariant(value, QMetaType::fromType<T>(), &t)) + return t; + + QMetaType::convert(value.metaType(), value.constData(), targetType, &t); + return t; + } + } + void collectGarbage(); enum ObjectOwnership { CppOwnership, JavaScriptOwnership }; @@ -157,6 +184,7 @@ private: static bool convertManaged(const QJSManagedValue &value, QMetaType type, void *ptr); static bool convertV2(const QJSValue &value, int type, void *ptr); static bool convertV2(const QJSValue &value, QMetaType metaType, void *ptr); + bool convertVariant(const QVariant &value, QMetaType metaType, void *ptr); template<typename T> friend inline T qjsvalue_cast(const QJSValue &); |