Simplify the object iterator API
authorLars Knoll <lars.knoll@digia.com>
Tue, 4 Jun 2013 08:36:39 +0000 (10:36 +0200)
committerSimon Hausmann <simon.hausmann@digia.com>
Tue, 4 Jun 2013 09:00:55 +0000 (11:00 +0200)
We were really missing methods to get both the key and the value
in one go.

Change-Id: I996bde79265f45312e68fcc6bdce76704385ea5b
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
src/imports/localstorage/plugin.cpp
src/qml/qml/v4/qv4functionobject_p.h
src/qml/qml/v4/qv4jsonobject.cpp
src/qml/qml/v4/qv4objectiterator.cpp
src/qml/qml/v4/qv4objectiterator_p.h
src/qml/qml/v4/qv4objectproto.cpp
src/qml/qml/v4/qv4v8.cpp
src/qml/qml/v8/qv8engine.cpp
src/qml/types/qqmllistmodel.cpp

index 92df9c3..323b89b 100644 (file)
@@ -268,17 +268,17 @@ static Value qmlsqldatabase_executeSql(SimpleCallContext *ctx)
             } else if (Object *object = values.asObject()) {
                 ObjectIterator it(object, ObjectIterator::WithProtoChain|ObjectIterator::EnumerableOnly);
                 while (1) {
-                    String *name;
-                    uint index;
-                    PropertyAttributes attrs;
-                    Property *p = it.next(&name, &index, &attrs);
-                    if (!p)
+                    Value value;
+                    Value key = it.nextPropertyName(&value);
+                    if (key.isNull())
                         break;
-                    QVariant v = engine->toVariant(object->getValue(ctx, p, attrs), -1);
-                    if (name)
-                        query.bindValue(name->toQString(), v);
-                    else
-                        query.bindValue(index, v);
+                    QVariant v = engine->toVariant(value, -1);
+                    if (key.isString()) {
+                        query.bindValue(key.stringValue()->toQString(), v);
+                    } else {
+                        assert(key.isInteger());
+                        query.bindValue(key.integerValue(), v);
+                    }
                 }
             } else {
                 query.bindValue(0, engine->toVariant(values, -1));
index 7e43e41..1d04306 100644 (file)
@@ -66,7 +66,6 @@ namespace QV4 {
 struct Value;
 struct Function;
 struct Object;
-struct ObjectIterator;
 struct BooleanObject;
 struct NumberObject;
 struct StringObject;
index cdc5ae7..45fe90d 100644 (file)
@@ -778,18 +778,11 @@ QString Stringify::JO(Object *o)
         ObjectIterator it(o, ObjectIterator::EnumerableOnly);
 
         while (1) {
-            String *name;
-            uint index;
-            PropertyAttributes attrs;
-            Property *pd = it.next(&name, &index, &attrs);
-            if (!pd)
+            Value v;
+            Value name = it.nextPropertyNameAsString(&v);
+            if (name.isNull())
                 break;
-            Value v = o->getValue(ctx, pd, attrs);
-            QString key;
-            if (name)
-                key = name->toQString();
-            else
-                key = QString::number(index);
+            QString key = name.toQString();
             QString member = makeMember(key, v);
             if (!member.isEmpty())
                 partial += member;
@@ -993,15 +986,12 @@ QJsonObject JsonObject::toJsonObject(QV4::Object *o, V4ObjectSet &visitedObjects
 
     ObjectIterator it(o, ObjectIterator::EnumerableOnly);
     while (1) {
-        PropertyAttributes attributes;
-        String *name;
-        uint idx;
-        Property *p = it.next(&name, &idx, &attributes);
-        if (!p)
+        Value v;
+        Value name = it.nextPropertyNameAsString(&v);
+        if (name.isNull())
             break;
 
-        Value v = o->getValue(o->engine()->current, p, attributes);
-        QString key = name ? name->toQString() : QString::number(idx);
+        QString key = name.toQString();
         result.insert(key, toJsonValue(v, visitedObjects));
     }
 
index ce30aee..67eb47b 100644 (file)
@@ -210,26 +210,38 @@ Property *ObjectIterator::next(String **name, uint *index, PropertyAttributes *a
     return 0;
 }
 
-Value ObjectIterator::nextPropertyName()
+Value ObjectIterator::nextPropertyName(Value *value)
 {
+    PropertyAttributes attrs;
     uint index;
     String *name;
-    next(&name, &index);
+    Property *p = next(&name, &index, &attrs);
+    if (!p)
+        return Value::nullValue();
+
+    if (value)
+        *value = object->getValue(object->engine()->current, p, attrs);
+
     if (name)
         return Value::fromString(name);
-    if (index < UINT_MAX)
-        return Value::fromDouble(index);
-    return Value::nullValue();
+    assert(index < UINT_MAX);
+    return Value::fromDouble(index);
 }
 
-Value ObjectIterator::nextPropertyNameAsString()
+Value ObjectIterator::nextPropertyNameAsString(Value *value)
 {
+    PropertyAttributes attrs;
     uint index;
     String *name;
-    next(&name, &index);
+    Property *p = next(&name, &index, &attrs);
+    if (!p)
+        return Value::nullValue();
+
+    if (value)
+        *value = object->getValue(object->engine()->current, p, attrs);
+
     if (name)
         return Value::fromString(name);
-    if (index < UINT_MAX)
-        return __qmljs_to_string(Value::fromDouble(index), object->internalClass->engine->current);
-    return Value::nullValue();
+    assert(index < UINT_MAX);
+    return Value::fromString(object->engine()->newString(QString::number(index)));
 }
index bab0aa4..1036129 100644 (file)
@@ -82,8 +82,8 @@ struct Q_QML_EXPORT ObjectIterator
 
     ObjectIterator(Object *o, uint flags);
     Property *next(String **name, uint *index, PropertyAttributes *attributes = 0);
-    Value nextPropertyName();
-    Value nextPropertyNameAsString();
+    Value nextPropertyName(Value *value = 0);
+    Value nextPropertyNameAsString(Value *value = 0);
 };
 
 }
index 5d34d33..efb40ee 100644 (file)
@@ -351,19 +351,10 @@ Value ObjectPrototype::method_keys(SimpleCallContext *ctx)
 
     ObjectIterator it(o, ObjectIterator::EnumerableOnly);
     while (1) {
-        uint index;
-        String *name;
-        Property *pd = it.next(&name, &index);
-        if (!pd)
+        Value name = it.nextPropertyNameAsString();
+        if (name.isNull())
             break;
-        Value key;
-        if (name) {
-            key = Value::fromString(name);
-        } else {
-            key = Value::fromDouble(index);
-            key = __qmljs_to_string(key, ctx);
-        }
-        a->push_back(key);
+        a->push_back(name);
     }
 
     return Value::fromObject(a);
@@ -567,10 +558,10 @@ ArrayObject *ObjectPrototype::getOwnPropertyNames(ExecutionEngine *v4, const Val
 
     ObjectIterator it(O, ObjectIterator::NoFlags);
     while (1) {
-        Value v = it.nextPropertyNameAsString();
-        if (v.isNull())
+        Value name = it.nextPropertyNameAsString();
+        if (name.isNull())
             break;
-        array->push_back(v);
+        array->push_back(name);
     }
     return array;
 }
index ccd560d..3b31311 100644 (file)
@@ -528,10 +528,10 @@ Handle<Array> Object::GetPropertyNames()
     QV4::ArrayObject *array = currentEngine()->newArrayObject();
     ObjectIterator it(o, ObjectIterator::WithProtoChain|ObjectIterator::EnumerableOnly);
     while (1) {
-        QV4::Value v = it.nextPropertyNameAsString();
-        if (v.isNull())
+        QV4::Value name = it.nextPropertyNameAsString();
+        if (name.isNull())
             break;
-        array->push_back(v);
+        array->push_back(name);
     }
     return QV4::Value::fromObject(array);
 }
@@ -544,10 +544,10 @@ Handle<Array> Object::GetOwnPropertyNames()
     ArrayObject *array = currentEngine()->newArrayObject();
     ObjectIterator it(o, ObjectIterator::EnumerableOnly);
     while (1) {
-        QV4::Value v = it.nextPropertyNameAsString();
-        if (v.isNull())
+        QV4::Value name = it.nextPropertyNameAsString();
+        if (name.isNull())
             break;
-        array->push_back(v);
+        array->push_back(name);
     }
     return QV4::Value::fromObject(array);
 }
