From a44de7a55f0e0391bc0e7281cf6293ec0a29a761 Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Fri, 9 Jul 2021 23:11:14 +0300 Subject: [PATCH] LibJS: Add %TypedArray%.prototype.toLocaleString --- .../LibJS/Runtime/TypedArrayPrototype.cpp | 33 +++++++++++++++++ .../LibJS/Runtime/TypedArrayPrototype.h | 1 + .../TypedArray.prototype.toLocaleString.js | 37 +++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 Userland/Libraries/LibJS/Tests/builtins/TypedArray/TypedArray.prototype.toLocaleString.js diff --git a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp index a9c12c3540..7f190b7595 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp @@ -53,6 +53,7 @@ void TypedArrayPrototype::initialize(GlobalObject& object) define_native_function(vm.names.copyWithin, copy_within, 2, attr); define_native_function(vm.names.filter, filter, 1, attr); define_native_function(vm.names.map, map, 1, attr); + define_native_function(vm.names.toLocaleString, to_locale_string, 0, attr); define_native_accessor(*vm.well_known_symbol_to_string_tag(), to_string_tag_getter, nullptr, Attribute::Configurable); @@ -1452,4 +1453,36 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::map) return return_array; } +// 23.2.3.28 %TypedArray%.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.tolocalestring +JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::to_locale_string) +{ + auto* typed_array = validate_typed_array(global_object); + if (!typed_array) + return {}; + + auto length = typed_array->array_length(); + + StringBuilder builder; + for (u32 k = 0; k < length; ++k) { + if (k > 0) + builder.append(','); // NOTE: Until we implement ECMA-402 (Intl) this is implementation specific. + auto value = typed_array->get(k); + if (vm.exception()) + return {}; + if (value.is_nullish()) + continue; + auto* value_object = value.to_object(global_object); + if (!value_object) + return {}; + auto locale_string_result = value_object->invoke(vm.names.toLocaleString); + if (vm.exception()) + return {}; + auto string = locale_string_result.to_string(global_object); + if (vm.exception()) + return {}; + builder.append(string); + } + return js_string(vm, builder.to_string()); +} + } diff --git a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.h b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.h index 088551e712..af97c5a459 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.h +++ b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.h @@ -49,6 +49,7 @@ private: JS_DECLARE_NATIVE_FUNCTION(copy_within); JS_DECLARE_NATIVE_FUNCTION(filter); JS_DECLARE_NATIVE_FUNCTION(map); + JS_DECLARE_NATIVE_FUNCTION(to_locale_string); }; } diff --git a/Userland/Libraries/LibJS/Tests/builtins/TypedArray/TypedArray.prototype.toLocaleString.js b/Userland/Libraries/LibJS/Tests/builtins/TypedArray/TypedArray.prototype.toLocaleString.js new file mode 100644 index 0000000000..9114c1b079 --- /dev/null +++ b/Userland/Libraries/LibJS/Tests/builtins/TypedArray/TypedArray.prototype.toLocaleString.js @@ -0,0 +1,37 @@ +const TYPED_ARRAYS = [ + Uint8Array, + Uint8ClampedArray, + Uint16Array, + Uint32Array, + Int8Array, + Int16Array, + Int32Array, + Float32Array, + Float64Array, +]; + +const BIGINT_TYPED_ARRAYS = [BigUint64Array, BigInt64Array]; + +test("basic functionality", () => { + TYPED_ARRAYS.forEach(T => { + expect(T.prototype.toLocaleString).toHaveLength(0); + + const typedArray = new T(3); + typedArray[0] = 1; + typedArray[1] = 2; + typedArray[2] = 3; + + expect(typedArray.toLocaleString()).toBe("1,2,3"); + }); + + BIGINT_TYPED_ARRAYS.forEach(T => { + expect(T.prototype.toLocaleString).toLocaleString(0); + + const typedArray = new T(3); + typedArray[0] = 1n; + typedArray[1] = 2n; + typedArray[2] = 3n; + + expect(typedArray.toLocaleString()).toBe("1,2,3"); + }); +});