aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2020-07-10 10:33:49 +0200
committerShawn Rutledge <shawn.rutledge@qt.io>2020-08-28 13:49:11 +0200
commit2afed94c70913e018198422ef222c9168326d09c (patch)
tree526952d291b70065886377e540f9e149be2f1537
parent6e423233b2e419fc3d7fc30bebcad976dca31934 (diff)
Fix QtQml after QMetaType/QVariant changes in Qt Core
Change-Id: I2a983cf8188e88d80d3b7726208d821427eb8f3c Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
-rw-r--r--src/plugins/qmltooling/qmldbg_preview/qqmlpreviewposition.cpp1
-rw-r--r--src/qml/jsapi/qjsvalue.cpp65
-rw-r--r--src/qml/jsapi/qjsvalue.h5
-rw-r--r--src/qml/jsruntime/qv4engine.cpp118
-rw-r--r--src/qml/parser/qqmljsast.cpp1
-rw-r--r--src/qml/qml/qqmlengine.cpp10
-rw-r--r--src/qml/qml/qqmlmetatype.cpp13
-rw-r--r--tests/auto/qml/qjsengine/tst_qjsengine.cpp2
-rw-r--r--tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp1
9 files changed, 107 insertions, 109 deletions
diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewposition.cpp b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewposition.cpp
index 47bb64140f..4da6b71b40 100644
--- a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewposition.cpp
+++ b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewposition.cpp
@@ -39,6 +39,7 @@
#include "qqmlpreviewposition.h"
+#include <QtCore/qiodevice.h>
#include <QtGui/qwindow.h>
#include <QtGui/qscreen.h>
#include <QtGui/qguiapplication.h>
diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp
index 663f6ced82..4a1833be51 100644
--- a/src/qml/jsapi/qjsvalue.cpp
+++ b/src/qml/jsapi/qjsvalue.cpp
@@ -1277,4 +1277,69 @@ bool QJSValue::isQMetaObject() const
return QJSValuePrivate::asManagedType<QV4::QMetaObjectWrapper>(this);
}
+#ifndef QT_NO_DATASTREAM
+QDataStream &operator<<(QDataStream &stream, const QJSValue &jsv)
+{
+ quint32 isNullOrUndefined = 0;
+ if (jsv.isNull())
+ isNullOrUndefined |= 0x1;
+ if (jsv.isUndefined())
+ isNullOrUndefined |= 0x2;
+ stream << isNullOrUndefined;
+ if (!isNullOrUndefined) {
+ const QVariant v = jsv.toVariant();
+ switch (v.userType()) {
+ case QMetaType::Bool:
+ case QMetaType::Double:
+ case QMetaType::Int:
+ case QMetaType::QString:
+ v.save(stream);
+ break;
+ default:
+ qWarning() << "QDataStream::operator<< was to save a non-trivial QJSValue."
+ << "This is not supported anymore, please stream a QVariant instead.";
+ QVariant().save(stream);
+ break;
+ }
+
+ }
+ return stream;
+}
+
+QDataStream &operator>>(QDataStream &stream, QJSValue &jsv)
+{
+ quint32 isNullOrUndefined;
+ stream >> isNullOrUndefined;
+
+ if (isNullOrUndefined & 0x1) {
+ jsv = QJSValue(QJSValue::NullValue);
+ } else if (isNullOrUndefined & 0x2) {
+ jsv = QJSValue();
+ } else {
+ QVariant v;
+ v.load(stream);
+
+ switch (v.userType()) {
+ case QMetaType::Bool:
+ jsv = QJSValue(v.toBool());
+ break;
+ case QMetaType::Double:
+ jsv = QJSValue(v.toDouble());
+ break;
+ case QMetaType::Int:
+ jsv = QJSValue(v.toInt());
+ break;
+ case QMetaType::QString:
+ jsv = QJSValue(v.toString());
+ break;
+ default:
+ qWarning() << "QDataStream::operator>> to restore a non-trivial QJSValue."
+ << "This is not supported anymore, please stream a QVariant instead.";
+ break;
+ }
+ }
+ return stream;
+}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/qml/jsapi/qjsvalue.h b/src/qml/jsapi/qjsvalue.h
index 3da76d16cb..c814ce14f8 100644
--- a/src/qml/jsapi/qjsvalue.h
+++ b/src/qml/jsapi/qjsvalue.h
@@ -158,6 +158,11 @@ private:
quint64 d;
};
+#ifndef QT_NO_DATASTREAM
+Q_QML_EXPORT QDataStream &operator<<(QDataStream &, const QJSValue &);
+Q_QML_EXPORT QDataStream &operator>>(QDataStream &, QJSValue &);
+#endif
+
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QJSValue)
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index f40fc3b780..9cd558590f 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -157,70 +157,6 @@ ReturnType convertJSValueToVariantType(const QJSValue &value)
return value.toVariant().value<ReturnType>();
}
-static void saveJSValue(QDataStream &stream, const void *data)
-{
- const QJSValue *jsv = reinterpret_cast<const QJSValue *>(data);
- quint32 isNullOrUndefined = 0;
- if (jsv->isNull())
- isNullOrUndefined |= 0x1;
- if (jsv->isUndefined())
- isNullOrUndefined |= 0x2;
- stream << isNullOrUndefined;
- if (!isNullOrUndefined) {
- const QVariant v = reinterpret_cast<const QJSValue*>(data)->toVariant();
- switch (v.userType()) {
- case QMetaType::Bool:
- case QMetaType::Double:
- case QMetaType::Int:
- case QMetaType::QString:
- v.save(stream);
- break;
- default:
- qWarning() << "QDataStream::operator<< was to save a non-trivial QJSValue."
- << "This is not supported anymore, please stream a QVariant instead.";
- QVariant().save(stream);
- break;
- }
-
- }
-}
-
-static void restoreJSValue(QDataStream &stream, void *data)
-{
- QJSValue *jsv = reinterpret_cast<QJSValue*>(data);
-
- quint32 isNullOrUndefined;
- stream >> isNullOrUndefined;
-
- if (isNullOrUndefined & 0x1) {
- *jsv = QJSValue(QJSValue::NullValue);
- } else if (isNullOrUndefined & 0x2) {
- *jsv = QJSValue();
- } else {
- QVariant v;
- v.load(stream);
-
- switch (v.userType()) {
- case QMetaType::Bool:
- *jsv = QJSValue(v.toBool());
- break;
- case QMetaType::Double:
- *jsv = QJSValue(v.toDouble());
- break;
- case QMetaType::Int:
- *jsv = QJSValue(v.toInt());
- break;
- case QMetaType::QString:
- *jsv = QJSValue(v.toString());
- break;
- default:
- qWarning() << "QDataStream::operator>> to restore a non-trivial QJSValue."
- << "This is not supported anymore, please stream a QVariant instead.";
- break;
- }
- }
-}
-
struct JSArrayIterator {
QJSValue const* data;
quint32 index;
@@ -241,9 +177,10 @@ static QtMetaTypePrivate::QSequentialIterableImpl jsvalueToSequence (const QJSVa
// set up some functions so that non-array QSequentialIterables do not crash
// but instead appear as an empty sequence
iterator._size = [](const void *) {return 0;};
- iterator._moveToBegin = [](const void *, void **) {};
- iterator._moveToEnd = [](const void *, void **) {};
+ iterator._at = [](const void *, int, void *) {};
+ iterator._moveTo = [](const void *, void **, QSequentialIterableImpl::Position) {};
iterator._advance = [](void **, int) {};
+ iterator._get = [](void * const *, void *) {};
iterator._equalIter = [](void * const *, void * const *){return true; /*all iterators are nullptr*/};
iterator._destroyIter = [](void **){};
return iterator;
@@ -251,8 +188,7 @@ static QtMetaTypePrivate::QSequentialIterableImpl jsvalueToSequence (const QJSVa
iterator._iterable = &value;
iterator._iterator = nullptr;
- iterator._metaType_id = qMetaTypeId<QVariant>();
- iterator._metaType_flags = QVariantConstructionFlags::ShouldDeleteVariantData;
+ iterator._metaType = QMetaType::fromType<QVariant>();
iterator._iteratorCapabilities = RandomAccessCapability | BiDirectionalCapability | ForwardCapability;
iterator._size = [](const void *p) -> int {
return static_cast<QJSValue const *>(p)->property(QString::fromLatin1("length")).toInt();
@@ -263,32 +199,28 @@ static QtMetaTypePrivate::QSequentialIterableImpl jsvalueToSequence (const QJSVa
* and QSequentialIterable::operator*() will free that memory
*/
- iterator._at = [](const void *iterable, int index) -> void const * {
- auto const value = static_cast<QJSValue const *>(iterable)->property(quint32(index)).toVariant();
- return QMetaType::create(qMetaTypeId<QVariant>(), &value);
+ iterator._at = [](const void *iterable, int index, void *dataPtr) -> void {
+ auto *data = static_cast<QVariant *>(dataPtr);
+ *data = static_cast<QJSValue const *>(iterable)->property(quint32(index)).toVariant();
};
- iterator._moveToBegin = [](const void *iterable, void **iterator) {
+ iterator._moveTo = [](const void *iterable, void **iterator, QSequentialIterableImpl::Position pos) {
createNewIteratorIfNonExisting(iterator);
auto jsArrayIterator = static_cast<JSArrayIterator *>(*iterator);
jsArrayIterator->index = 0;
jsArrayIterator->data = reinterpret_cast<QJSValue const*>(iterable);
- };
- iterator._moveToEnd = [](const void *iterable, void **iterator) {
- createNewIteratorIfNonExisting(iterator);
- auto jsArrayIterator = static_cast<JSArrayIterator *>(*iterator);
- auto length = static_cast<QJSValue const *>(iterable)->property(QString::fromLatin1("length")).toInt();
- jsArrayIterator->data = reinterpret_cast<QJSValue const*>(iterable);
- jsArrayIterator->index = quint32(length);
+ if (pos == QSequentialIterableImpl::ToEnd) {
+ auto length = static_cast<QJSValue const *>(iterable)->property(QString::fromLatin1("length")).toInt();
+ jsArrayIterator->index = quint32(length);
+ }
};
iterator._advance = [](void **iterator, int advanceBy) {
static_cast<JSArrayIterator *>(*iterator)->index += quint32(advanceBy);
};
- iterator._get = []( void * const *iterator, int metaTypeId, uint flags) -> VariantData {
+ iterator._get = []( void * const *iterator, void *dataPtr) -> void {
auto const * const arrayIterator = static_cast<const JSArrayIterator *>(*iterator);
QJSValue const * const jsArray = arrayIterator->data;
- auto const value = jsArray->property(arrayIterator->index).toVariant();
- Q_ASSERT(flags & QVariantConstructionFlags::ShouldDeleteVariantData);
- return {metaTypeId, QMetaType::create(qMetaTypeId<QVariant>(), &value), flags};
+ auto *data = static_cast<QVariant *>(dataPtr);
+ *data = jsArray->property(arrayIterator->index).toVariant();
};
iterator._destroyIter = [](void **iterator) {
delete static_cast<JSArrayIterator *>(*iterator);
@@ -848,7 +780,6 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine)
QMetaType::registerConverter<QJSValue, QStringList>(convertJSValueToVariantType<QStringList>);
if (!QMetaType::hasRegisteredConverterFunction<QJSValue, QtMetaTypePrivate::QSequentialIterableImpl>())
QMetaType::registerConverter<QJSValue, QtMetaTypePrivate::QSequentialIterableImpl>(jsvalueToSequence);
- QMetaType::registerStreamOperators(qMetaTypeId<QJSValue>(), saveJSValue, restoreJSValue);
QV4::QObjectWrapper::initializeBindings(this);
@@ -1565,11 +1496,8 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int
return retn;
#endif
if (typeHint != -1) {
- // the QVariant constructor will create a copy, so we have manually
- // destroy the value returned by QMetaType::create
- auto temp = QMetaType::create(typeHint);
- retn = QVariant(QMetaType(typeHint), temp);
- QMetaType::destroy(typeHint, temp);
+ auto metaType = QMetaType(typeHint);
+ retn = QVariant(metaType, nullptr);
auto retnAsIterable = retn.value<QtMetaTypePrivate::QSequentialIterableImpl>();
if (retnAsIterable.containerCapabilities() & QtMetaTypePrivate::ContainerIsAppendable) {
auto const length = a->getLength();
@@ -1577,26 +1505,26 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int
for (qint64 i = 0; i < length; ++i) {
arrayValue = a->get(i);
QVariant asVariant;
- if (QMetaType::hasRegisteredConverterFunction(qMetaTypeId<QJSValue>(), retnAsIterable._metaType_id)) {
+ if (QMetaType::hasRegisteredConverterFunction(qMetaTypeId<QJSValue>(), retnAsIterable._metaType.id())) {
// before attempting a conversion from the concrete types,
// check if there exists a conversion from QJSValue -> out type
// prefer that one for compatibility reasons
asVariant = QVariant::fromValue(QJSValuePrivate::fromReturnedValue(arrayValue->asReturnedValue()));
- if (asVariant.convert(retnAsIterable._metaType_id)) {
+ if (asVariant.convert(retnAsIterable._metaType.id())) {
retnAsIterable.append(asVariant.constData());
continue;
}
}
- asVariant = toVariant(e, arrayValue, retnAsIterable._metaType_id, false, visitedObjects);
+ asVariant = toVariant(e, arrayValue, retnAsIterable._metaType.id(), false, visitedObjects);
auto originalType = asVariant.userType();
- bool couldConvert = asVariant.convert(retnAsIterable._metaType_id);
+ bool couldConvert = asVariant.convert(retnAsIterable._metaType.id());
if (!couldConvert) {
qWarning() << QLatin1String("Could not convert array value at position %1 from %2 to %3")
.arg(QString::number(i),
QString::fromUtf8(QMetaType::typeName(originalType)),
- QString::fromUtf8(QMetaType::typeName(retnAsIterable._metaType_id)));
+ QString::fromUtf8(QMetaType::typeName(retnAsIterable._metaType.id())));
// create default constructed value
- asVariant = QVariant(QMetaType(retnAsIterable._metaType_id), nullptr);
+ asVariant = QVariant(retnAsIterable._metaType, nullptr);
}
retnAsIterable.append(asVariant.constData());
}
diff --git a/src/qml/parser/qqmljsast.cpp b/src/qml/parser/qqmljsast.cpp
index 9885875499..7309cf8162 100644
--- a/src/qml/parser/qqmljsast.cpp
+++ b/src/qml/parser/qqmljsast.cpp
@@ -41,6 +41,7 @@
#include "qqmljsast_p.h"
#include "qqmljsastvisitor_p.h"
+#include <qlocale.h>
QT_BEGIN_NAMESPACE
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 7191da694d..4326002575 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -767,23 +767,23 @@ void QQmlData::signalEmitted(QAbstractDeclarativeData *, QObject *object, int in
parameterTypes.count() + 1));
void **args = ev->args();
- int *types = ev->types();
+ QMetaType *types = ev->types();
for (int ii = 0; ii < parameterTypes.count(); ++ii) {
const QByteArray &typeName = parameterTypes.at(ii);
if (typeName.endsWith('*'))
- types[ii + 1] = QMetaType::VoidStar;
+ types[ii + 1] = QMetaType(QMetaType::VoidStar);
else
- types[ii + 1] = QMetaType::type(typeName);
+ types[ii + 1] = QMetaType::fromName(typeName);
- if (!types[ii + 1]) {
+ if (!types[ii + 1].isValid()) {
qWarning("QObject::connect: Cannot queue arguments of type '%s'\n"
"(Make sure '%s' is registered using qRegisterMetaType().)",
typeName.constData(), typeName.constData());
return;
}
- args[ii + 1] = QMetaType::create(types[ii + 1], a[ii + 1]);
+ args[ii + 1] = types[ii + 1].create(a[ii + 1]);
}
QQmlThreadNotifierProxyObject *mpo = new QQmlThreadNotifierProxyObject;
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 9b0df3c5c4..cb2522a675 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -549,16 +549,12 @@ struct QQmlMetaTypeInterface : QtPrivate::QMetaTypeInterface
QQmlMetaTypeInterface(const QByteArray &name)
: QMetaTypeInterface {
/*.revision=*/ 0,
- /*.size=*/ sizeof(T),
/*.alignment=*/ alignof(T),
+ /*.size=*/ sizeof(T),
/*.flags=*/ QtPrivate::QMetaTypeTypeFlags<T>::Flags,
- /*.metaObject=*/ nullptr,
- /*.name=*/ name.constData(),
/*.typeId=*/ 0,
- /*.ref=*/ { Q_BASIC_ATOMIC_INITIALIZER(0) },
- /*.deleteSelf=*/ [](QMetaTypeInterface *self) {
- delete static_cast<QQmlMetaTypeInterface *>(self);
- },
+ /*.metaObject=*/ nullptr,//QtPrivate::MetaObjectForType<T>::value(),
+ /*.name=*/ name.constData(),
/*.defaultCtr=*/ [](const QMetaTypeInterface *, void *addr) { new (addr) T(); },
/*.copyCtr=*/ [](const QMetaTypeInterface *, void *addr, const void *other) {
new (addr) T(*reinterpret_cast<const T *>(other));
@@ -571,6 +567,9 @@ struct QQmlMetaTypeInterface : QtPrivate::QMetaTypeInterface
},
/*.equals*/ nullptr,
/*.lessThan*/ nullptr,
+ /*.debugStream=*/ nullptr,
+ /*.dataStreamOut=*/ nullptr,
+ /*.dataStreamIn=*/ nullptr,
/*.legacyRegisterOp=*/ nullptr
}
, name(name) { }
diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
index cd03903da2..81e150bf1f 100644
--- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
@@ -563,7 +563,7 @@ void tst_QJSEngine::toScriptValue()
if (input.metaType().id() == QMetaType::QChar) {
if (!input.convert(QMetaType::QString))
QFAIL("cannot convert to the original value");
- } else if (!output.convert(input.metaType().id()))
+ } else if (!output.convert(input.metaType().id()) && input.isValid())
QFAIL("cannot convert to the original value");
QCOMPARE(input, output);
}
diff --git a/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp b/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp
index 48613d04f1..c0f74b3ec0 100644
--- a/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp
+++ b/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp
@@ -98,7 +98,6 @@ void tst_qqmlconsole::logging()
QStringList stringList; stringList << QStringLiteral("Hello") << QStringLiteral("World");
CustomObject customObject;
- QVERIFY(QMetaType::registerDebugStreamOperator<CustomObject>());
QQmlComponent component(&engine, testUrl);
QScopedPointer<QObject> object(component.createWithInitialProperties({