mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-02 12:30:31 +00:00
LibJS: Implement the EnumerateObjectProperties AO
This commit is contained in:
parent
9711e1b303
commit
9cfbbfd8d8
Notes:
sideshowbarker
2024-07-17 16:34:44 +09:00
Author: https://github.com/IdanHo Commit: https://github.com/SerenityOS/serenity/commit/9cfbbfd8d8 Pull-request: https://github.com/SerenityOS/serenity/pull/13322 Reviewed-by: https://github.com/davidot ✅ Reviewed-by: https://github.com/linusg ✅
2 changed files with 43 additions and 0 deletions
|
@ -1155,6 +1155,45 @@ ThrowCompletionOr<Object*> Object::define_properties(Value properties)
|
|||
return this;
|
||||
}
|
||||
|
||||
// 14.7.5.9 EnumerateObjectProperties ( O ), https://tc39.es/ecma262/#sec-enumerate-object-properties
|
||||
Optional<Completion> Object::enumerate_object_properties(Function<Optional<Completion>(Value)> callback) const
|
||||
{
|
||||
// 1. Return an Iterator object (27.1.1.2) whose next method iterates over all the String-valued keys of enumerable properties of O. The iterator object is never directly accessible to ECMAScript code. The mechanics and order of enumerating the properties is not specified but must conform to the rules specified below.
|
||||
// * Returned property keys do not include keys that are Symbols.
|
||||
// * Properties of the target object may be deleted during enumeration.
|
||||
// * A property that is deleted before it is processed is ignored.
|
||||
// * If new properties are added to the target object during enumeration, the newly added properties are not guaranteed to be processed in the active enumeration.
|
||||
// * A property name will be returned at most once in any enumeration.
|
||||
// * Enumerating the properties of the target object includes enumerating properties of its prototype, and the prototype of the prototype, and so on, recursively.
|
||||
// * A property of a prototype is not processed if it has the same name as a property that has already been processed.
|
||||
|
||||
HashTable<FlyString> visited;
|
||||
|
||||
auto const* target = this;
|
||||
while (target) {
|
||||
auto own_keys = TRY(target->internal_own_property_keys());
|
||||
for (auto& key : own_keys) {
|
||||
if (!key.is_string())
|
||||
continue;
|
||||
FlyString property_key = key.as_string().string();
|
||||
if (visited.contains(property_key))
|
||||
continue;
|
||||
auto descriptor = TRY(target->internal_get_own_property(property_key));
|
||||
if (!descriptor.has_value())
|
||||
continue;
|
||||
visited.set(property_key);
|
||||
if (!*descriptor->enumerable)
|
||||
continue;
|
||||
if (auto completion = callback(key); completion.has_value())
|
||||
return completion.release_value();
|
||||
}
|
||||
|
||||
target = TRY(target->internal_get_prototype_of());
|
||||
};
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void Object::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Cell::visit_edges(visitor);
|
||||
|
|
|
@ -136,6 +136,10 @@ public:
|
|||
|
||||
ThrowCompletionOr<Object*> define_properties(Value properties);
|
||||
|
||||
// 14.7.5 The for-in, for-of, and for-await-of Statements
|
||||
|
||||
Optional<Completion> enumerate_object_properties(Function<Optional<Completion>(Value)>) const;
|
||||
|
||||
// Implementation-specific storage abstractions
|
||||
|
||||
Optional<ValueAndAttributes> storage_get(PropertyKey const&) const;
|
||||
|
|
Loading…
Reference in a new issue