ladybird/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatFunction.cpp
Timothy Flynn 67f3de2320 LibJS+LibLocale: Begin replacing number formatting with ICU
This uses ICU for the Intl.NumberFormat `format` and `formatToParts`
prototypes. It does not yet port the range formatter prototypes.

Most of the new code in LibLocale/NumberFormat is simply mapping from
ECMA-402 types to ICU types. Beyond that, the only algorithmic change is
that we have to mutate the output from ICU for `formatToParts` to match
what is expected by ECMA-402. This is explained in NumberFormat.cpp in
`flatten_partitions`.

This lets us remove most data from our number format generator. All that
remains are numbering system digits and symbols, which are relied upon
still for other interfaces (e.g. Intl.DateTimeFormat). So they will be
removed in a future patch.

Note: All of the changes to the test files in this patch are now aligned
with both Chrome and Safari.
2024-06-10 13:51:51 +02:00

59 lines
1.8 KiB
C++

/*
* Copyright (c) 2021-2024, Tim Flynn <trflynn89@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibJS/Runtime/GlobalObject.h>
#include <LibJS/Runtime/Intl/NumberFormat.h>
#include <LibJS/Runtime/Intl/NumberFormatFunction.h>
namespace JS::Intl {
JS_DEFINE_ALLOCATOR(NumberFormatFunction);
// 15.5.2 Number Format Functions, https://tc39.es/ecma402/#sec-number-format-functions
NonnullGCPtr<NumberFormatFunction> NumberFormatFunction::create(Realm& realm, NumberFormat& number_format)
{
return realm.heap().allocate<NumberFormatFunction>(realm, number_format, realm.intrinsics().function_prototype());
}
NumberFormatFunction::NumberFormatFunction(NumberFormat& number_format, Object& prototype)
: NativeFunction(prototype)
, m_number_format(number_format)
{
}
void NumberFormatFunction::initialize(Realm& realm)
{
auto& vm = this->vm();
Base::initialize(realm);
define_direct_property(vm.names.length, Value(1), Attribute::Configurable);
define_direct_property(vm.names.name, PrimitiveString::create(vm, String {}), Attribute::Configurable);
}
ThrowCompletionOr<Value> NumberFormatFunction::call()
{
auto& vm = this->vm();
// 1. Let nf be F.[[NumberFormat]].
// 2. Assert: Type(nf) is Object and nf has an [[InitializedNumberFormat]] internal slot.
// 3. If value is not provided, let value be undefined.
auto value = vm.argument(0);
// 4. Let x be ? ToIntlMathematicalValue(value).
auto mathematical_value = TRY(to_intl_mathematical_value(vm, value));
// 5. Return ? FormatNumeric(nf, x).
auto formatted = format_numeric(m_number_format, move(mathematical_value));
return PrimitiveString::create(vm, move(formatted));
}
void NumberFormatFunction::visit_edges(Cell::Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(m_number_format);
}
}