mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 19:37:36 +00:00
LibJS: Make use of the Intl MV in more Intl.NumberFormat AOs
This is an editorial change in the Intl.NumberFormat V3 spec. See:
c24b33e
Note our implementation was already using the Intl MV in these AOs just
due to C++ type safety.
This commit is contained in:
parent
a283daaab7
commit
6a50fb465c
1 changed files with 89 additions and 39 deletions
|
@ -398,7 +398,7 @@ ThrowCompletionOr<FormatResult> format_numeric_to_string(VM& vm, NumberFormatBas
|
||||||
// b. If x < 0, let isNegative be true; else let isNegative be false.
|
// b. If x < 0, let isNegative be true; else let isNegative be false.
|
||||||
is_negative = number.is_negative();
|
is_negative = number.is_negative();
|
||||||
|
|
||||||
// c. If isNegative, then
|
// c. If isNegative is true, then
|
||||||
if (is_negative) {
|
if (is_negative) {
|
||||||
// i. Set x to -x.
|
// i. Set x to -x.
|
||||||
number.negate();
|
number.negate();
|
||||||
|
@ -472,7 +472,7 @@ ThrowCompletionOr<FormatResult> format_numeric_to_string(VM& vm, NumberFormatBas
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7. Let x be result.[[RoundedNumber]].
|
// 7. Set x to result.[[RoundedNumber]].
|
||||||
number = move(result.rounded_number);
|
number = move(result.rounded_number);
|
||||||
|
|
||||||
// 8. Let string be result.[[FormattedString]].
|
// 8. Let string be result.[[FormattedString]].
|
||||||
|
@ -480,12 +480,13 @@ ThrowCompletionOr<FormatResult> format_numeric_to_string(VM& vm, NumberFormatBas
|
||||||
|
|
||||||
// 9. If intlObject.[[TrailingZeroDisplay]] is "stripIfInteger" and x modulo 1 = 0, then
|
// 9. If intlObject.[[TrailingZeroDisplay]] is "stripIfInteger" and x modulo 1 = 0, then
|
||||||
if ((intl_object.trailing_zero_display() == NumberFormat::TrailingZeroDisplay::StripIfInteger) && number.modulo_is_zero(1)) {
|
if ((intl_object.trailing_zero_display() == NumberFormat::TrailingZeroDisplay::StripIfInteger) && number.modulo_is_zero(1)) {
|
||||||
// a. If string contains ".", then
|
// a. Let i be StringIndexOf(string, ".", 0).
|
||||||
if (auto index = string.find_byte_offset('.'); index.has_value()) {
|
auto index = string.find_byte_offset('.');
|
||||||
// i. Set string to the substring of string from index 0 to the index of ".".
|
|
||||||
|
// b. If i ≠ -1, set string to the substring of string from 0 to i.
|
||||||
|
if (index.has_value())
|
||||||
string = TRY_OR_THROW_OOM(vm, string.substring_from_byte_offset(0, *index));
|
string = TRY_OR_THROW_OOM(vm, string.substring_from_byte_offset(0, *index));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// 10. Let int be result.[[IntegerDigitsCount]].
|
// 10. Let int be result.[[IntegerDigitsCount]].
|
||||||
int digits = result.digits;
|
int digits = result.digits;
|
||||||
|
@ -502,18 +503,16 @@ ThrowCompletionOr<FormatResult> format_numeric_to_string(VM& vm, NumberFormatBas
|
||||||
string = TRY_OR_THROW_OOM(vm, String::formatted("{}{}", forward_zeros, string));
|
string = TRY_OR_THROW_OOM(vm, String::formatted("{}{}", forward_zeros, string));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13. If isNegative and x is 0, then
|
// 13. If isNegative is true, then
|
||||||
if (is_negative && number.is_zero()) {
|
if (is_negative) {
|
||||||
// a. Let x be -0.
|
// a. If x is 0, set x to negative-zero. Otherwise, set x to -x.
|
||||||
|
if (number.is_zero())
|
||||||
number = MathematicalValue { MathematicalValue::Symbol::NegativeZero };
|
number = MathematicalValue { MathematicalValue::Symbol::NegativeZero };
|
||||||
}
|
else
|
||||||
// 14. Else if isNegative, then
|
|
||||||
else if (is_negative) {
|
|
||||||
// b. Let x be -x.
|
|
||||||
number.negate();
|
number.negate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 15. Return the Record { [[RoundedNumber]]: x, [[FormattedString]]: string }.
|
// 14. Return the Record { [[RoundedNumber]]: x, [[FormattedString]]: string }.
|
||||||
return FormatResult { move(string), move(number) };
|
return FormatResult { move(string), move(number) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -729,12 +728,12 @@ ThrowCompletionOr<Vector<PatternPartition>> partition_notation_sub_pattern(VM& v
|
||||||
if (!grouping_sizes.has_value())
|
if (!grouping_sizes.has_value())
|
||||||
return Vector<PatternPartition> {};
|
return Vector<PatternPartition> {};
|
||||||
|
|
||||||
// 2. If x is NaN, then
|
// 2. If x is not-a-number, then
|
||||||
if (number.is_nan()) {
|
if (number.is_nan()) {
|
||||||
// a. Append a new Record { [[Type]]: "nan", [[Value]]: n } as the last element of result.
|
// a. Append a new Record { [[Type]]: "nan", [[Value]]: n } as the last element of result.
|
||||||
result.append({ "nan"sv, move(formatted_string) });
|
result.append({ "nan"sv, move(formatted_string) });
|
||||||
}
|
}
|
||||||
// 3. Else if x is a non-finite Number, then
|
// 3. Else if x is positive-infinity or negative-infinity, then
|
||||||
else if (number.is_positive_infinity() || number.is_negative_infinity()) {
|
else if (number.is_positive_infinity() || number.is_negative_infinity()) {
|
||||||
// a. Append a new Record { [[Type]]: "infinity", [[Value]]: n } as the last element of result.
|
// a. Append a new Record { [[Type]]: "infinity", [[Value]]: n } as the last element of result.
|
||||||
result.append({ "infinity"sv, move(formatted_string) });
|
result.append({ "infinity"sv, move(formatted_string) });
|
||||||
|
@ -1276,6 +1275,13 @@ ThrowCompletionOr<RawFormatResult> to_raw_fixed(VM& vm, MathematicalValue const&
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class NumberCategory {
|
||||||
|
NegativeNonZero,
|
||||||
|
NegativeZero,
|
||||||
|
PositiveNonZero,
|
||||||
|
PositiveZero,
|
||||||
|
};
|
||||||
|
|
||||||
// 15.5.11 GetNumberFormatPattern ( numberFormat, x ), https://tc39.es/ecma402/#sec-getnumberformatpattern
|
// 15.5.11 GetNumberFormatPattern ( numberFormat, x ), https://tc39.es/ecma402/#sec-getnumberformatpattern
|
||||||
// 1.5.11 GetNumberFormatPattern ( numberFormat, x ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-getnumberformatpattern
|
// 1.5.11 GetNumberFormatPattern ( numberFormat, x ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-getnumberformatpattern
|
||||||
ThrowCompletionOr<Optional<Variant<StringView, String>>> get_number_format_pattern(VM& vm, NumberFormat& number_format, MathematicalValue const& number, ::Locale::NumberFormat& found_pattern)
|
ThrowCompletionOr<Optional<Variant<StringView, String>>> get_number_format_pattern(VM& vm, NumberFormat& number_format, MathematicalValue const& number, ::Locale::NumberFormat& found_pattern)
|
||||||
|
@ -1361,20 +1367,64 @@ ThrowCompletionOr<Optional<Variant<StringView, String>>> get_number_format_patte
|
||||||
if (!patterns.has_value())
|
if (!patterns.has_value())
|
||||||
return OptionalNone {};
|
return OptionalNone {};
|
||||||
|
|
||||||
|
NumberCategory category;
|
||||||
|
|
||||||
|
// 11. If x is negative-infinity, then
|
||||||
|
if (number.is_negative_infinity()) {
|
||||||
|
// a. Let category be negative-nonzero.
|
||||||
|
category = NumberCategory::NegativeNonZero;
|
||||||
|
}
|
||||||
|
// 12. Else if x is negative-zero, then
|
||||||
|
else if (number.is_negative_zero()) {
|
||||||
|
// a. Let category be negative-zero.
|
||||||
|
category = NumberCategory::NegativeZero;
|
||||||
|
}
|
||||||
|
// 13. Else if x is not-a-number, then
|
||||||
|
else if (number.is_nan()) {
|
||||||
|
// a. Let category be positive-zero.
|
||||||
|
category = NumberCategory::PositiveZero;
|
||||||
|
}
|
||||||
|
// 14. Else if x is positive-infinity, then
|
||||||
|
else if (number.is_positive_infinity()) {
|
||||||
|
// a. Let category be positive-nonzero.
|
||||||
|
category = NumberCategory::PositiveNonZero;
|
||||||
|
}
|
||||||
|
// 15. Else,
|
||||||
|
else {
|
||||||
|
// a. Assert: x is a mathematical value.
|
||||||
|
VERIFY(number.is_mathematical_value());
|
||||||
|
|
||||||
|
// b. If x < 0, then
|
||||||
|
if (number.is_negative()) {
|
||||||
|
// i. Let category be negative-nonzero.
|
||||||
|
category = NumberCategory::NegativeNonZero;
|
||||||
|
}
|
||||||
|
// c. Else if x > 0, then
|
||||||
|
else if (number.is_positive()) {
|
||||||
|
// i. Let category be positive-nonzero.
|
||||||
|
category = NumberCategory::PositiveNonZero;
|
||||||
|
}
|
||||||
|
// d. Else,
|
||||||
|
else {
|
||||||
|
// i. Let category be positive-zero.
|
||||||
|
category = NumberCategory::PositiveZero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
StringView pattern;
|
StringView pattern;
|
||||||
|
|
||||||
// 11. Let signDisplay be numberFormat.[[SignDisplay]].
|
// 16. Let signDisplay be numberFormat.[[SignDisplay]].
|
||||||
switch (number_format.sign_display()) {
|
switch (number_format.sign_display()) {
|
||||||
// 12. If signDisplay is "never", then
|
// 17. If signDisplay is "never", then
|
||||||
case NumberFormat::SignDisplay::Never:
|
case NumberFormat::SignDisplay::Never:
|
||||||
// a. Let pattern be patterns.[[zeroPattern]].
|
// a. Let pattern be patterns.[[zeroPattern]].
|
||||||
pattern = patterns->zero_format;
|
pattern = patterns->zero_format;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 13. Else if signDisplay is "auto", then
|
// 18. Else if signDisplay is "auto", then
|
||||||
case NumberFormat::SignDisplay::Auto:
|
case NumberFormat::SignDisplay::Auto:
|
||||||
// a. If x is 0 or x > 0 or x is NaN, then
|
// a. If category is positive-nonzero or positive-zero, then
|
||||||
if (number.is_zero() || number.is_positive() || number.is_nan()) {
|
if (category == NumberCategory::PositiveNonZero || category == NumberCategory::PositiveZero) {
|
||||||
// i. Let pattern be patterns.[[zeroPattern]].
|
// i. Let pattern be patterns.[[zeroPattern]].
|
||||||
pattern = patterns->zero_format;
|
pattern = patterns->zero_format;
|
||||||
}
|
}
|
||||||
|
@ -1385,10 +1435,10 @@ ThrowCompletionOr<Optional<Variant<StringView, String>>> get_number_format_patte
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 14. Else if signDisplay is "always", then
|
// 19. Else if signDisplay is "always", then
|
||||||
case NumberFormat::SignDisplay::Always:
|
case NumberFormat::SignDisplay::Always:
|
||||||
// a. If x is 0 or x > 0 or x is NaN, then
|
// a. If category is positive-nonzero or positive-zero, then
|
||||||
if (number.is_zero() || number.is_positive() || number.is_nan()) {
|
if (category == NumberCategory::PositiveNonZero || category == NumberCategory::PositiveZero) {
|
||||||
// i. Let pattern be patterns.[[positivePattern]].
|
// i. Let pattern be patterns.[[positivePattern]].
|
||||||
pattern = patterns->positive_format;
|
pattern = patterns->positive_format;
|
||||||
}
|
}
|
||||||
|
@ -1399,15 +1449,15 @@ ThrowCompletionOr<Optional<Variant<StringView, String>>> get_number_format_patte
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 15. Else if signDisplay is "exceptZero", then
|
// 20. Else if signDisplay is "exceptZero", then
|
||||||
case NumberFormat::SignDisplay::ExceptZero:
|
case NumberFormat::SignDisplay::ExceptZero:
|
||||||
// a. If x is 0 or x is -0 or x is NaN, then
|
// a. If category is positive-zero or negative-zero, then
|
||||||
if (number.is_zero() || number.is_negative_zero() || number.is_nan()) {
|
if (category == NumberCategory::PositiveZero || category == NumberCategory::NegativeZero) {
|
||||||
// i. Let pattern be patterns.[[zeroPattern]].
|
// i. Let pattern be patterns.[[zeroPattern]].
|
||||||
pattern = patterns->zero_format;
|
pattern = patterns->zero_format;
|
||||||
}
|
}
|
||||||
// b. Else if x > 0, then
|
// b. Else if category is positive-nonzero, then
|
||||||
else if (number.is_positive()) {
|
else if (category == NumberCategory::PositiveNonZero) {
|
||||||
// i. Let pattern be patterns.[[positivePattern]].
|
// i. Let pattern be patterns.[[positivePattern]].
|
||||||
pattern = patterns->positive_format;
|
pattern = patterns->positive_format;
|
||||||
}
|
}
|
||||||
|
@ -1418,18 +1468,18 @@ ThrowCompletionOr<Optional<Variant<StringView, String>>> get_number_format_patte
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 16. Else,
|
// 21. Else,
|
||||||
case NumberFormat::SignDisplay::Negative:
|
case NumberFormat::SignDisplay::Negative:
|
||||||
// a. Assert: signDisplay is "negative".
|
// a. Assert: signDisplay is "negative".
|
||||||
// b. If x is 0 or x is -0 or x > 0 or x is NaN, then
|
// b. If category is negative-nonzero, then
|
||||||
if (number.is_zero() || number.is_negative_zero() || number.is_positive() || number.is_nan()) {
|
if (category == NumberCategory::NegativeNonZero) {
|
||||||
// i. Let pattern be patterns.[[zeroPattern]].
|
// i. Let pattern be patterns.[[negativePattern]].
|
||||||
pattern = patterns->zero_format;
|
pattern = patterns->negative_format;
|
||||||
}
|
}
|
||||||
// c. Else,
|
// c. Else,
|
||||||
else {
|
else {
|
||||||
// i. Let pattern be patterns.[[negativePattern]].
|
// i. Let pattern be patterns.[[zeroPattern]].
|
||||||
pattern = patterns->negative_format;
|
pattern = patterns->zero_format;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1448,7 +1498,7 @@ ThrowCompletionOr<Optional<Variant<StringView, String>>> get_number_format_patte
|
||||||
return modified_pattern.release_value();
|
return modified_pattern.release_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 16. Return pattern.
|
// 22. Return pattern.
|
||||||
return pattern;
|
return pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue