[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
commit-queue at webkit.org
commit-queue at webkit.org
Wed Dec 22 11:08:49 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit 07fa9ad75106a14b7d8481f37fd8c22376896b2b
Author: commit-queue at webkit.org <commit-queue at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Tue Jul 13 19:33:57 2010 +0000
2010-07-13 Jedrzej Nowacki <jedrzej.nowacki at nokia.com>
Reviewed by Simon Hausmann.
Introduce QScriptValueIterator.
The QScriptValueIterator class permits to iterate over a QScriptValue's properties.
[Qt] QtScript should provide an API for enumerating a JS object's properties
https://bugs.webkit.org/show_bug.cgi?id=41680
* api/QtScript.pro:
* api/qscriptvalueiterator.cpp: Added.
(QScriptValueIterator::QScriptValueIterator):
(QScriptValueIterator::~QScriptValueIterator):
(QScriptValueIterator::hasNext):
(QScriptValueIterator::next):
(QScriptValueIterator::hasPrevious):
(QScriptValueIterator::previous):
(QScriptValueIterator::toFront):
(QScriptValueIterator::toBack):
(QScriptValueIterator::name):
(QScriptValueIterator::scriptName):
(QScriptValueIterator::value):
(QScriptValueIterator::setValue):
(QScriptValueIterator::remove):
(QScriptValueIterator::flags):
(QScriptValueIterator::operator=):
* api/qscriptvalueiterator.h: Added.
* api/qscriptvalueiterator_p.h: Added.
(QScriptValueIteratorPrivate::QScriptValueIteratorPrivate):
(QScriptValueIteratorPrivate::~QScriptValueIteratorPrivate):
(QScriptValueIteratorPrivate::hasNext):
(QScriptValueIteratorPrivate::next):
(QScriptValueIteratorPrivate::hasPrevious):
(QScriptValueIteratorPrivate::previous):
(QScriptValueIteratorPrivate::name):
(QScriptValueIteratorPrivate::scriptName):
(QScriptValueIteratorPrivate::value):
(QScriptValueIteratorPrivate::setValue):
(QScriptValueIteratorPrivate::remove):
(QScriptValueIteratorPrivate::toFront):
(QScriptValueIteratorPrivate::toBack):
(QScriptValueIteratorPrivate::flags):
(QScriptValueIteratorPrivate::isValid):
(QScriptValueIteratorPrivate::engine):
* tests/qscriptvalueiterator/qscriptvalueiterator.pro: Added.
* tests/qscriptvalueiterator/tst_qscriptvalueiterator.cpp: Added.
(tst_QScriptValueIterator::tst_QScriptValueIterator):
(tst_QScriptValueIterator::~tst_QScriptValueIterator):
(tst_QScriptValueIterator::iterateForward_data):
(tst_QScriptValueIterator::iterateForward):
(tst_QScriptValueIterator::iterateBackward_data):
(tst_QScriptValueIterator::iterateBackward):
(tst_QScriptValueIterator::iterateArray_data):
(tst_QScriptValueIterator::iterateArray):
(tst_QScriptValueIterator::iterateBackAndForth):
(tst_QScriptValueIterator::setValue):
(tst_QScriptValueIterator::remove):
(tst_QScriptValueIterator::removeMixed):
(tst_QScriptValueIterator::removeUndeletable):
(tst_QScriptValueIterator::iterateString):
(tst_QScriptValueIterator::assignObjectToIterator):
* tests/tests.pro:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@63233 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/qt/ChangeLog b/JavaScriptCore/qt/ChangeLog
index 71b4a21..2599aed 100644
--- a/JavaScriptCore/qt/ChangeLog
+++ b/JavaScriptCore/qt/ChangeLog
@@ -1,3 +1,68 @@
+2010-07-13 Jedrzej Nowacki <jedrzej.nowacki at nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Introduce QScriptValueIterator.
+
+ The QScriptValueIterator class permits to iterate over a QScriptValue's properties.
+
+ [Qt] QtScript should provide an API for enumerating a JS object's properties
+ https://bugs.webkit.org/show_bug.cgi?id=41680
+
+ * api/QtScript.pro:
+ * api/qscriptvalueiterator.cpp: Added.
+ (QScriptValueIterator::QScriptValueIterator):
+ (QScriptValueIterator::~QScriptValueIterator):
+ (QScriptValueIterator::hasNext):
+ (QScriptValueIterator::next):
+ (QScriptValueIterator::hasPrevious):
+ (QScriptValueIterator::previous):
+ (QScriptValueIterator::toFront):
+ (QScriptValueIterator::toBack):
+ (QScriptValueIterator::name):
+ (QScriptValueIterator::scriptName):
+ (QScriptValueIterator::value):
+ (QScriptValueIterator::setValue):
+ (QScriptValueIterator::remove):
+ (QScriptValueIterator::flags):
+ (QScriptValueIterator::operator=):
+ * api/qscriptvalueiterator.h: Added.
+ * api/qscriptvalueiterator_p.h: Added.
+ (QScriptValueIteratorPrivate::QScriptValueIteratorPrivate):
+ (QScriptValueIteratorPrivate::~QScriptValueIteratorPrivate):
+ (QScriptValueIteratorPrivate::hasNext):
+ (QScriptValueIteratorPrivate::next):
+ (QScriptValueIteratorPrivate::hasPrevious):
+ (QScriptValueIteratorPrivate::previous):
+ (QScriptValueIteratorPrivate::name):
+ (QScriptValueIteratorPrivate::scriptName):
+ (QScriptValueIteratorPrivate::value):
+ (QScriptValueIteratorPrivate::setValue):
+ (QScriptValueIteratorPrivate::remove):
+ (QScriptValueIteratorPrivate::toFront):
+ (QScriptValueIteratorPrivate::toBack):
+ (QScriptValueIteratorPrivate::flags):
+ (QScriptValueIteratorPrivate::isValid):
+ (QScriptValueIteratorPrivate::engine):
+ * tests/qscriptvalueiterator/qscriptvalueiterator.pro: Added.
+ * tests/qscriptvalueiterator/tst_qscriptvalueiterator.cpp: Added.
+ (tst_QScriptValueIterator::tst_QScriptValueIterator):
+ (tst_QScriptValueIterator::~tst_QScriptValueIterator):
+ (tst_QScriptValueIterator::iterateForward_data):
+ (tst_QScriptValueIterator::iterateForward):
+ (tst_QScriptValueIterator::iterateBackward_data):
+ (tst_QScriptValueIterator::iterateBackward):
+ (tst_QScriptValueIterator::iterateArray_data):
+ (tst_QScriptValueIterator::iterateArray):
+ (tst_QScriptValueIterator::iterateBackAndForth):
+ (tst_QScriptValueIterator::setValue):
+ (tst_QScriptValueIterator::remove):
+ (tst_QScriptValueIterator::removeMixed):
+ (tst_QScriptValueIterator::removeUndeletable):
+ (tst_QScriptValueIterator::iterateString):
+ (tst_QScriptValueIterator::assignObjectToIterator):
+ * tests/tests.pro:
+
2010-07-09 Jedrzej Nowacki <jedrzej.nowacki at nokia.com>
Reviewed by Simon Hausmann.
diff --git a/JavaScriptCore/qt/api/QtScript.pro b/JavaScriptCore/qt/api/QtScript.pro
index 3c2691e..fb49cfe 100644
--- a/JavaScriptCore/qt/api/QtScript.pro
+++ b/JavaScriptCore/qt/api/QtScript.pro
@@ -24,6 +24,7 @@ INCLUDEPATH += $$PWD/../../API
SOURCES += $$PWD/qscriptengine.cpp \
$$PWD/qscriptengine_p.cpp \
$$PWD/qscriptvalue.cpp \
+ $$PWD/qscriptvalueiterator.cpp \
$$PWD/qscriptstring.cpp \
$$PWD/qscriptprogram.cpp \
$$PWD/qscriptsyntaxcheckresult.cpp \
@@ -33,6 +34,8 @@ HEADERS += $$PWD/qtscriptglobal.h \
$$PWD/qscriptengine_p.h \
$$PWD/qscriptvalue.h \
$$PWD/qscriptvalue_p.h \
+ $$PWD/qscriptvalueiterator.h \
+ $$PWD/qscriptvalueiterator_p.h \
$$PWD/qscriptconverter_p.h \
$$PWD/qscriptstring.h \
$$PWD/qscriptstring_p.h \
diff --git a/JavaScriptCore/qt/api/qscriptvalueiterator.cpp b/JavaScriptCore/qt/api/qscriptvalueiterator.cpp
new file mode 100644
index 0000000..f1caa61
--- /dev/null
+++ b/JavaScriptCore/qt/api/qscriptvalueiterator.cpp
@@ -0,0 +1,226 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#include "qscriptvalueiterator.h"
+
+#include "qscriptvalue_p.h"
+#include "qscriptvalueiterator_p.h"
+
+/*!
+ \class QScriptValueIterator
+
+ \brief The QScriptValueIterator class provides a Java-style iterator for QScriptValue.
+
+ \ingroup script
+
+
+ The QScriptValueIterator constructor takes a QScriptValue as
+ argument. After construction, the iterator is located at the very
+ beginning of the sequence of properties. Here's how to iterate over
+ all the properties of a QScriptValue:
+
+ \snippet doc/src/snippets/code/src_script_qscriptvalueiterator.cpp 0
+
+ The next() advances the iterator. The name(), value() and flags()
+ functions return the name, value and flags of the last item that was
+ jumped over.
+
+ If you want to remove properties as you iterate over the
+ QScriptValue, use remove(). If you want to modify the value of a
+ property, use setValue().
+
+ Note that QScriptValueIterator only iterates over the QScriptValue's
+ own properties; i.e. it does not follow the prototype chain. You can
+ use a loop like this to follow the prototype chain:
+
+ \snippet doc/src/snippets/code/src_script_qscriptvalueiterator.cpp 1
+
+ Note that QScriptValueIterator will not automatically skip over
+ properties that have the QScriptValue::SkipInEnumeration flag set;
+ that flag only affects iteration in script code. If you want, you
+ can skip over such properties with code like the following:
+
+ \snippet doc/src/snippets/code/src_script_qscriptvalueiterator.cpp 2
+
+ \sa QScriptValue::property()
+*/
+
+/*!
+ Constructs an iterator for traversing \a object. The iterator is
+ set to be at the front of the sequence of properties (before the
+ first property).
+*/
+QScriptValueIterator::QScriptValueIterator(const QScriptValue& object)
+ : d_ptr(new QScriptValueIteratorPrivate(QScriptValuePrivate::get(object)))
+{}
+
+/*!
+ Destroys the iterator.
+*/
+QScriptValueIterator::~QScriptValueIterator()
+{}
+
+/*!
+ Returns true if there is at least one item ahead of the iterator
+ (i.e. the iterator is \e not at the back of the property sequence);
+ otherwise returns false.
+
+ \sa next(), hasPrevious()
+*/
+bool QScriptValueIterator::hasNext() const
+{
+ return d_ptr->hasNext();
+}
+
+/*!
+ Advances the iterator by one position.
+
+ Calling this function on an iterator located at the back of the
+ container leads to undefined results.
+
+ \sa hasNext(), previous(), name()
+*/
+void QScriptValueIterator::next()
+{
+ d_ptr->next();
+}
+
+/*!
+ Returns true if there is at least one item behind the iterator
+ (i.e. the iterator is \e not at the front of the property sequence);
+ otherwise returns false.
+
+ \sa previous(), hasNext()
+*/
+bool QScriptValueIterator::hasPrevious() const
+{
+ return d_ptr->hasPrevious();
+}
+
+/*!
+ Moves the iterator back by one position.
+
+ Calling this function on an iterator located at the front of the
+ container leads to undefined results.
+
+ \sa hasPrevious(), next(), name()
+*/
+void QScriptValueIterator::previous()
+{
+ d_ptr->previous();
+}
+
+/*!
+ Moves the iterator to the front of the QScriptValue (before the
+ first property).
+
+ \sa toBack(), next()
+*/
+void QScriptValueIterator::toFront()
+{
+ d_ptr->toFront();
+}
+
+/*!
+ Moves the iterator to the back of the QScriptValue (after the
+ last property).
+
+ \sa toFront(), previous()
+*/
+void QScriptValueIterator::toBack()
+{
+ d_ptr->toBack();
+}
+
+/*!
+ Returns the name of the last property that was jumped over using
+ next() or previous().
+
+ \sa value(), flags()
+*/
+QString QScriptValueIterator::name() const
+{
+ return d_ptr->name();
+}
+
+/*!
+ Returns the name of the last property that was jumped over using
+ next() or previous().
+*/
+QScriptString QScriptValueIterator::scriptName() const
+{
+ return QScriptStringPrivate::get(d_ptr->scriptName());
+}
+
+/*!
+ Returns the value of the last property that was jumped over using
+ next() or previous().
+
+ \sa setValue(), name()
+*/
+QScriptValue QScriptValueIterator::value() const
+{
+ return QScriptValuePrivate::get(d_ptr->value());
+}
+
+/*!
+ Sets the \a value of the last property that was jumped over using
+ next() or previous().
+
+ \sa value(), name()
+*/
+void QScriptValueIterator::setValue(const QScriptValue& value)
+{
+ d_ptr->setValue(QScriptValuePrivate::get(value));
+}
+
+/*!
+ Removes the last property that was jumped over using next()
+ or previous().
+
+ \sa setValue()
+*/
+void QScriptValueIterator::remove()
+{
+ d_ptr->remove();
+}
+
+/*!
+ Returns the flags of the last property that was jumped over using
+ next() or previous().
+
+ \sa value()
+*/
+QScriptValue::PropertyFlags QScriptValueIterator::flags() const
+{
+ return d_ptr->flags();
+}
+
+/*!
+ Makes the iterator operate on \a object. The iterator is set to be
+ at the front of the sequence of properties (before the first
+ property).
+*/
+QScriptValueIterator& QScriptValueIterator::operator=(QScriptValue& object)
+{
+ d_ptr = new QScriptValueIteratorPrivate(QScriptValuePrivate::get(object));
+ return *this;
+}
diff --git a/JavaScriptCore/qt/api/qscriptvalueiterator.h b/JavaScriptCore/qt/api/qscriptvalueiterator.h
new file mode 100644
index 0000000..0c90661
--- /dev/null
+++ b/JavaScriptCore/qt/api/qscriptvalueiterator.h
@@ -0,0 +1,63 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef qscriptvalueiterator_h
+#define qscriptvalueiterator_h
+
+#include "qtscriptglobal.h"
+#include "qscriptstring.h"
+#include <QtCore/qshareddata.h>
+#include "qscriptvalue.h"
+
+class QScriptValue;
+class QScriptValueIteratorPrivate;
+
+
+class Q_JAVASCRIPT_EXPORT QScriptValueIterator {
+public:
+ QScriptValueIterator(const QScriptValue& value);
+ ~QScriptValueIterator();
+
+ bool hasNext() const;
+ void next();
+
+ bool hasPrevious() const;
+ void previous();
+
+ QString name() const;
+ QScriptString scriptName() const;
+
+ QScriptValue value() const;
+ void setValue(const QScriptValue& value);
+
+ void remove();
+ QScriptValue::PropertyFlags flags() const;
+
+ void toFront();
+ void toBack();
+
+ QScriptValueIterator& operator=(QScriptValue& value);
+private:
+ QExplicitlySharedDataPointer<QScriptValueIteratorPrivate> d_ptr;
+
+ Q_DECLARE_PRIVATE(QScriptValueIterator)
+ Q_DISABLE_COPY(QScriptValueIterator)
+};
+
+#endif // qscriptvalueiterator_h
diff --git a/JavaScriptCore/qt/api/qscriptvalueiterator_p.h b/JavaScriptCore/qt/api/qscriptvalueiterator_p.h
new file mode 100644
index 0000000..66fc001
--- /dev/null
+++ b/JavaScriptCore/qt/api/qscriptvalueiterator_p.h
@@ -0,0 +1,206 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef qscriptvalueiterator_p_h
+#define qscriptvalueiterator_p_h
+
+#include "qscriptvalue_p.h"
+#include <JavaScriptCore/JavaScript.h>
+#include <JavaScriptCore/JSRetainPtr.h>
+#include <QtCore/qshareddata.h>
+#include <QtCore/qvector.h>
+
+class QScriptValueIteratorPrivate: public QSharedData {
+public:
+ inline QScriptValueIteratorPrivate(const QScriptValuePrivate* value);
+ inline ~QScriptValueIteratorPrivate();
+
+ inline bool hasNext();
+ inline void next();
+
+ inline bool hasPrevious();
+ inline void previous();
+
+ inline QString name() const;
+ inline QScriptStringPrivate* scriptName() const;
+
+ inline QScriptValuePrivate* value() const;
+ inline void setValue(const QScriptValuePrivate* value);
+
+ inline void remove();
+
+ inline void toFront();
+ inline void toBack();
+
+ QScriptValue::PropertyFlags flags() const;
+
+ inline bool isValid() const;
+private:
+ inline QScriptEnginePrivate* engine() const;
+
+ QExplicitlySharedDataPointer<QScriptValuePrivate> m_object;
+ QVector<JSStringRef> m_names;
+ QMutableVectorIterator<JSStringRef> m_idx;
+};
+
+inline QScriptValueIteratorPrivate::QScriptValueIteratorPrivate(const QScriptValuePrivate* value)
+ : m_object(const_cast<QScriptValuePrivate*>(value))
+ , m_idx(m_names)
+{
+ // FIXME There is assumption that global object wasn't changed (bug 41839).
+ // FIXME We can't use C API function JSObjectGetPropertyNames as it returns only enumerable properties.
+ if (const_cast<QScriptValuePrivate*>(value)->isObject()) {
+ static JSStringRef objectName = QScriptConverter::toString("Object");
+ static JSStringRef getOwnPropertyNamesName = QScriptConverter::toString("getOwnPropertyNames");
+
+ JSValueRef exception = 0;
+ JSObjectRef globalObject = JSContextGetGlobalObject(*engine());
+ Q_ASSERT(JSValueIsObject(*engine(), globalObject));
+ JSValueRef objectConstructor = JSObjectGetProperty(*engine(), globalObject, objectName, &exception);
+ Q_ASSERT(JSValueIsObject(*engine(), objectConstructor));
+ Q_ASSERT(!exception);
+ JSValueRef propertyNamesGetter = JSObjectGetProperty(*engine(), const_cast<JSObjectRef>(objectConstructor), getOwnPropertyNamesName, &exception);
+ Q_ASSERT(JSValueIsObject(*engine(), propertyNamesGetter));
+ Q_ASSERT(!exception);
+
+ JSValueRef arguments[] = { *m_object };
+ JSObjectRef propertyNames
+ = const_cast<JSObjectRef>(JSObjectCallAsFunction(*engine(),
+ const_cast<JSObjectRef>(propertyNamesGetter),
+ /* thisObject */ 0,
+ /* argumentCount */ 1,
+ arguments,
+ &exception));
+ Q_ASSERT(JSValueIsObject(*engine(), propertyNames));
+ Q_ASSERT(!exception);
+ static JSStringRef lengthName = QScriptConverter::toString("length");
+ int count = JSValueToNumber(*engine(), JSObjectGetProperty(*engine(), propertyNames, lengthName, &exception), &exception);
+
+ Q_ASSERT(!exception);
+ m_names.reserve(count);
+ for (int i = 0; i < count; ++i) {
+ JSValueRef tmp = JSObjectGetPropertyAtIndex(*engine(), propertyNames, i, &exception);
+ m_names.append(JSValueToStringCopy(*engine(), tmp, &exception));
+ Q_ASSERT(!exception);
+ }
+ m_idx = m_names;
+ } else
+ m_object = 0;
+}
+
+inline QScriptValueIteratorPrivate::~QScriptValueIteratorPrivate()
+{
+ QVector<JSStringRef>::const_iterator i = m_names.constBegin();
+ for (; i != m_names.constEnd(); ++i)
+ JSStringRelease(*i);
+}
+
+inline bool QScriptValueIteratorPrivate::hasNext()
+{
+ return m_idx.hasNext();
+}
+
+inline void QScriptValueIteratorPrivate::next()
+{
+ // FIXME (Qt5) This method should return a value (QTBUG-11226).
+ m_idx.next();
+}
+
+inline bool QScriptValueIteratorPrivate::hasPrevious()
+{
+ return m_idx.hasPrevious();
+}
+
+inline void QScriptValueIteratorPrivate::previous()
+{
+ m_idx.previous();
+}
+
+inline QString QScriptValueIteratorPrivate::name() const
+{
+ if (!isValid())
+ return QString();
+ return QScriptConverter::toString(m_idx.value());
+}
+
+inline QScriptStringPrivate* QScriptValueIteratorPrivate::scriptName() const
+{
+ if (!isValid())
+ return new QScriptStringPrivate();
+ return new QScriptStringPrivate(QScriptConverter::toString(m_idx.value()));
+}
+
+inline QScriptValuePrivate* QScriptValueIteratorPrivate::value() const
+{
+ if (!isValid())
+ return new QScriptValuePrivate();
+ JSValueRef exception = 0;
+ JSValueRef value = m_object->property(m_idx.value(), &exception);
+ engine()->setException(exception);
+ return new QScriptValuePrivate(engine(), value);
+}
+
+inline void QScriptValueIteratorPrivate::setValue(const QScriptValuePrivate* value)
+{
+ if (!isValid())
+ return;
+ JSValueRef exception = 0;
+ m_object->setProperty(m_idx.value(), *value, /* flags */ 0, &exception);
+ engine()->setException(exception);
+}
+
+inline void QScriptValueIteratorPrivate::remove()
+{
+ if (!isValid())
+ return;
+ JSValueRef exception = 0;
+ m_object->deleteProperty(m_idx.value(), &exception);
+ engine()->setException(exception);
+ m_idx.remove();
+}
+
+inline void QScriptValueIteratorPrivate::toFront()
+{
+ m_idx.toFront();
+}
+
+inline void QScriptValueIteratorPrivate::toBack()
+{
+ m_idx.toBack();
+}
+
+QScriptValue::PropertyFlags QScriptValueIteratorPrivate::flags() const
+{
+ if (!isValid())
+ return QScriptValue::PropertyFlags(0);
+ return m_object->propertyFlags(m_idx.value(), QScriptValue::ResolveLocal);
+}
+
+inline bool QScriptValueIteratorPrivate::isValid() const
+{
+ return m_object;
+}
+
+inline QScriptEnginePrivate* QScriptValueIteratorPrivate::engine() const
+{
+ Q_ASSERT(isValid());
+ return m_object->engine();
+}
+
+#endif // qscriptvalueiterator_p_h
diff --git a/JavaScriptCore/qt/tests/qscriptvalueiterator/qscriptvalueiterator.pro b/JavaScriptCore/qt/tests/qscriptvalueiterator/qscriptvalueiterator.pro
new file mode 100644
index 0000000..5314ec9
--- /dev/null
+++ b/JavaScriptCore/qt/tests/qscriptvalueiterator/qscriptvalueiterator.pro
@@ -0,0 +1,7 @@
+TEMPLATE = app
+TARGET = tst_qscriptvalueiterator
+QT += testlib
+include(../tests.pri)
+
+SOURCES += tst_qscriptvalueiterator.cpp
+
diff --git a/JavaScriptCore/qt/tests/qscriptvalueiterator/tst_qscriptvalueiterator.cpp b/JavaScriptCore/qt/tests/qscriptvalueiterator/tst_qscriptvalueiterator.cpp
new file mode 100644
index 0000000..43d0042
--- /dev/null
+++ b/JavaScriptCore/qt/tests/qscriptvalueiterator/tst_qscriptvalueiterator.cpp
@@ -0,0 +1,531 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef tst_qscriptvalueiterator_h
+#define tst_qscriptvalueiterator_h
+
+#include "qscriptengine.h"
+#include "qscriptvalue.h"
+#include "qscriptvalueiterator.h"
+#include <QtCore/qhash.h>
+#include <QtTest/QtTest>
+
+class tst_QScriptValueIterator : public QObject {
+ Q_OBJECT
+
+public:
+ tst_QScriptValueIterator();
+ virtual ~tst_QScriptValueIterator();
+
+private slots:
+ void iterateForward_data();
+ void iterateForward();
+ void iterateBackward_data();
+ void iterateBackward();
+ void iterateArray_data();
+ void iterateArray();
+ void iterateBackAndForth();
+ void setValue();
+ void remove();
+ void removeMixed();
+ void removeUndeletable();
+ void iterateString();
+ void assignObjectToIterator();
+};
+
+tst_QScriptValueIterator::tst_QScriptValueIterator()
+{
+}
+
+tst_QScriptValueIterator::~tst_QScriptValueIterator()
+{
+}
+
+void tst_QScriptValueIterator::iterateForward_data()
+{
+ QTest::addColumn<QStringList>("propertyNames");
+ QTest::addColumn<QStringList>("propertyValues");
+
+ QTest::newRow("no properties")
+ << QStringList() << QStringList();
+ QTest::newRow("foo=bar")
+ << (QStringList() << "foo")
+ << (QStringList() << "bar");
+ QTest::newRow("foo=bar, baz=123")
+ << (QStringList() << "foo" << "baz")
+ << (QStringList() << "bar" << "123");
+ QTest::newRow("foo=bar, baz=123, rab=oof")
+ << (QStringList() << "foo" << "baz" << "rab")
+ << (QStringList() << "bar" << "123" << "oof");
+}
+
+void tst_QScriptValueIterator::iterateForward()
+{
+ QFETCH(QStringList, propertyNames);
+ QFETCH(QStringList, propertyValues);
+ QMap<QString, QString> pmap;
+ Q_ASSERT(propertyNames.size() == propertyValues.size());
+
+ QScriptEngine engine;
+ QScriptValue object = engine.newObject();
+ for (int i = 0; i < propertyNames.size(); ++i) {
+ QString name = propertyNames.at(i);
+ QString value = propertyValues.at(i);
+ pmap.insert(name, value);
+ object.setProperty(name, QScriptValue(&engine, value));
+ }
+ QScriptValue otherObject = engine.newObject();
+ otherObject.setProperty("foo", QScriptValue(&engine, 123456));
+ otherObject.setProperty("protoProperty", QScriptValue(&engine, 654321));
+ object.setPrototype(otherObject); // should not affect iterator
+
+ QStringList lst;
+ QScriptValueIterator it(object);
+ while (!pmap.isEmpty()) {
+ QCOMPARE(it.hasNext(), true);
+ QCOMPARE(it.hasNext(), true);
+ it.next();
+ QString name = it.name();
+ QCOMPARE(pmap.contains(name), true);
+ QCOMPARE(it.name(), name);
+ QCOMPARE(it.flags(), object.propertyFlags(name));
+ QCOMPARE(it.value().strictlyEquals(QScriptValue(&engine, pmap.value(name))), true);
+ QCOMPARE(it.scriptName(), engine.toStringHandle(name));
+ pmap.remove(name);
+ lst.append(name);
+ }
+
+ QCOMPARE(it.hasNext(), false);
+ QCOMPARE(it.hasNext(), false);
+
+ it.toFront();
+ for (int i = 0; i < lst.count(); ++i) {
+ QCOMPARE(it.hasNext(), true);
+ it.next();
+ QCOMPARE(it.name(), lst.at(i));
+ }
+
+ for (int i = 0; i < lst.count(); ++i) {
+ QCOMPARE(it.hasPrevious(), true);
+ it.previous();
+ QCOMPARE(it.name(), lst.at(lst.count()-1-i));
+ }
+ QCOMPARE(it.hasPrevious(), false);
+}
+
+void tst_QScriptValueIterator::iterateBackward_data()
+{
+ iterateForward_data();
+}
+
+void tst_QScriptValueIterator::iterateBackward()
+{
+ QFETCH(QStringList, propertyNames);
+ QFETCH(QStringList, propertyValues);
+ QMap<QString, QString> pmap;
+ Q_ASSERT(propertyNames.size() == propertyValues.size());
+
+ QScriptEngine engine;
+ QScriptValue object = engine.newObject();
+ for (int i = 0; i < propertyNames.size(); ++i) {
+ QString name = propertyNames.at(i);
+ QString value = propertyValues.at(i);
+ pmap.insert(name, value);
+ object.setProperty(name, QScriptValue(&engine, value));
+ }
+
+ QStringList lst;
+ QScriptValueIterator it(object);
+ it.toBack();
+ while (!pmap.isEmpty()) {
+ QCOMPARE(it.hasPrevious(), true);
+ QCOMPARE(it.hasPrevious(), true);
+ it.previous();
+ QString name = it.name();
+ QCOMPARE(pmap.contains(name), true);
+ QCOMPARE(it.name(), name);
+ QCOMPARE(it.flags(), object.propertyFlags(name));
+ QCOMPARE(it.value().strictlyEquals(QScriptValue(&engine, pmap.value(name))), true);
+ pmap.remove(name);
+ lst.append(name);
+ }
+
+ QCOMPARE(it.hasPrevious(), false);
+ QCOMPARE(it.hasPrevious(), false);
+
+ it.toBack();
+ for (int i = 0; i < lst.count(); ++i) {
+ QCOMPARE(it.hasPrevious(), true);
+ it.previous();
+ QCOMPARE(it.name(), lst.at(i));
+ }
+
+ for (int i = 0; i < lst.count(); ++i) {
+ QCOMPARE(it.hasNext(), true);
+ it.next();
+ QCOMPARE(it.name(), lst.at(lst.count()-1-i));
+ }
+ QCOMPARE(it.hasNext(), false);
+}
+
+void tst_QScriptValueIterator::iterateArray_data()
+{
+ QTest::addColumn<QStringList>("inputPropertyNames");
+ QTest::addColumn<QStringList>("inputPropertyValues");
+ QTest::addColumn<QStringList>("propertyNames");
+ QTest::addColumn<QStringList>("propertyValues");
+ QTest::newRow("no elements") << QStringList() << QStringList() << QStringList() << QStringList();
+
+ QTest::newRow("0=foo, 1=barr")
+ << (QStringList() << "0" << "1")
+ << (QStringList() << "foo" << "bar")
+ << (QStringList() << "0" << "1")
+ << (QStringList() << "foo" << "bar");
+
+ QTest::newRow("0=foo, 3=barr")
+ << (QStringList() << "0" << "1" << "2" << "3")
+ << (QStringList() << "foo" << "" << "" << "bar")
+ << (QStringList() << "0" << "1" << "2" << "3")
+ << (QStringList() << "foo" << "" << "" << "bar");
+}
+
+void tst_QScriptValueIterator::iterateArray()
+{
+ QFETCH(QStringList, inputPropertyNames);
+ QFETCH(QStringList, inputPropertyValues);
+ QFETCH(QStringList, propertyNames);
+ QFETCH(QStringList, propertyValues);
+
+ QScriptEngine engine;
+ QScriptValue array = engine.newArray();
+ for (int i = 0; i < inputPropertyNames.size(); ++i)
+ array.setProperty(inputPropertyNames.at(i), inputPropertyValues.at(i));
+
+ int length = array.property("length").toInt32();
+ QCOMPARE(length, propertyNames.size());
+ QScriptValueIterator it(array);
+ for (int i = 0; i < length; ++i) {
+ QCOMPARE(it.hasNext(), true);
+ it.next();
+ QCOMPARE(it.name(), propertyNames.at(i));
+ QCOMPARE(it.flags(), array.propertyFlags(propertyNames.at(i)));
+ QVERIFY(it.value().strictlyEquals(array.property(propertyNames.at(i))));
+ QCOMPARE(it.value().toString(), propertyValues.at(i));
+ }
+ QVERIFY(it.hasNext());
+ it.next();
+ QCOMPARE(it.name(), QString::fromLatin1("length"));
+ QVERIFY(it.value().isNumber());
+ QCOMPARE(it.value().toInt32(), length);
+ QCOMPARE(it.flags(), QScriptValue::PropertyFlags(QScriptValue::SkipInEnumeration | QScriptValue::Undeletable));
+
+ it.previous();
+ QCOMPARE(it.hasPrevious(), length > 0);
+ for (int i = length - 1; i >= 0; --i) {
+ it.previous();
+ QCOMPARE(it.name(), propertyNames.at(i));
+ QCOMPARE(it.flags(), array.propertyFlags(propertyNames.at(i)));
+ QVERIFY(it.value().strictlyEquals(array.property(propertyNames.at(i))));
+ QCOMPARE(it.value().toString(), propertyValues.at(i));
+ QCOMPARE(it.hasPrevious(), i > 0);
+ }
+ QCOMPARE(it.hasPrevious(), false);
+
+ // hasNext() and hasPrevious() cache their result; verify that the result is in sync
+ if (length > 1) {
+ QVERIFY(it.hasNext());
+ it.next();
+ QCOMPARE(it.name(), QString::fromLatin1("0"));
+ QVERIFY(it.hasNext());
+ it.previous();
+ QCOMPARE(it.name(), QString::fromLatin1("0"));
+ QVERIFY(!it.hasPrevious());
+ it.next();
+ QCOMPARE(it.name(), QString::fromLatin1("0"));
+ QVERIFY(it.hasPrevious());
+ it.next();
+ QCOMPARE(it.name(), QString::fromLatin1("1"));
+ }
+ {
+ // same test as object:
+ QScriptValue originalArray = engine.newArray();
+ for (int i = 0; i < inputPropertyNames.size(); ++i)
+ originalArray.setProperty(inputPropertyNames.at(i), inputPropertyValues.at(i));
+
+ QScriptValue array = originalArray.toObject();
+ int length = array.property("length").toInt32();
+ QCOMPARE(length, propertyNames.size());
+ QScriptValueIterator it(array);
+ for (int i = 0; i < length; ++i) {
+ QCOMPARE(it.hasNext(), true);
+ it.next();
+ QCOMPARE(it.name(), propertyNames.at(i));
+ QCOMPARE(it.flags(), array.propertyFlags(propertyNames.at(i)));
+ QVERIFY(it.value().strictlyEquals(array.property(propertyNames.at(i))));
+ QCOMPARE(it.value().toString(), propertyValues.at(i));
+ }
+ QCOMPARE(it.hasNext(), true);
+ it.next();
+ QCOMPARE(it.name(), QString::fromLatin1("length"));
+ }
+}
+
+void tst_QScriptValueIterator::iterateBackAndForth()
+{
+ QScriptEngine engine;
+ {
+ QScriptValue object = engine.newObject();
+ object.setProperty("foo", QScriptValue(&engine, "bar"));
+ object.setProperty("rab", QScriptValue(&engine, "oof"),
+ QScriptValue::SkipInEnumeration); // should not affect iterator
+ QScriptValueIterator it(object);
+ QVERIFY(it.hasNext());
+ it.next();
+ QCOMPARE(it.name(), QLatin1String("foo"));
+ QVERIFY(it.hasPrevious());
+ it.previous();
+ QCOMPARE(it.name(), QLatin1String("foo"));
+ QVERIFY(it.hasNext());
+ it.next();
+ QCOMPARE(it.name(), QLatin1String("foo"));
+ QVERIFY(it.hasPrevious());
+ it.previous();
+ QCOMPARE(it.name(), QLatin1String("foo"));
+ QVERIFY(it.hasNext());
+ it.next();
+ QCOMPARE(it.name(), QLatin1String("foo"));
+ QVERIFY(it.hasNext());
+ it.next();
+ QCOMPARE(it.name(), QLatin1String("rab"));
+ QVERIFY(it.hasPrevious());
+ it.previous();
+ QCOMPARE(it.name(), QLatin1String("rab"));
+ QVERIFY(it.hasNext());
+ it.next();
+ QCOMPARE(it.name(), QLatin1String("rab"));
+ QVERIFY(it.hasPrevious());
+ it.previous();
+ QCOMPARE(it.name(), QLatin1String("rab"));
+ }
+ {
+ // hasNext() and hasPrevious() cache their result; verify that the result is in sync
+ QScriptValue object = engine.newObject();
+ object.setProperty("foo", QScriptValue(&engine, "bar"));
+ object.setProperty("rab", QScriptValue(&engine, "oof"));
+ QScriptValueIterator it(object);
+ QVERIFY(it.hasNext());
+ it.next();
+ QCOMPARE(it.name(), QString::fromLatin1("foo"));
+ QVERIFY(it.hasNext());
+ it.previous();
+ QCOMPARE(it.name(), QString::fromLatin1("foo"));
+ QVERIFY(!it.hasPrevious());
+ it.next();
+ QCOMPARE(it.name(), QString::fromLatin1("foo"));
+ QVERIFY(it.hasPrevious());
+ it.next();
+ QCOMPARE(it.name(), QString::fromLatin1("rab"));
+ }
+}
+
+void tst_QScriptValueIterator::setValue()
+{
+ QScriptEngine engine;
+ QScriptValue object = engine.newObject();
+ object.setProperty("foo", QScriptValue(&engine, "bar"));
+ QScriptValueIterator it(object);
+ it.next();
+ QCOMPARE(it.name(), QLatin1String("foo"));
+ it.setValue(QScriptValue(&engine, "baz"));
+ QCOMPARE(it.value().strictlyEquals(QScriptValue(&engine, QLatin1String("baz"))), true);
+ QCOMPARE(object.property("foo").toString(), QLatin1String("baz"));
+ it.setValue(QScriptValue(&engine, "zab"));
+ QCOMPARE(it.value().strictlyEquals(QScriptValue(&engine, QLatin1String("zab"))), true);
+ QCOMPARE(object.property("foo").toString(), QLatin1String("zab"));
+}
+
+void tst_QScriptValueIterator::remove()
+{
+ QScriptEngine engine;
+ QScriptValue object = engine.newObject();
+ object.setProperty("foo", QScriptValue(&engine, "bar"),
+ QScriptValue::SkipInEnumeration); // should not affect iterator
+ object.setProperty("rab", QScriptValue(&engine, "oof"));
+ QScriptValueIterator it(object);
+ it.next();
+ QCOMPARE(it.name(), QLatin1String("foo"));
+ it.remove();
+ QCOMPARE(it.hasPrevious(), false);
+ QCOMPARE(object.property("foo").isValid(), false);
+ QCOMPARE(object.property("rab").toString(), QLatin1String("oof"));
+ it.next();
+ QCOMPARE(it.name(), QLatin1String("rab"));
+ QCOMPARE(it.value().toString(), QLatin1String("oof"));
+ QCOMPARE(it.hasNext(), false);
+ it.remove();
+ QCOMPARE(object.property("rab").isValid(), false);
+ QCOMPARE(it.hasPrevious(), false);
+ QCOMPARE(it.hasNext(), false);
+}
+
+void tst_QScriptValueIterator::removeMixed()
+{
+ // This test checks if QScriptValueIterator behaives correctly if an object's property got deleted
+ // in different way.
+ QScriptEngine engine;
+ QScriptValue object = engine.evaluate("o = new Object; o");
+ object.setProperty("a", QScriptValue(124), QScriptValue::SkipInEnumeration);
+ object.setProperty("b", QScriptValue(816));
+ object.setProperty("c", QScriptValue(3264));
+ QScriptValueIterator it(object);
+ it.next();
+ it.next();
+ QCOMPARE(it.name(), QLatin1String("b"));
+ QCOMPARE(it.hasPrevious(), true);
+ QCOMPARE(it.hasNext(), true);
+ // Remove 'a'
+ object.setProperty("a", QScriptValue());
+ QEXPECT_FAIL("", "That would be a significant behavioral and performance change, new QtScript API should be developed (QTBUG-12087)", Abort);
+ QCOMPARE(it.hasPrevious(), false);
+ QCOMPARE(it.hasNext(), true);
+ // Remove 'c'
+ engine.evaluate("delete o.c");
+ QCOMPARE(it.hasPrevious(), false);
+ QCOMPARE(it.hasNext(), false);
+ // Remove 'b'
+ object.setProperty("b", QScriptValue());
+ QCOMPARE(it.hasPrevious(), false);
+ QCOMPARE(it.hasNext(), false);
+ QCOMPARE(it.name(), QString());
+ QCOMPARE(it.value().toString(), QString());
+
+ // Try to remove a removed property.
+ it.remove();
+ QCOMPARE(it.hasPrevious(), false);
+ QCOMPARE(it.hasNext(), false);
+ QCOMPARE(it.name(), QString());
+ QCOMPARE(it.value().toString(), QString());
+
+ for (int i = 0; i < 2; ++i) {
+ it.next();
+ QCOMPARE(it.hasPrevious(), false);
+ QCOMPARE(it.hasNext(), false);
+ QCOMPARE(it.name(), QString());
+ QCOMPARE(it.value().toString(), QString());
+ }
+
+ for (int i = 0; i < 2; ++i) {
+ it.previous();
+ QCOMPARE(it.hasPrevious(), false);
+ QCOMPARE(it.hasNext(), false);
+ QCOMPARE(it.name(), QString());
+ QCOMPARE(it.value().toString(), QString());
+ }
+}
+
+void tst_QScriptValueIterator::removeUndeletable()
+{
+ // Undeletable property can't be deleted via iterator.
+ QScriptEngine engine;
+ QScriptValue object = engine.evaluate("o = new Object; o");
+ object.setProperty("a", QScriptValue(&engine, 124));
+ object.setProperty("b", QScriptValue(&engine, 816), QScriptValue::Undeletable);
+ QVERIFY(object.property("b").isValid());
+ QScriptValueIterator it(object);
+ it.next();
+ it.next();
+ it.remove();
+ it.toFront();
+ QVERIFY(it.hasNext());
+ QVERIFY(object.property("b").isValid());
+}
+
+void tst_QScriptValueIterator::iterateString()
+{
+ QScriptEngine engine;
+ QScriptValue str = QScriptValue(&engine, QString::fromLatin1("ciao"));
+ QVERIFY(str.isString());
+ QScriptValue obj = str.toObject();
+ int length = obj.property("length").toInt32();
+ QCOMPARE(length, 4);
+ QScriptValueIterator it(obj);
+ for (int i = 0; i < length; ++i) {
+ QCOMPARE(it.hasNext(), true);
+ QString indexStr = QScriptValue(&engine, i).toString();
+ it.next();
+ QCOMPARE(it.name(), indexStr);
+ QCOMPARE(it.flags(), obj.propertyFlags(indexStr));
+ QCOMPARE(it.value().strictlyEquals(obj.property(indexStr)), true);
+ }
+ QVERIFY(it.hasNext());
+ it.next();
+ QCOMPARE(it.name(), QString::fromLatin1("length"));
+ QVERIFY(it.value().isNumber());
+ QCOMPARE(it.value().toInt32(), length);
+ QCOMPARE(it.flags(), QScriptValue::PropertyFlags(QScriptValue::ReadOnly | QScriptValue::SkipInEnumeration | QScriptValue::Undeletable));
+
+ it.previous();
+ QCOMPARE(it.hasPrevious(), length > 0);
+ for (int i = length - 1; i >= 0; --i) {
+ it.previous();
+ QString indexStr = QScriptValue(&engine, i).toString();
+ QCOMPARE(it.name(), indexStr);
+ QCOMPARE(it.flags(), obj.propertyFlags(indexStr));
+ QCOMPARE(it.value().strictlyEquals(obj.property(indexStr)), true);
+ QCOMPARE(it.hasPrevious(), i > 0);
+ }
+ QCOMPARE(it.hasPrevious(), false);
+}
+
+void tst_QScriptValueIterator::assignObjectToIterator()
+{
+ QScriptEngine eng;
+ QScriptValue obj1 = eng.newObject();
+ obj1.setProperty("foo", 123);
+ QScriptValue obj2 = eng.newObject();
+ obj2.setProperty("bar", 456);
+
+ QScriptValueIterator it(obj1);
+ QVERIFY(it.hasNext());
+ it.next();
+ it = obj2;
+ QVERIFY(it.hasNext());
+ it.next();
+ QCOMPARE(it.name(), QString::fromLatin1("bar"));
+
+ it = obj1;
+ QVERIFY(it.hasNext());
+ it.next();
+ QCOMPARE(it.name(), QString::fromLatin1("foo"));
+
+ it = obj2;
+ QVERIFY(it.hasNext());
+ it.next();
+ QCOMPARE(it.name(), QString::fromLatin1("bar"));
+
+ it = obj2;
+ QVERIFY(it.hasNext());
+ it.next();
+ QCOMPARE(it.name(), QString::fromLatin1("bar"));
+}
+
+QTEST_MAIN(tst_QScriptValueIterator)
+#include "tst_qscriptvalueiterator.moc"
+
+#endif // tst_qscriptvalueiterator_h
diff --git a/JavaScriptCore/qt/tests/tests.pro b/JavaScriptCore/qt/tests/tests.pro
index 7c3f590..6d5559b 100644
--- a/JavaScriptCore/qt/tests/tests.pro
+++ b/JavaScriptCore/qt/tests/tests.pro
@@ -1,4 +1,5 @@
TEMPLATE = subdirs
SUBDIRS = qscriptengine \
qscriptvalue \
+ qscriptvalueiterator \
qscriptstring
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list