From b0c8543b285ced9c123e6be08670a4546eb7b8a3 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Fri, 11 Aug 2023 07:50:34 -0400 Subject: [PATCH] LibJS: Compute NumberFormat's rounding priority during construction This is an editorial change in the ECMA-402 spec. See: https://github.com/tc39/ecma402/commit/c28118e --- .../LibJS/Runtime/Intl/NumberFormat.cpp | 14 ++++++++ .../LibJS/Runtime/Intl/NumberFormat.h | 34 +++++++++++++------ .../Runtime/Intl/NumberFormatConstructor.cpp | 14 ++++++++ .../Runtime/Intl/NumberFormatPrototype.cpp | 21 ++---------- 4 files changed, 53 insertions(+), 30 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp index 550cc3fc8a..4fcab40a93 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp @@ -171,6 +171,20 @@ StringView NumberFormatBase::rounding_type_string() const } } +StringView NumberFormatBase::computed_rounding_priority_string() const +{ + switch (m_computed_rounding_priority) { + case ComputedRoundingPriority::Auto: + return "auto"sv; + case ComputedRoundingPriority::MorePrecision: + return "morePrecision"sv; + case ComputedRoundingPriority::LessPrecision: + return "lessPrecision"sv; + default: + VERIFY_NOT_REACHED(); + } +} + StringView NumberFormatBase::rounding_mode_string() const { switch (m_rounding_mode) { diff --git a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.h b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.h index 728d1e7d25..5f66127d88 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.h +++ b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.h @@ -29,6 +29,13 @@ public: LessPrecision, }; + enum class ComputedRoundingPriority { + Invalid, + Auto, + MorePrecision, + LessPrecision, + }; + enum class RoundingMode { Invalid, Ceil, @@ -87,6 +94,10 @@ public: StringView rounding_type_string() const; void set_rounding_type(RoundingType rounding_type) { m_rounding_type = rounding_type; } + ComputedRoundingPriority computed_rounding_priority() const { return m_computed_rounding_priority; } + StringView computed_rounding_priority_string() const; + void set_computed_rounding_priority(ComputedRoundingPriority computed_rounding_priority) { m_computed_rounding_priority = computed_rounding_priority; } + RoundingMode rounding_mode() const { return m_rounding_mode; } StringView rounding_mode_string() const; void set_rounding_mode(StringView rounding_mode); @@ -102,17 +113,18 @@ protected: explicit NumberFormatBase(Object& prototype); private: - String m_locale; // [[Locale]] - String m_data_locale; // [[DataLocale]] - int m_min_integer_digits { 0 }; // [[MinimumIntegerDigits]] - Optional m_min_fraction_digits {}; // [[MinimumFractionDigits]] - Optional m_max_fraction_digits {}; // [[MaximumFractionDigits]] - Optional m_min_significant_digits {}; // [[MinimumSignificantDigits]] - Optional m_max_significant_digits {}; // [[MaximumSignificantDigits]] - RoundingType m_rounding_type { RoundingType::Invalid }; // [[RoundingType]] - RoundingMode m_rounding_mode { RoundingMode::Invalid }; // [[RoundingMode]] - int m_rounding_increment { 1 }; // [[RoundingIncrement]] - TrailingZeroDisplay m_trailing_zero_display { TrailingZeroDisplay::Invalid }; // [[TrailingZeroDisplay]] + String m_locale; // [[Locale]] + String m_data_locale; // [[DataLocale]] + int m_min_integer_digits { 0 }; // [[MinimumIntegerDigits]] + Optional m_min_fraction_digits {}; // [[MinimumFractionDigits]] + Optional m_max_fraction_digits {}; // [[MaximumFractionDigits]] + Optional m_min_significant_digits {}; // [[MinimumSignificantDigits]] + Optional m_max_significant_digits {}; // [[MaximumSignificantDigits]] + RoundingType m_rounding_type { RoundingType::Invalid }; // [[RoundingType]] + ComputedRoundingPriority m_computed_rounding_priority { ComputedRoundingPriority::Invalid }; // [[ComputedRoundingPriority]] + RoundingMode m_rounding_mode { RoundingMode::Invalid }; // [[RoundingMode]] + int m_rounding_increment { 1 }; // [[RoundingIncrement]] + TrailingZeroDisplay m_trailing_zero_display { TrailingZeroDisplay::Invalid }; // [[TrailingZeroDisplay]] }; class NumberFormat final : public NumberFormatBase { diff --git a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatConstructor.cpp b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatConstructor.cpp index 1badcae7ab..9990c5ba02 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatConstructor.cpp @@ -370,27 +370,41 @@ ThrowCompletionOr set_number_format_digit_options(VM& vm, NumberFormatBase // e. Set intlObj.[[RoundingType]] to morePrecision. intl_object.set_rounding_type(NumberFormatBase::RoundingType::MorePrecision); + + // f. Set intlObj.[[ComputedRoundingPriority]] to "morePrecision". + intl_object.set_computed_rounding_priority(NumberFormatBase::ComputedRoundingPriority::MorePrecision); } // 27. Else if roundingPriority is "morePrecision", then else if (rounding_priority == "morePrecision"sv) { // a. Set intlObj.[[RoundingType]] to morePrecision. intl_object.set_rounding_type(NumberFormatBase::RoundingType::MorePrecision); + // b. Set intlObj.[[ComputedRoundingPriority]] to "morePrecision". + intl_object.set_computed_rounding_priority(NumberFormatBase::ComputedRoundingPriority::MorePrecision); } // 28. Else if roundingPriority is "lessPrecision", then else if (rounding_priority == "lessPrecision"sv) { // a. Set intlObj.[[RoundingType]] to lessPrecision. intl_object.set_rounding_type(NumberFormatBase::RoundingType::LessPrecision); + + // b. Set intlObj.[[ComputedRoundingPriority]] to "lessPrecision". + intl_object.set_computed_rounding_priority(NumberFormatBase::ComputedRoundingPriority::LessPrecision); } // 29. Else if hasSd is true, then else if (has_significant_digits) { // a. Set intlObj.[[RoundingType]] to significantDigits. intl_object.set_rounding_type(NumberFormatBase::RoundingType::SignificantDigits); + + // b. Set intlObj.[[ComputedRoundingPriority]] to "auto". + intl_object.set_computed_rounding_priority(NumberFormatBase::ComputedRoundingPriority::Auto); } // 30. Else, else { // a. Set intlObj.[[RoundingType]] to fractionDigits. intl_object.set_rounding_type(NumberFormatBase::RoundingType::FractionDigits); + + // b. Set intlObj.[[ComputedRoundingPriority]] to "auto". + intl_object.set_computed_rounding_priority(NumberFormatBase::ComputedRoundingPriority::Auto); } // 31. If roundingIncrement is not 1, then diff --git a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.cpp index 0b955f51cc..544c1ddc1e 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.cpp @@ -180,26 +180,9 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::resolved_options) MUST(options->create_data_property_or_throw(vm.names.roundingMode, PrimitiveString::create(vm, number_format->rounding_mode_string()))); MUST(options->create_data_property_or_throw(vm.names.roundingIncrement, Value(number_format->rounding_increment()))); MUST(options->create_data_property_or_throw(vm.names.trailingZeroDisplay, PrimitiveString::create(vm, number_format->trailing_zero_display_string()))); + MUST(options->create_data_property_or_throw(vm.names.roundingPriority, PrimitiveString::create(vm, number_format->computed_rounding_priority_string()))); - switch (number_format->rounding_type()) { - // 6. If nf.[[RoundingType]] is morePrecision, then - case NumberFormatBase::RoundingType::MorePrecision: - // a. Perform ! CreateDataPropertyOrThrow(options, "roundingPriority", "morePrecision"). - MUST(options->create_data_property_or_throw(vm.names.roundingPriority, PrimitiveString::create(vm, "morePrecision"_string))); - break; - // 7. Else if nf.[[RoundingType]] is lessPrecision, then - case NumberFormatBase::RoundingType::LessPrecision: - // a. Perform ! CreateDataPropertyOrThrow(options, "roundingPriority", "lessPrecision"). - MUST(options->create_data_property_or_throw(vm.names.roundingPriority, PrimitiveString::create(vm, "lessPrecision"_string))); - break; - // 8. Else, - default: - // a. Perform ! CreateDataPropertyOrThrow(options, "roundingPriority", "auto"). - MUST(options->create_data_property_or_throw(vm.names.roundingPriority, PrimitiveString::create(vm, "auto"_string))); - break; - } - - // 9. Return options. + // 6. Return options. return options; }