Fix visibility of properties in value types
It should be possible to enumerate the properties of value types (gadgets), in order for things like JSON.stringify(Qt.point(10, 20)) to return something sensible. Task-number: QTBUG-43382 Task-number: QTBUG-34878 Change-Id: I3a2c09151ebe97fd97760dfbbf5a4f58e022bc94 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io> Reviewed-by: Robin Burchell <robin.burchell@viroteck.net>
This commit is contained in:
parent
35d8d4bc2b
commit
1c51ae2911
|
@ -50,6 +50,7 @@
|
|||
#include <private/qv4functionobject_p.h>
|
||||
#include <private/qv4variantobject_p.h>
|
||||
#include <private/qv4alloca_p.h>
|
||||
#include <private/qv4objectiterator_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
@ -244,6 +245,34 @@ PropertyAttributes QQmlValueTypeWrapper::query(const Managed *m, String *name)
|
|||
return result ? Attr_Data : Attr_Invalid;
|
||||
}
|
||||
|
||||
void QQmlValueTypeWrapper::advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes)
|
||||
{
|
||||
name->setM(0);
|
||||
*index = UINT_MAX;
|
||||
|
||||
QQmlValueTypeWrapper *that = static_cast<QQmlValueTypeWrapper*>(m);
|
||||
|
||||
if (QQmlValueTypeReference *ref = that->as<QQmlValueTypeReference>()) {
|
||||
if (!ref->readReferenceValue())
|
||||
return;
|
||||
}
|
||||
|
||||
if (that->d()->propertyCache) {
|
||||
const QMetaObject *mo = that->d()->propertyCache->createMetaObject();
|
||||
const int propertyCount = mo->propertyCount();
|
||||
if (it->arrayIndex < static_cast<uint>(propertyCount)) {
|
||||
Scope scope(that->engine());
|
||||
ScopedString propName(scope, that->engine()->newString(QString::fromUtf8(mo->property(it->arrayIndex).name())));
|
||||
name->setM(propName->d());
|
||||
++it->arrayIndex;
|
||||
*attributes = QV4::Attr_Data;
|
||||
p->value = that->QV4::Object::get(propName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
QV4::Object::advanceIterator(m, it, name, index, p, attributes);
|
||||
}
|
||||
|
||||
bool QQmlValueTypeWrapper::isEqual(const QVariant& value)
|
||||
{
|
||||
if (QQmlValueTypeReference *ref = as<QQmlValueTypeReference>())
|
||||
|
|
|
@ -99,6 +99,7 @@ public:
|
|||
static void put(Managed *m, String *name, const Value &value);
|
||||
static bool isEqualTo(Managed *m, Managed *other);
|
||||
static PropertyAttributes query(const Managed *, String *name);
|
||||
static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
|
||||
|
||||
static QV4::ReturnedValue method_toString(CallContext *ctx);
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <QQmlEngine>
|
||||
#include <QQmlComponent>
|
||||
#include <QDebug>
|
||||
#include <QJSValueIterator>
|
||||
#include <private/qquickvaluetypes_p.h>
|
||||
#include <private/qqmlglobal_p.h>
|
||||
#include "../../shared/util.h"
|
||||
|
@ -89,6 +90,7 @@ private slots:
|
|||
void customValueTypeInQml();
|
||||
void gadgetInheritance();
|
||||
void toStringConversion();
|
||||
void enumerableProperties();
|
||||
|
||||
private:
|
||||
QQmlEngine engine;
|
||||
|
@ -1649,6 +1651,25 @@ void tst_qqmlvaluetypes::toStringConversion()
|
|||
QCOMPARE(stringConversion.toString(), StringLessGadget_to_QString(g));
|
||||
}
|
||||
|
||||
void tst_qqmlvaluetypes::enumerableProperties()
|
||||
{
|
||||
QJSEngine engine;
|
||||
DerivedGadget g;
|
||||
QJSValue value = engine.toScriptValue(g);
|
||||
QSet<QString> names;
|
||||
QJSValueIterator it(value);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
const QString name = it.name();
|
||||
QVERIFY(!names.contains(name));
|
||||
names.insert(name);
|
||||
}
|
||||
|
||||
QCOMPARE(names.count(), 2);
|
||||
QVERIFY(names.contains(QStringLiteral("baseProperty")));
|
||||
QVERIFY(names.contains(QStringLiteral("derivedProperty")));
|
||||
}
|
||||
|
||||
|
||||
QTEST_MAIN(tst_qqmlvaluetypes)
|
||||
|
||||
|
|
Loading…
Reference in New Issue