Skip to content

Commit

Permalink
Implement Array.prototype.toLocaleString
Browse files Browse the repository at this point in the history
  • Loading branch information
jedel1043 committed Dec 11, 2022
1 parent 19481cd commit 08316e7
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 1 deletion.
68 changes: 68 additions & 0 deletions boa_engine/src/builtins/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub mod array_iterator;
#[cfg(test)]
mod tests;

use boa_macros::utf16;
use boa_profiler::Profiler;
use tap::{Conv, Pipe};

Expand Down Expand Up @@ -117,6 +118,7 @@ impl BuiltIn for Array {
.method(Self::some, "some", 1)
.method(Self::sort, "sort", 1)
.method(Self::splice, "splice", 2)
.method(Self::to_locale_string, "toLocaleString", 0)
.method(Self::reduce, "reduce", 1)
.method(Self::reduce_right, "reduceRight", 1)
.method(Self::keys, "keys", 0)
Expand Down Expand Up @@ -2027,6 +2029,72 @@ impl Array {
Ok(a.into())
}

/// [`Array.prototype.toLocaleString ( [ locales [ , options ] ] )`][spec].
///
/// Returns a string representing the elements of the array. The elements are converted to
/// strings using their `toLocaleString` methods and these strings are separated by a
/// locale-specific string (such as a comma ",").
///
/// More information:
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma402/#sup-array.prototype.tolocalestring
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toLocaleString
pub(crate) fn to_locale_string(
this: &JsValue,
args: &[JsValue],
context: &mut Context,
) -> JsResult<JsValue> {
// 1. Let array be ? ToObject(this value).
let array = this.to_object(context)?;
// 2. Let len be ? ToLength(? Get(array, "length")).
let len = array.length_of_array_like(context)?;

// 3. Let separator be the implementation-defined list-separator String value appropriate for the host environment's current locale (such as ", ").
let separator = {
#[cfg(feature = "intl")]
{
// TODO: this should eventually return a locale-sensitive separator.
utf16!(", ")
}

#[cfg(not(feature = "intl"))]
{
utf16!(", ")
}
};

// 4. Let R be the empty String.
let mut r = Vec::new();

// 5. Let k be 0.
// 6. Repeat, while k < len,
for k in 0..len {
// a. If k > 0, then
if k > 0 {
// i. Set R to the string-concatenation of R and separator.
r.extend_from_slice(separator);
}

// b. Let nextElement be ? Get(array, ! ToString(k)).
let next = array.get(k, context)?;

// c. If nextElement is not undefined or null, then
if !next.is_null_or_undefined() {
// i. Let S be ? ToString(? Invoke(nextElement, "toLocaleString", « locales, options »)).
let s = next
.invoke("toLocaleString", args, context)?
.to_string(context)?;

// ii. Set R to the string-concatenation of R and S.
r.extend_from_slice(&s);
}
// d. Increase k by 1.
}
// 7. Return R.
Ok(js_string!(r).into())
}

/// `Array.prototype.splice ( start, [deleteCount[, ...items]] )`
///
/// Splices an array by following
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/builtins/string/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1322,7 +1322,7 @@ impl String {
collator.compare_utf16(&s, &that_value) as i8
}

// Default to common comparison if the used doesn't have `Intl` enabled.
// Default to common comparison if the user doesn't have `Intl` enabled.
#[cfg(not(feature = "intl"))]
{
s.cmp(&that_value) as i8;
Expand Down
5 changes: 5 additions & 0 deletions boa_engine/src/object/operations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,11 @@ impl JsObject {
Ok(true)
}

/// Abstract operation [`LengthOfArrayLike ( obj )`][spec].
///
/// Returns the value of the "length" property of an array-like object.
///
/// [spec]: https://tc39.es/ecma262/#sec-lengthofarraylike
#[inline]
pub(crate) fn length_of_array_like(&self, context: &mut Context) -> JsResult<u64> {
// 1. Assert: Type(obj) is Object.
Expand Down

0 comments on commit 08316e7

Please sign in to comment.