index 4af730f..3af2efb 100644 (file)
@@ -626,15 +626,12 @@ QVariantMap QV8Engine::variantMapFromJS(QV4::Object *o,
 
     QV4::ObjectIterator it(o, QV4::ObjectIterator::EnumerableOnly);
     while (1) {
-        QV4::PropertyAttributes attributes;
-        QV4::String *name;
-        uint idx;
-        QV4::Property *p = it.next(&name, &idx, &attributes);
-        if (!p)
+        QV4::Value v;
+        QV4::Value name = it.nextPropertyNameAsString(&v);
+        if (name.isNull())
             break;
 
-        QV4::Value v = o->getValue(m_v4Engine->current, p, attributes);
-        QString key = name ? name->toQString() : QString::number(idx);
+        QString key = name.toQString();
         result.insert(key, variantFromJS(v, visitedObjects));
     }
 
index 4bb0577..f016a9a 100644 (file)
@@ -418,16 +418,11 @@ void ListModel::set(int elementIndex, QV4::Object *object, QVector<int> *roles,
     QV4::ExecutionEngine *v4 = object->engine();
     QV4::ObjectIterator it(object, QV4::ObjectIterator::WithProtoChain|QV4::ObjectIterator::EnumerableOnly);
     while (1) {
-        QV4::String *name;
-        uint index;
-        QV4::PropertyAttributes attrs;
-        QV4::Property *p = it.next(&name, &index, &attrs);
-        if (!p)
+        QV4::Value propertyValue;
+        QV4::Value propertyName = it.nextPropertyNameAsString(&propertyValue);
+        if (propertyName.isNull())
             break;
 
-        QV4::Value propertyName = QV4::Value::fromString(name ? name : v4->newString(QString::number(index)));
-        QV4::Value propertyValue = object->getValue(v4->current, p, attrs);
-
         // Check if this key exists yet
         int roleIndex = -1;
 
@@ -489,16 +484,11 @@ void ListModel::set(int elementIndex, QV4::Object *object, QV8Engine *eng)
     QV4::ExecutionEngine *v4 = object->engine();
     QV4::ObjectIterator it(object, QV4::ObjectIterator::WithProtoChain|QV4::ObjectIterator::EnumerableOnly);
     while (1) {
-        QV4::String *name;
-        uint index;
-        QV4::PropertyAttributes attrs;
-        QV4::Property *p = it.next(&name, &index, &attrs);
-        if (!p)
+        QV4::Value propertyValue;
+        QV4::Value propertyName = it.nextPropertyNameAsString(&propertyValue);
+        if (propertyName.isNull())
             break;
 
-        QV4::Value propertyName = QV4::Value::fromString(name ? name : v4->newString(QString::number(index)));
-        QV4::Value propertyValue = object->getValue(v4->current, p, attrs);
-
         // Add the value now
         if (QV4::String *s = propertyValue.asString()) {
             const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::String);