From 5e621e494f4bf76fa53582a98f80c73009c3a1d3 Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Tue, 6 Jul 2021 19:41:54 +0300 Subject: [PATCH] LibJS: Implement Object.getOwnPropertyDescriptors() --- .../LibJS/Runtime/CommonPropertyNames.h | 1 + .../LibJS/Runtime/ObjectConstructor.cpp | 35 +++++++++++++++++++ .../LibJS/Runtime/ObjectConstructor.h | 1 + 3 files changed, 37 insertions(+) diff --git a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h index 6553e59444..da8e9fcfa4 100644 --- a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h +++ b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h @@ -156,6 +156,7 @@ namespace JS { P(getMinutes) \ P(getMonth) \ P(getOwnPropertyDescriptor) \ + P(getOwnPropertyDescriptors) \ P(getOwnPropertyNames) \ P(getOwnPropertySymbols) \ P(getPrototypeOf) \ diff --git a/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp b/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp index 65d506ada3..26255be9aa 100644 --- a/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp @@ -37,6 +37,7 @@ void ObjectConstructor::initialize(GlobalObject& global_object) define_native_function(vm.names.defineProperties, define_properties, 2, attr); define_native_function(vm.names.is, is, 2, attr); define_native_function(vm.names.getOwnPropertyDescriptor, get_own_property_descriptor, 2, attr); + define_native_function(vm.names.getOwnPropertyDescriptors, get_own_property_descriptors, 1, attr); define_native_function(vm.names.getOwnPropertyNames, get_own_property_names, 1, attr); define_native_function(vm.names.getOwnPropertySymbols, get_own_property_symbols, 1, attr); define_native_function(vm.names.getPrototypeOf, get_prototype_of, 1, attr); @@ -304,6 +305,40 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_descriptor) return from_property_descriptor(global_object, descriptor); } +// 20.1.2.9 Object.getOwnPropertyDescriptors ( O ), https://tc39.es/ecma262/#sec-object.getownpropertydescriptors +JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_descriptors) +{ + // 1. Let obj be ? ToObject(O). + auto* object = vm.argument(0).to_object(global_object); + if (vm.exception()) + return {}; + // 2. Let ownKeys be ? obj.[[OwnPropertyKeys]](). + auto own_keys = object->internal_own_property_keys(); + if (vm.exception()) + return {}; + // 3. Let descriptors be ! OrdinaryObjectCreate(%Object.prototype%). + auto* descriptors = Object::create(global_object, global_object.object_prototype()); + // 4. For each element key of ownKeys, do + for (auto& key : own_keys) { + auto property_name = PropertyName::from_value(global_object, key); + + // a. Let desc be ? obj.[[GetOwnProperty]](key). + auto desc = object->internal_get_own_property(property_name); + if (vm.exception()) + return {}; + + // b. Let descriptor be ! FromPropertyDescriptor(desc). + auto descriptor = from_property_descriptor(global_object, desc); + + // c. If descriptor is not undefined, perform ! CreateDataPropertyOrThrow(descriptors, key, descriptor). + if (!descriptor.is_undefined()) + descriptors->create_data_property_or_throw(property_name, descriptor); + } + + // 5. Return descriptors. + return descriptors; +} + // 20.1.2.4 Object.defineProperty ( O, P, Attributes ), https://tc39.es/ecma262/#sec-object.defineproperty JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::define_property) { diff --git a/Userland/Libraries/LibJS/Runtime/ObjectConstructor.h b/Userland/Libraries/LibJS/Runtime/ObjectConstructor.h index ad0f300708..f827357dd3 100644 --- a/Userland/Libraries/LibJS/Runtime/ObjectConstructor.h +++ b/Userland/Libraries/LibJS/Runtime/ObjectConstructor.h @@ -29,6 +29,7 @@ private: JS_DECLARE_NATIVE_FUNCTION(define_properties); JS_DECLARE_NATIVE_FUNCTION(is); JS_DECLARE_NATIVE_FUNCTION(get_own_property_descriptor); + JS_DECLARE_NATIVE_FUNCTION(get_own_property_descriptors); JS_DECLARE_NATIVE_FUNCTION(get_own_property_names); JS_DECLARE_NATIVE_FUNCTION(get_own_property_symbols); JS_DECLARE_NATIVE_FUNCTION(get_prototype_of);