/src/serenity/Userland/Libraries/LibJS/Runtime/Iterator.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2020, Matthew Olsson <mattco@serenityos.org> |
3 | | * Copyright (c) 2022-2023, Linus Groh <linusg@serenityos.org> |
4 | | * Copyright (c) 2023-2024, Tim Flynn <trflynn89@ladybird.org> |
5 | | * |
6 | | * SPDX-License-Identifier: BSD-2-Clause |
7 | | */ |
8 | | |
9 | | #pragma once |
10 | | |
11 | | #include <AK/Function.h> |
12 | | #include <AK/Optional.h> |
13 | | #include <LibJS/Runtime/Completion.h> |
14 | | #include <LibJS/Runtime/Object.h> |
15 | | #include <LibJS/Runtime/Value.h> |
16 | | |
17 | | namespace JS { |
18 | | |
19 | | // 7.4.1 Iterator Records, https://tc39.es/ecma262/#sec-iterator-records |
20 | | class IteratorRecord final : public Object { |
21 | | JS_OBJECT(IteratorRecord, Object); |
22 | | JS_DECLARE_ALLOCATOR(IteratorRecord); |
23 | | |
24 | | public: |
25 | | IteratorRecord(Realm& realm, GCPtr<Object> iterator, Value next_method, bool done) |
26 | 0 | : Object(ConstructWithoutPrototypeTag::Tag, realm) |
27 | 0 | , iterator(iterator) |
28 | 0 | , next_method(next_method) |
29 | 0 | , done(done) |
30 | 0 | { |
31 | 0 | } |
32 | | |
33 | | GCPtr<Object> iterator; // [[Iterator]] |
34 | | Value next_method; // [[NextMethod]] |
35 | | bool done { false }; // [[Done]] |
36 | | |
37 | | private: |
38 | | virtual void visit_edges(Cell::Visitor&) override; |
39 | 0 | virtual bool is_iterator_record() const override { return true; } |
40 | | }; |
41 | | |
42 | | template<> |
43 | 0 | inline bool Object::fast_is<IteratorRecord>() const { return is_iterator_record(); } |
44 | | |
45 | | class Iterator : public Object { |
46 | | JS_OBJECT(Iterator, Object); |
47 | | JS_DECLARE_ALLOCATOR(Iterator); |
48 | | |
49 | | public: |
50 | | static NonnullGCPtr<Iterator> create(Realm&, Object& prototype, NonnullGCPtr<IteratorRecord> iterated); |
51 | | |
52 | 0 | IteratorRecord const& iterated() const { return m_iterated; } |
53 | | |
54 | | private: |
55 | | Iterator(Object& prototype, NonnullGCPtr<IteratorRecord> iterated); |
56 | | explicit Iterator(Object& prototype); |
57 | | |
58 | | virtual void visit_edges(Cell::Visitor&) override; |
59 | | |
60 | | NonnullGCPtr<IteratorRecord> m_iterated; // [[Iterated]] |
61 | | }; |
62 | | |
63 | | enum class IteratorHint { |
64 | | Sync, |
65 | | Async, |
66 | | }; |
67 | | |
68 | | enum class PrimitiveHandling { |
69 | | IterateStringPrimitives, |
70 | | RejectPrimitives, |
71 | | }; |
72 | | |
73 | | ThrowCompletionOr<NonnullGCPtr<IteratorRecord>> get_iterator_direct(VM&, Object&); |
74 | | ThrowCompletionOr<NonnullGCPtr<IteratorRecord>> get_iterator_from_method(VM&, Value, NonnullGCPtr<FunctionObject>); |
75 | | ThrowCompletionOr<NonnullGCPtr<IteratorRecord>> get_iterator(VM&, Value, IteratorHint); |
76 | | ThrowCompletionOr<NonnullGCPtr<IteratorRecord>> get_iterator_flattenable(VM&, Value, PrimitiveHandling); |
77 | | ThrowCompletionOr<NonnullGCPtr<Object>> iterator_next(VM&, IteratorRecord&, Optional<Value> = {}); |
78 | | ThrowCompletionOr<bool> iterator_complete(VM&, Object& iterator_result); |
79 | | ThrowCompletionOr<Value> iterator_value(VM&, Object& iterator_result); |
80 | | ThrowCompletionOr<GCPtr<Object>> iterator_step(VM&, IteratorRecord&); |
81 | | ThrowCompletionOr<Optional<Value>> iterator_step_value(VM&, IteratorRecord&); |
82 | | Completion iterator_close(VM&, IteratorRecord const&, Completion); |
83 | | Completion async_iterator_close(VM&, IteratorRecord const&, Completion); |
84 | | NonnullGCPtr<Object> create_iterator_result_object(VM&, Value, bool done); |
85 | | ThrowCompletionOr<MarkedVector<Value>> iterator_to_list(VM&, IteratorRecord&); |
86 | | ThrowCompletionOr<void> setter_that_ignores_prototype_properties(VM&, Value this_, Object const& home, PropertyKey const& property, Value value); |
87 | | |
88 | | using IteratorValueCallback = Function<Optional<Completion>(Value)>; |
89 | | Completion get_iterator_values(VM&, Value iterable, IteratorValueCallback callback); |
90 | | |
91 | | } |