aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsapi
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2023-09-12 12:16:47 +0200
committerUlf Hermann <ulf.hermann@qt.io>2023-09-21 10:11:05 +0200
commita173d50a9e54d2a21a5207f6c66bb54bb8f3a612 (patch)
tree4b433bf9a693da88dbb7e5d995adbf996dd79b20 /src/qml/jsapi
parentaf24ed58c250cce32e8d2dc12cfc36de79706f92 (diff)
QmlCompiler: Implement GetIterator and IteratorNext
Each GetIterator generates * A unique iterator variable that keeps track of the current index * In the case of for...of a copy of reference to the list being iterated The result register holds a pointer to the unique iterator so that it can be loaded and stored without resetting it. In order to do anything meaningful with iterators (in the tests) we also need to allow LoadElement with our "optional" types. That is a conversion of undefined and some other type to QVariant or QJSPrimitiveValue. This follows the same pattern as the other "optional"s we already have. For...of is currently not testable because it requires exception handlers. The tests will be added once we get exception handlers. Task-number: QTBUG-116725 Change-Id: I167fe16b983dc34bf86e1840dfcbf2bf682eecc1 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/jsapi')
-rw-r--r--src/qml/jsapi/qjslist.h63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/qml/jsapi/qjslist.h b/src/qml/jsapi/qjslist.h
index aeba3ec4b2..f55d669a41 100644
--- a/src/qml/jsapi/qjslist.h
+++ b/src/qml/jsapi/qjslist.h
@@ -43,6 +43,17 @@ struct QJSList : private QJSListIndexClamp
QJSList(List *list, QJSEngine *engine) : m_list(list), m_engine(engine) {}
+ Value at(int index) const
+ {
+ Q_ASSERT(index >= 0 && index < size());
+ return *(m_list->cbegin() + index);
+ }
+
+ int size() const
+ {
+ return int(std::min(m_list->size(), qsizetype(std::numeric_limits<int>::max())));
+ }
+
void resize(int size)
{
m_list->resize(size);
@@ -157,6 +168,17 @@ struct QJSList<QQmlListProperty<QObject>, QObject *> : private QJSListIndexClam
QJSList(QQmlListProperty<QObject> *list, QJSEngine *engine) : m_list(list), m_engine(engine) {}
+ QObject *at(int index) const
+ {
+ Q_ASSERT(index >= 0 && index < size());
+ return m_list->at(m_list, index);
+ }
+
+ int size() const
+ {
+ return int(std::min(m_list->count(m_list), qsizetype(std::numeric_limits<int>::max())));
+ }
+
void resize(int size)
{
qsizetype current = m_list->count(m_list);
@@ -308,6 +330,47 @@ private:
QJSEngine *m_engine = nullptr;
};
+struct QJSListForInIterator
+{
+public:
+ using Ptr = QJSListForInIterator *;
+ template<typename List, typename Value>
+ void init(const QJSList<List, Value> &list)
+ {
+ m_index = 0;
+ m_size = list.size();
+ }
+
+ bool hasNext() const { return m_index < m_size; }
+ int next() { return m_index++; }
+
+private:
+ int m_index;
+ int m_size;
+};
+
+// QJSListForInIterator must not require initialization so that we can jump over it with goto.
+static_assert(std::is_trivial_v<QJSListForInIterator>);
+
+struct QJSListForOfIterator
+{
+public:
+ using Ptr = QJSListForOfIterator *;
+ void init() { m_index = 0; }
+
+ template<typename List, typename Value>
+ bool hasNext(const QJSList<List, Value> &list) const { return m_index < list.size(); }
+
+ template<typename List, typename Value>
+ Value next(const QJSList<List, Value> &list) { return list.at(m_index++); }
+
+private:
+ int m_index;
+};
+
+// QJSListForOfIterator must not require initialization so that we can jump over it with goto.
+static_assert(std::is_trivial_v<QJSListForOfIterator>);
+
QT_END_NAMESPACE
#endif // QJSLIST_H