1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 08:47:34 +00:00

LibJS: Compute NumberFormat's rounding priority during construction

This is an editorial change in the ECMA-402 spec. See:
c28118e
This commit is contained in:
Timothy Flynn 2023-08-11 07:50:34 -04:00 committed by Tim Flynn
parent bc8c2b2bc2
commit b0c8543b28
4 changed files with 53 additions and 30 deletions

View file

@ -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 StringView NumberFormatBase::rounding_mode_string() const
{ {
switch (m_rounding_mode) { switch (m_rounding_mode) {

View file

@ -29,6 +29,13 @@ public:
LessPrecision, LessPrecision,
}; };
enum class ComputedRoundingPriority {
Invalid,
Auto,
MorePrecision,
LessPrecision,
};
enum class RoundingMode { enum class RoundingMode {
Invalid, Invalid,
Ceil, Ceil,
@ -87,6 +94,10 @@ public:
StringView rounding_type_string() const; StringView rounding_type_string() const;
void set_rounding_type(RoundingType rounding_type) { m_rounding_type = rounding_type; } 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; } RoundingMode rounding_mode() const { return m_rounding_mode; }
StringView rounding_mode_string() const; StringView rounding_mode_string() const;
void set_rounding_mode(StringView rounding_mode); void set_rounding_mode(StringView rounding_mode);
@ -102,17 +113,18 @@ protected:
explicit NumberFormatBase(Object& prototype); explicit NumberFormatBase(Object& prototype);
private: private:
String m_locale; // [[Locale]] String m_locale; // [[Locale]]
String m_data_locale; // [[DataLocale]] String m_data_locale; // [[DataLocale]]
int m_min_integer_digits { 0 }; // [[MinimumIntegerDigits]] int m_min_integer_digits { 0 }; // [[MinimumIntegerDigits]]
Optional<int> m_min_fraction_digits {}; // [[MinimumFractionDigits]] Optional<int> m_min_fraction_digits {}; // [[MinimumFractionDigits]]
Optional<int> m_max_fraction_digits {}; // [[MaximumFractionDigits]] Optional<int> m_max_fraction_digits {}; // [[MaximumFractionDigits]]
Optional<int> m_min_significant_digits {}; // [[MinimumSignificantDigits]] Optional<int> m_min_significant_digits {}; // [[MinimumSignificantDigits]]
Optional<int> m_max_significant_digits {}; // [[MaximumSignificantDigits]] Optional<int> m_max_significant_digits {}; // [[MaximumSignificantDigits]]
RoundingType m_rounding_type { RoundingType::Invalid }; // [[RoundingType]] RoundingType m_rounding_type { RoundingType::Invalid }; // [[RoundingType]]
RoundingMode m_rounding_mode { RoundingMode::Invalid }; // [[RoundingMode]] ComputedRoundingPriority m_computed_rounding_priority { ComputedRoundingPriority::Invalid }; // [[ComputedRoundingPriority]]
int m_rounding_increment { 1 }; // [[RoundingIncrement]] RoundingMode m_rounding_mode { RoundingMode::Invalid }; // [[RoundingMode]]
TrailingZeroDisplay m_trailing_zero_display { TrailingZeroDisplay::Invalid }; // [[TrailingZeroDisplay]] int m_rounding_increment { 1 }; // [[RoundingIncrement]]
TrailingZeroDisplay m_trailing_zero_display { TrailingZeroDisplay::Invalid }; // [[TrailingZeroDisplay]]
}; };
class NumberFormat final : public NumberFormatBase { class NumberFormat final : public NumberFormatBase {

View file

@ -370,27 +370,41 @@ ThrowCompletionOr<void> set_number_format_digit_options(VM& vm, NumberFormatBase
// e. Set intlObj.[[RoundingType]] to morePrecision. // e. Set intlObj.[[RoundingType]] to morePrecision.
intl_object.set_rounding_type(NumberFormatBase::RoundingType::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 // 27. Else if roundingPriority is "morePrecision", then
else if (rounding_priority == "morePrecision"sv) { else if (rounding_priority == "morePrecision"sv) {
// a. Set intlObj.[[RoundingType]] to morePrecision. // a. Set intlObj.[[RoundingType]] to morePrecision.
intl_object.set_rounding_type(NumberFormatBase::RoundingType::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 // 28. Else if roundingPriority is "lessPrecision", then
else if (rounding_priority == "lessPrecision"sv) { else if (rounding_priority == "lessPrecision"sv) {
// a. Set intlObj.[[RoundingType]] to lessPrecision. // a. Set intlObj.[[RoundingType]] to lessPrecision.
intl_object.set_rounding_type(NumberFormatBase::RoundingType::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 // 29. Else if hasSd is true, then
else if (has_significant_digits) { else if (has_significant_digits) {
// a. Set intlObj.[[RoundingType]] to significantDigits. // a. Set intlObj.[[RoundingType]] to significantDigits.
intl_object.set_rounding_type(NumberFormatBase::RoundingType::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, // 30. Else,
else { else {
// a. Set intlObj.[[RoundingType]] to fractionDigits. // a. Set intlObj.[[RoundingType]] to fractionDigits.
intl_object.set_rounding_type(NumberFormatBase::RoundingType::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 // 31. If roundingIncrement is not 1, then

View file

@ -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.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.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.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. Return options.
// 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.
return options; return options;
} }