diff options
5 files changed, 44 insertions, 15 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h index 9f38eb08a5..d17dd77527 100644 --- a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h +++ b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h @@ -137,6 +137,7 @@ namespace JS { P(getMonth) \ P(getOwnPropertyDescriptor) \ P(getOwnPropertyNames) \ + P(getOwnPropertySymbols) \ P(getPrototypeOf) \ P(getSeconds) \ P(getTime) \ diff --git a/Userland/Libraries/LibJS/Runtime/Object.cpp b/Userland/Libraries/LibJS/Runtime/Object.cpp index 29df7bf2c3..d9867e51c5 100644 --- a/Userland/Libraries/LibJS/Runtime/Object.cpp +++ b/Userland/Libraries/LibJS/Runtime/Object.cpp @@ -307,23 +307,25 @@ MarkedValueList Object::get_own_properties(PropertyKind kind, bool only_enumerab return properties; } - for (auto& entry : m_indexed_properties) { - auto value_and_attributes = entry.value_and_attributes(const_cast<Object*>(this)); - if (only_enumerable_properties && !value_and_attributes.attributes.is_enumerable()) - continue; + if (return_type != GetOwnPropertyReturnType::SymbolOnly) { + for (auto& entry : m_indexed_properties) { + auto value_and_attributes = entry.value_and_attributes(const_cast<Object*>(this)); + if (only_enumerable_properties && !value_and_attributes.attributes.is_enumerable()) + continue; - if (kind == PropertyKind::Key) { - properties.append(js_string(vm(), String::number(entry.index()))); - } else if (kind == PropertyKind::Value) { - properties.append(value_and_attributes.value); - } else { - auto* entry_array = Array::create(global_object()); - entry_array->define_property(0, js_string(vm(), String::number(entry.index()))); - entry_array->define_property(1, value_and_attributes.value); - properties.append(entry_array); + if (kind == PropertyKind::Key) { + properties.append(js_string(vm(), String::number(entry.index()))); + } else if (kind == PropertyKind::Value) { + properties.append(value_and_attributes.value); + } else { + auto* entry_array = Array::create(global_object()); + entry_array->define_property(0, js_string(vm(), String::number(entry.index()))); + entry_array->define_property(1, value_and_attributes.value); + properties.append(entry_array); + } + if (vm().exception()) + return MarkedValueList { heap() }; } - if (vm().exception()) - return MarkedValueList { heap() }; } auto add_property_to_results = [&](auto& property) { diff --git a/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp b/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp index b2d1c81435..489335fa28 100644 --- a/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp @@ -33,6 +33,7 @@ void ObjectConstructor::initialize(GlobalObject& global_object) 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.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); define_native_function(vm.names.setPrototypeOf, set_prototype_of, 2, attr); define_native_function(vm.names.isExtensible, is_extensible, 1, attr); @@ -74,6 +75,14 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_names) return Array::create_from(global_object, object->get_own_properties(PropertyKind::Key, false, GetOwnPropertyReturnType::StringOnly)); } +JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_symbols) +{ + auto* object = vm.argument(0).to_object(global_object); + if (vm.exception()) + return {}; + return Array::create_from(global_object, object->get_own_properties(PropertyKind::Key, false, GetOwnPropertyReturnType::SymbolOnly)); +} + JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_prototype_of) { auto* object = vm.argument(0).to_object(global_object); diff --git a/Userland/Libraries/LibJS/Runtime/ObjectConstructor.h b/Userland/Libraries/LibJS/Runtime/ObjectConstructor.h index 192f8a0267..27e6456d12 100644 --- a/Userland/Libraries/LibJS/Runtime/ObjectConstructor.h +++ b/Userland/Libraries/LibJS/Runtime/ObjectConstructor.h @@ -30,6 +30,7 @@ private: JS_DECLARE_NATIVE_FUNCTION(is); JS_DECLARE_NATIVE_FUNCTION(get_own_property_descriptor); JS_DECLARE_NATIVE_FUNCTION(get_own_property_names); + JS_DECLARE_NATIVE_FUNCTION(get_own_property_symbols); JS_DECLARE_NATIVE_FUNCTION(get_prototype_of); JS_DECLARE_NATIVE_FUNCTION(set_prototype_of); JS_DECLARE_NATIVE_FUNCTION(is_extensible); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Object/Object.getOwnPropertySymbols.js b/Userland/Libraries/LibJS/Tests/builtins/Object/Object.getOwnPropertySymbols.js new file mode 100644 index 0000000000..f431cd07b6 --- /dev/null +++ b/Userland/Libraries/LibJS/Tests/builtins/Object/Object.getOwnPropertySymbols.js @@ -0,0 +1,16 @@ +test("use with array", () => { + let names = Object.getOwnPropertySymbols([1, 2, 3]); + console.log(names); + expect(names).toEqual([]); +}); + +test("use with object", () => { + let names = Object.getOwnPropertySymbols({ [Symbol.iterator]: 1, [Symbol.species]: 2 }); + expect(names).toEqual([Symbol.iterator, Symbol.species]); +}); + +test("use with object with string keys", () => { + let symbol = Symbol("bar"); + let names = Object.getOwnPropertySymbols({ foo: 1, [symbol]: 2, baz: 3 }); + expect(names).toEqual([symbol]); +}); |