diff options
author | Timothy Flynn <trflynn89@pm.me> | 2023-04-11 08:45:51 -0400 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2023-04-11 23:22:32 +0200 |
commit | f816a24b864d8203c6ce24cfcb7f5562b4bc13b9 (patch) | |
tree | c8a4c3f2cfaf23697a2ac07deaa26c0d7770a2fa /Userland | |
parent | b411e300246b700cbf311c90a30dca3b75055d29 (diff) | |
download | serenity-f816a24b864d8203c6ce24cfcb7f5562b4bc13b9.zip |
LibJS: Update spec numbers for the Intl NumberFormat v3 proposal
This proposal has been merged into the main ECMA-402 spec. See:
https://github.com/tc39/ecma402/commit/4257160
Note this includes some editorial and normative changes made when the
proposal was merged into the main spec, but are not in the proposal spec
itself. In particular, the following AOs were changed:
PartitionNumberRangePattern (normative)
SetNumberFormatDigitOptions (editorial)
Diffstat (limited to 'Userland')
9 files changed, 98 insertions, 112 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp index 68e57b5e43..f8773d6eb5 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp @@ -264,7 +264,6 @@ ThrowCompletionOr<Vector<String>> canonicalize_locale_list(VM& vm, Value locales } // 9.2.2 BestAvailableLocale ( availableLocales, locale ), https://tc39.es/ecma402/#sec-bestavailablelocale -// 1.2.2 BestAvailableLocale ( availableLocales, locale ), https://tc39.es/proposal-intl-numberformat-v3/out/negotiation/proposed.html#sec-bestavailablelocale Optional<StringView> best_available_locale(StringView locale) { // 1. Let candidate be locale. @@ -608,7 +607,7 @@ ThrowCompletionOr<Object*> coerce_options_to_object(VM& vm, Value options) // NOTE: 9.2.13 GetOption has been removed and is being pulled in from ECMA-262 in the Temporal proposal. -// 1.2.14 GetBooleanOrStringNumberFormatOption ( options, property, stringValues, fallback ), https://tc39.es/proposal-intl-numberformat-v3/out/negotiation/proposed.html#sec-getbooleanorstringnumberformatoption +// 9.2.14 GetBooleanOrStringNumberFormatOption ( options, property, stringValues, fallback ), https://tc39.es/ecma402/#sec-getbooleanorstringnumberformatoption ThrowCompletionOr<StringOrBoolean> get_boolean_or_string_number_format_option(VM& vm, Object const& options, PropertyKey const& property, ReadonlySpan<StringView> string_values, StringOrBoolean fallback) { // 1. Let value be ? Get(options, property). @@ -638,7 +637,7 @@ ThrowCompletionOr<StringOrBoolean> get_boolean_or_string_number_format_option(VM return StringOrBoolean { *it }; } -// 9.2.14 DefaultNumberOption ( value, minimum, maximum, fallback ), https://tc39.es/ecma402/#sec-defaultnumberoption +// 9.2.15 DefaultNumberOption ( value, minimum, maximum, fallback ), https://tc39.es/ecma402/#sec-defaultnumberoption ThrowCompletionOr<Optional<int>> default_number_option(VM& vm, Value value, int minimum, int maximum, Optional<int> fallback) { // 1. If value is undefined, return fallback. @@ -656,7 +655,7 @@ ThrowCompletionOr<Optional<int>> default_number_option(VM& vm, Value value, int return floor(value.as_double()); } -// 9.2.15 GetNumberOption ( options, property, minimum, maximum, fallback ), https://tc39.es/ecma402/#sec-getnumberoption +// 9.2.16 GetNumberOption ( options, property, minimum, maximum, fallback ), https://tc39.es/ecma402/#sec-getnumberoption ThrowCompletionOr<Optional<int>> get_number_option(VM& vm, Object const& options, PropertyKey const& property, int minimum, int maximum, Optional<int> fallback) { // 1. Assert: Type(options) is Object. @@ -668,7 +667,7 @@ ThrowCompletionOr<Optional<int>> get_number_option(VM& vm, Object const& options return default_number_option(vm, value, minimum, maximum, move(fallback)); } -// 9.2.16 PartitionPattern ( pattern ), https://tc39.es/ecma402/#sec-partitionpattern +// 9.2.17 PartitionPattern ( pattern ), https://tc39.es/ecma402/#sec-partitionpattern ThrowCompletionOr<Vector<PatternPartition>> partition_pattern(VM& vm, StringView pattern) { // 1. Let result be a new empty List. diff --git a/Userland/Libraries/LibJS/Runtime/Intl/MathematicalValue.h b/Userland/Libraries/LibJS/Runtime/Intl/MathematicalValue.h index 1ff11938ea..3d783679e8 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/MathematicalValue.h +++ b/Userland/Libraries/LibJS/Runtime/Intl/MathematicalValue.h @@ -15,7 +15,7 @@ namespace JS::Intl { -// https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#intl-mathematical-value +// https://tc39.es/ecma402/#intl-mathematical-value class MathematicalValue { public: enum class Symbol { diff --git a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp index de3215b1c0..21ecf72834 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp @@ -377,7 +377,6 @@ int currency_digits(StringView currency) } // 15.5.3 FormatNumericToString ( intlObject, x ), https://tc39.es/ecma402/#sec-formatnumberstring -// 1.5.3 FormatNumericToString ( intlObject, x ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-formatnumberstring ThrowCompletionOr<FormatResult> format_numeric_to_string(VM& vm, NumberFormatBase const& intl_object, MathematicalValue number) { bool is_negative = false; @@ -514,7 +513,6 @@ ThrowCompletionOr<FormatResult> format_numeric_to_string(VM& vm, NumberFormatBas } // 15.5.4 PartitionNumberPattern ( numberFormat, x ), https://tc39.es/ecma402/#sec-partitionnumberpattern -// 1.5.4 PartitionNumberPattern ( numberFormat, x ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-partitionnumberpattern ThrowCompletionOr<Vector<PatternPartition>> partition_number_pattern(VM& vm, NumberFormat& number_format, MathematicalValue number) { // 1. Let exponent be 0. @@ -727,7 +725,6 @@ static ThrowCompletionOr<Vector<String>> separate_integer_into_groups(VM& vm, :: } // 15.5.5 PartitionNotationSubPattern ( numberFormat, x, n, exponent ), https://tc39.es/ecma402/#sec-partitionnotationsubpattern -// 1.5.5 PartitionNotationSubPattern ( numberFormat, x, n, exponent ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-partitionnotationsubpattern ThrowCompletionOr<Vector<PatternPartition>> partition_notation_sub_pattern(VM& vm, NumberFormat& number_format, MathematicalValue const& number, String formatted_string, int exponent) { // 1. Let result be a new empty List. @@ -769,8 +766,8 @@ ThrowCompletionOr<Vector<PatternPartition>> partition_notation_sub_pattern(VM& v } // iii. Else if p is equal to "number", then else if (part == "number"sv) { - // 1. If the numberFormat.[[NumberingSystem]] matches one of the values in the "Numbering System" column of Table 12 below, then - // a. Let digits be a List whose elements are the code points specified in the "Digits" column of the matching row in Table 13. + // 1. If the numberFormat.[[NumberingSystem]] matches one of the values in the "Numbering System" column of Table 14 below, then + // a. Let digits be a List whose elements are the code points specified in the "Digits" column of the matching row in Table 14. // b. Assert: The length of digits is 10. // c. Let transliterated be the empty String. // d. Let len be the length of n. @@ -999,7 +996,7 @@ struct RawPrecisionResult { MathematicalValue rounded; }; -// ToRawPrecisionFn, https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#eqn-ToRawPrecisionFn +// ToRawPrecisionFn, https://tc39.es/ecma402/#eqn-ToRawPrecisionFn static ThrowCompletionOr<RawPrecisionResult> to_raw_precision_function(VM& vm, MathematicalValue const& number, int precision, PreferredResult mode) { RawPrecisionResult result {}; @@ -1036,7 +1033,6 @@ static ThrowCompletionOr<RawPrecisionResult> to_raw_precision_function(VM& vm, M } // 15.5.8 ToRawPrecision ( x, minPrecision, maxPrecision ), https://tc39.es/ecma402/#sec-torawprecision -// 1.5.8 ToRawPrecision ( x, minPrecision, maxPrecision, unsignedRoundingMode ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-torawprecision ThrowCompletionOr<RawFormatResult> to_raw_precision(VM& vm, MathematicalValue const& number, int min_precision, int max_precision, NumberFormat::UnsignedRoundingMode unsigned_rounding_mode) { RawFormatResult result {}; @@ -1153,7 +1149,7 @@ struct RawFixedResult { MathematicalValue rounded; }; -// ToRawFixedFn, https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#eqn-ToRawFixedFn +// ToRawFixedFn, https://tc39.es/ecma402/#eqn-ToRawFixedFn static ThrowCompletionOr<RawFixedResult> to_raw_fixed_function(VM& vm, MathematicalValue const& number, int fraction, int rounding_increment, PreferredResult mode) { RawFixedResult result {}; @@ -1200,7 +1196,6 @@ static ThrowCompletionOr<RawFixedResult> to_raw_fixed_function(VM& vm, Mathemati } // 15.5.9 ToRawFixed ( x, minInteger, minFraction, maxFraction ), https://tc39.es/ecma402/#sec-torawfixed -// 1.5.9 ToRawFixed ( x, minFraction, maxFraction, roundingIncrement, unsignedRoundingMode ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-torawfixed ThrowCompletionOr<RawFormatResult> to_raw_fixed(VM& vm, MathematicalValue const& number, int min_fraction, int max_fraction, int rounding_increment, NumberFormat::UnsignedRoundingMode unsigned_rounding_mode) { RawFormatResult result {}; @@ -1292,7 +1287,6 @@ enum class NumberCategory { }; // 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 ThrowCompletionOr<Optional<Variant<StringView, String>>> get_number_format_pattern(VM& vm, NumberFormat& number_format, MathematicalValue const& number, ::Locale::NumberFormat& found_pattern) { // 1. Let localeData be %NumberFormat%.[[LocaleData]]. @@ -1655,10 +1649,9 @@ ThrowCompletionOr<int> compute_exponent_for_magnitude(VM& vm, NumberFormat& numb } } -// 1.5.16 ToIntlMathematicalValue ( value ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-tointlmathematicalvalue +// 15.5.16 ToIntlMathematicalValue ( value ), https://tc39.es/ecma402/#sec-tointlmathematicalvalue ThrowCompletionOr<MathematicalValue> to_intl_mathematical_value(VM& vm, Value value) { - // 1. Let primValue be ? ToPrimitive(value, number). auto primitive_value = TRY(value.to_primitive(vm, Value::PreferredType::Number)); @@ -1700,13 +1693,13 @@ ThrowCompletionOr<MathematicalValue> to_intl_mathematical_value(VM& vm, Value va return mathematical_value; } -// 1.5.17 GetUnsignedRoundingMode ( roundingMode, isNegative ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-getunsignedroundingmode +// 15.5.17 GetUnsignedRoundingMode ( roundingMode, isNegative ), https://tc39.es/ecma402/#sec-getunsignedroundingmode NumberFormat::UnsignedRoundingMode get_unsigned_rounding_mode(NumberFormat::RoundingMode rounding_mode, bool is_negative) { - // 1. If isNegative is true, return the specification type in the third column of Table 2 where the first column is roundingMode and the second column is "negative". - // 2. Else, return the specification type in the third column of Table 2 where the first column is roundingMode and the second column is "positive". + // 1. If isNegative is true, return the specification type in the third column of Table 15 where the first column is roundingMode and the second column is "negative". + // 2. Else, return the specification type in the third column of Table 15 where the first column is roundingMode and the second column is "positive". - // Table 2: Conversion from rounding mode to unsigned rounding mode, https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#table-intl-unsigned-rounding-modes + // Table 15: Conversion from rounding mode to unsigned rounding mode, https://tc39.es/ecma402/#table-intl-unsigned-rounding-modes switch (rounding_mode) { case NumberFormat::RoundingMode::Ceil: return is_negative ? NumberFormat::UnsignedRoundingMode::Zero : NumberFormat::UnsignedRoundingMode::Infinity; @@ -1731,7 +1724,7 @@ NumberFormat::UnsignedRoundingMode get_unsigned_rounding_mode(NumberFormat::Roun }; } -// 1.5.18 ApplyUnsignedRoundingMode ( x, r1, r2, unsignedRoundingMode ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-applyunsignedroundingmode +// 15.5.18 ApplyUnsignedRoundingMode ( x, r1, r2, unsignedRoundingMode ), https://tc39.es/ecma402/#sec-applyunsignedroundingmode RoundingDecision apply_unsigned_rounding_mode(MathematicalValue const& x, MathematicalValue const& r1, MathematicalValue const& r2, NumberFormat::UnsignedRoundingMode unsigned_rounding_mode) { // 1. If x is equal to r1, return r1. @@ -1743,7 +1736,7 @@ RoundingDecision apply_unsigned_rounding_mode(MathematicalValue const& x, Mathem // // This should be resolved when the "Intl mathematical value" is implemented to support // arbitrarily precise decimals. - // https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#intl-mathematical-value + // https://tc39.es/ecma402/#intl-mathematical-value // 2. Assert: r1 < x < r2. // 3. Assert: unsignedRoundingMode is not undefined. @@ -1795,7 +1788,7 @@ RoundingDecision apply_unsigned_rounding_mode(MathematicalValue const& x, Mathem return RoundingDecision::HigherValue; } -// 1.5.19 PartitionNumberRangePattern ( numberFormat, x, y ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-partitionnumberrangepattern +// 15.5.19 PartitionNumberRangePattern ( numberFormat, x, y ), https://tc39.es/ecma402/#sec-partitionnumberrangepattern ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_number_range_pattern(VM& vm, NumberFormat& number_format, MathematicalValue start, MathematicalValue end) { // 1. If x is NaN or y is NaN, throw a RangeError exception. @@ -1815,8 +1808,11 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_number_range_pat auto raw_end_result = TRY(partition_number_pattern(vm, number_format, move(end))); auto end_result = MUST_OR_THROW_OOM(PatternPartitionWithSource::create_from_parent_list(vm, move(raw_end_result))); - // 5. If xResult is equal to yResult, then - if (start_result == end_result) { + // 5. If ! FormatNumeric(numberFormat, x) is equal to ! FormatNumeric(numberFormat, y), then + auto formatted_start = MUST_OR_THROW_OOM(format_numeric(vm, number_format, start)); + auto formatted_end = MUST_OR_THROW_OOM(format_numeric(vm, number_format, end)); + + if (formatted_start == formatted_end) { // a. Let appxResult be ? FormatApproximately(numberFormat, xResult). auto approximate_result = TRY(format_approximately(vm, number_format, move(start_result))); @@ -1830,20 +1826,24 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_number_range_pat return approximate_result; } - // 6. For each r in xResult, do - for (auto& part : start_result) { - // i. Set r.[[Source]] to "startRange". + // 6. For each element r in xResult, do + TRY_OR_THROW_OOM(vm, result.try_ensure_capacity(start_result.size())); + + for (auto& start_part : start_result) { + // a. Append a new Record { [[Type]]: r.[[Type]], [[Value]]: r.[[Value]], [[Source]]: "startRange" } as the last element of result. + PatternPartitionWithSource part; + part.type = start_part.type; + part.value = move(start_part.value); part.source = "startRange"sv; - } - // 7. Add all elements in xResult to result in order. - result = move(start_result); + result.unchecked_append(move(part)); + } - // 8. Let rangeSeparator be an ILND String value used to separate two numbers. + // 7. Let rangeSeparator be an ILND String value used to separate two numbers. auto range_separator_symbol = TRY_OR_THROW_OOM(vm, ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::RangeSeparator)).value_or("-"sv); auto range_separator = TRY_OR_THROW_OOM(vm, ::Locale::augment_range_pattern(range_separator_symbol, result.last().value, end_result[0].value)); - // 9. Append a new Record { [[Type]]: "literal", [[Value]]: rangeSeparator, [[Source]]: "shared" } element to result. + // 8. Append a new Record { [[Type]]: "literal", [[Value]]: rangeSeparator, [[Source]]: "shared" } element to result. PatternPartitionWithSource part; part.type = "literal"sv; part.value = range_separator.has_value() @@ -1852,27 +1852,30 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_number_range_pat part.source = "shared"sv; TRY_OR_THROW_OOM(vm, result.try_append(move(part))); - // 10. For each r in yResult, do - for (auto& part : end_result) { - // a. Set r.[[Source]] to "endRange". + // 9. For each element r in yResult, do + TRY_OR_THROW_OOM(vm, result.try_ensure_capacity(result.size() + end_result.size())); + + for (auto& end_part : end_result) { + // a. Append a new Record { [[Type]]: r.[[Type]], [[Value]]: r.[[Value]], [[Source]]: "endRange" } as the last element of result. + PatternPartitionWithSource part; + part.type = end_part.type; + part.value = move(end_part.value); part.source = "endRange"sv; - } - // 11. Add all elements in yResult to result in order. - TRY_OR_THROW_OOM(vm, result.try_extend(move(end_result))); + result.unchecked_append(move(part)); + } - // 12. Return ! CollapseNumberRange(result). + // 10. Return ! CollapseNumberRange(result). return collapse_number_range(move(result)); } -// 1.5.20 FormatApproximately ( numberFormat, result ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-formatapproximately +// 15.5.20 FormatApproximately ( numberFormat, result ), https://tc39.es/ecma402/#sec-formatapproximately ThrowCompletionOr<Vector<PatternPartitionWithSource>> format_approximately(VM& vm, NumberFormat& number_format, Vector<PatternPartitionWithSource> result) { - // 1. Let i be an index into result, determined by an implementation-defined algorithm based on numberFormat and result. - // 2. Let approximatelySign be an ILND String value used to signify that a number is approximate. + // 1. Let approximatelySign be an ILND String value used to signify that a number is approximate. auto approximately_sign = TRY_OR_THROW_OOM(vm, ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::ApproximatelySign)); - // 3. If approximatelySign is not empty, insert a new Record { [[Type]]: "approximatelySign", [[Value]]: approximatelySign } at index i in result. + // 2. If approximatelySign is not empty, insert a new Record { [[Type]]: "approximatelySign", [[Value]]: approximatelySign } at an ILND index in result. For example, if numberFormat has [[Locale]] "en-US" and [[NumberingSystem]] "latn" and [[Style]] "decimal", the new Record might be inserted before the first element of result. if (approximately_sign.has_value() && !approximately_sign->is_empty()) { PatternPartitionWithSource partition; partition.type = "approximatelySign"sv; @@ -1883,18 +1886,18 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> format_approximately(VM& v })); } - // 4. Return result. + // 3. Return result. return result; } -// 1.5.21 CollapseNumberRange ( result ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-collapsenumberrange +// 15.5.21 CollapseNumberRange ( result ), https://tc39.es/ecma402/#sec-collapsenumberrange Vector<PatternPartitionWithSource> collapse_number_range(Vector<PatternPartitionWithSource> result) { // Returning result unmodified is guaranteed to be a correct implementation of CollapseNumberRange. return result; } -// 1.5.22 FormatNumericRange( numberFormat, x, y ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-formatnumericrange +// 15.5.22 FormatNumericRange ( numberFormat, x, y ), https://tc39.es/ecma402/#sec-formatnumericrange ThrowCompletionOr<String> format_numeric_range(VM& vm, NumberFormat& number_format, MathematicalValue start, MathematicalValue end) { // 1. Let parts be ? PartitionNumberRangePattern(numberFormat, x, y). @@ -1913,7 +1916,7 @@ ThrowCompletionOr<String> format_numeric_range(VM& vm, NumberFormat& number_form return result.to_string(); } -// 1.5.23 FormatNumericRangeToParts( numberFormat, x, y ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-formatnumericrangetoparts +// 15.5.23 FormatNumericRangeToParts ( numberFormat, x, y ), https://tc39.es/ecma402/#sec-formatnumericrangetoparts ThrowCompletionOr<Array*> format_numeric_range_to_parts(VM& vm, NumberFormat& number_format, MathematicalValue start, MathematicalValue end) { auto& realm = *vm.current_realm(); diff --git a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatConstructor.cpp b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatConstructor.cpp index d253e52391..c3e64c270a 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatConstructor.cpp @@ -81,7 +81,6 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatConstructor::supported_locales_of) } // 15.1.2 InitializeNumberFormat ( numberFormat, locales, options ), https://tc39.es/ecma402/#sec-initializenumberformat -// 1.1.2 InitializeNumberFormat ( numberFormat, locales, options ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-initializenumberformat ThrowCompletionOr<NumberFormat*> initialize_number_format(VM& vm, NumberFormat& number_format, Value locales_value, Value options_value) { // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). @@ -215,7 +214,6 @@ ThrowCompletionOr<NumberFormat*> initialize_number_format(VM& vm, NumberFormat& } // 15.1.3 SetNumberFormatDigitOptions ( intlObj, options, mnfdDefault, mxfdDefault, notation ), https://tc39.es/ecma402/#sec-setnfdigitoptions -// 1.1.1 SetNumberFormatDigitOptions ( intlObj, options, mnfdDefault, mxfdDefault, notation ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-setnfdigitoptions ThrowCompletionOr<void> set_number_format_digit_options(VM& vm, NumberFormatBase& intl_object, Object const& options, int default_min_fraction_digits, int default_max_fraction_digits, NumberFormat::Notation notation) { // 1. Let mnid be ? GetNumberOption(options, "minimumIntegerDigits,", 1, 21, 1). @@ -237,7 +235,8 @@ ThrowCompletionOr<void> set_number_format_digit_options(VM& vm, NumberFormatBase intl_object.set_min_integer_digits(*min_integer_digits); // 7. Let roundingPriority be ? GetOption(options, "roundingPriority", string, ยซ "auto", "morePrecision", "lessPrecision" ยป, "auto"). - auto rounding_priority = TRY(get_option(vm, options, vm.names.roundingPriority, OptionType::String, { "auto"sv, "morePrecision"sv, "lessPrecision"sv }, "auto"sv)); + auto rounding_priority_option = TRY(get_option(vm, options, vm.names.roundingPriority, OptionType::String, { "auto"sv, "morePrecision"sv, "lessPrecision"sv }, "auto"sv)); + auto rounding_priority = MUST_OR_THROW_OOM(rounding_priority_option.as_string().utf8_string_view()); // 8. Let roundingIncrement be ? GetNumberOption(options, "roundingIncrement", 1, 5000, 1). auto rounding_increment = TRY(get_number_option(vm, options, vm.names.roundingIncrement, 1, 5000, 1)); @@ -288,7 +287,7 @@ ThrowCompletionOr<void> set_number_format_digit_options(VM& vm, NumberFormatBase bool need_fraction_digits = true; // 23. If roundingPriority is "auto", then - if (TRY(rounding_priority.as_string().utf8_string_view()) == "auto"sv) { + if (rounding_priority == "auto"sv) { // a. Set needSd to hasSd. need_significant_digits = has_significant_digits; @@ -303,16 +302,12 @@ ThrowCompletionOr<void> set_number_format_digit_options(VM& vm, NumberFormatBase if (need_significant_digits) { // a. If hasSd is true, then if (has_significant_digits) { - // i. Set mnsd to ? DefaultNumberOption(mnsd, 1, 21, 1). + // i. Set intlObj.[[MinimumSignificantDigits]] to ? DefaultNumberOption(mnsd, 1, 21, 1). auto min_digits = TRY(default_number_option(vm, min_significant_digits, 1, 21, 1)); - - // ii. Set mxsd to ? DefaultNumberOption(mxsd, mnsd, 21, 21). - auto max_digits = TRY(default_number_option(vm, max_significant_digits, *min_digits, 21, 21)); - - // iii. Set intlObj.[[MinimumSignificantDigits]] to mnsd. intl_object.set_min_significant_digits(*min_digits); - // iv. Set intlObj.[[MaximumSignificantDigits]] to mxsd. + // ii. Set intlObj.[[MaximumSignificantDigits]] to ? DefaultNumberOption(mxsd, intlObj.[[MinimumSignificantDigits]], 21, 21). + auto max_digits = TRY(default_number_option(vm, max_significant_digits, *min_digits, 21, 21)); intl_object.set_max_significant_digits(*max_digits); } // b. Else, @@ -361,51 +356,46 @@ ThrowCompletionOr<void> set_number_format_digit_options(VM& vm, NumberFormatBase } } - // 26. If needSd is true or needFd is true, then - if (need_significant_digits || need_fraction_digits) { - auto rounding_priority_string = TRY(rounding_priority.as_string().utf8_string_view()); - - // a. If roundingPriority is "morePrecision", then - if (rounding_priority_string == "morePrecision"sv) { - // i. Set intlObj.[[RoundingType]] to morePrecision. - intl_object.set_rounding_type(NumberFormatBase::RoundingType::MorePrecision); - } - // b. Else if roundingPriority is "lessPrecision", then - else if (rounding_priority_string == "lessPrecision"sv) { - // i. Set intlObj.[[RoundingType]] to lessPrecision. - intl_object.set_rounding_type(NumberFormatBase::RoundingType::LessPrecision); - } - // c. Else if hasSd is true, then - else if (has_significant_digits) { - // i. Set intlObj.[[RoundingType]] to significantDigits. - intl_object.set_rounding_type(NumberFormatBase::RoundingType::SignificantDigits); - } - // d. Else, - else { - // i. Set intlObj.[[RoundingType]] to fractionDigits. - intl_object.set_rounding_type(NumberFormatBase::RoundingType::FractionDigits); - } - } - - // 27. Else, - else { - // a. Set intlObj.[[RoundingType]] to morePrecision. - intl_object.set_rounding_type(NumberFormatBase::RoundingType::MorePrecision); - - // b. Set intlObj.[[MinimumFractionDigits]] to 0. + // 26. If needSd is false and needFd is false, then + if (!need_significant_digits && !need_fraction_digits) { + // a. Set intlObj.[[MinimumFractionDigits]] to 0. intl_object.set_min_fraction_digits(0); - // c. Set intlObj.[[MaximumFractionDigits]] to 0. + // b. Set intlObj.[[MaximumFractionDigits]] to 0. intl_object.set_max_fraction_digits(0); - // d. Set intlObj.[[MinimumSignificantDigits]] to 1. + // c. Set intlObj.[[MinimumSignificantDigits]] to 1. intl_object.set_min_significant_digits(1); - // e. Set intlObj.[[MaximumSignificantDigits]] to 2. + // d. Set intlObj.[[MaximumSignificantDigits]] to 2. intl_object.set_max_significant_digits(2); + + // e. Set intlObj.[[RoundingType]] to morePrecision. + intl_object.set_rounding_type(NumberFormatBase::RoundingType::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); + + } + // 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); + } + // 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); + } + // 30. Else, + else { + // a. Set intlObj.[[RoundingType]] to fractionDigits. + intl_object.set_rounding_type(NumberFormatBase::RoundingType::FractionDigits); } - // 28. If roundingIncrement is not 1, then + // 31. If roundingIncrement is not 1, then if (rounding_increment != 1) { // a. If intlObj.[[RoundingType]] is not fractionDigits, throw a TypeError exception. if (intl_object.rounding_type() != NumberFormatBase::RoundingType::FractionDigits) @@ -441,7 +431,7 @@ ThrowCompletionOr<void> set_number_format_unit_options(VM& vm, NumberFormat& int return vm.throw_completion<TypeError>(ErrorType::IntlOptionUndefined, "currency"sv, "style"sv, style); } // 7. Else, - // a. If ! IsWellFormedCurrencyCode(currency) is false, throw a RangeError exception. + // a. If IsWellFormedCurrencyCode(currency) is false, throw a RangeError exception. else if (!is_well_formed_currency_code(TRY(currency.as_string().utf8_string_view()))) return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, currency, "currency"sv); diff --git a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatFunction.cpp b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatFunction.cpp index 8f1c7d2847..e47cd5edc1 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatFunction.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatFunction.cpp @@ -11,7 +11,6 @@ namespace JS::Intl { // 15.5.2 Number Format Functions, https://tc39.es/ecma402/#sec-number-format-functions -// 1.5.2 Number Format Functions, https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#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()).release_allocated_value_but_fixme_should_propagate_errors(); diff --git a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.cpp index e5d4537e45..9b5ba4ddae 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.cpp @@ -65,7 +65,6 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format) } // 15.3.4 Intl.NumberFormat.prototype.formatToParts ( value ), https://tc39.es/ecma402/#sec-intl.numberformat.prototype.formattoparts -// 1.3.4 Intl.NumberFormat.prototype.formatToParts ( value ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-intl.numberformat.prototype.formattoparts JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_to_parts) { auto value = vm.argument(0); @@ -81,7 +80,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_to_parts) return TRY(format_numeric_to_parts(vm, *number_format, move(mathematical_value))); } -// 1.3.5 Intl.NumberFormat.prototype.formatRange ( start, end ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-intl.numberformat.prototype.formatrange +// 15.3.5 Intl.NumberFormat.prototype.formatRange ( start, end ), https://tc39.es/ecma402/#sec-intl.numberformat.prototype.formatrange JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_range) { auto start = vm.argument(0); @@ -108,7 +107,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_range) return PrimitiveString::create(vm, move(formatted)); } -// 1.3.6 Intl.NumberFormat.prototype.formatRangeToParts ( start, end ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-intl.numberformat.prototype.formatrangetoparts +// 15.3.6 Intl.NumberFormat.prototype.formatRangeToParts ( start, end ), https://tc39.es/ecma402/#sec-intl.numberformat.prototype.formatrangetoparts JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_range_to_parts) { auto start = vm.argument(0); @@ -134,8 +133,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_range_to_parts) return TRY(format_numeric_range_to_parts(vm, *number_format, move(x), move(y))); } -// 15.3.5 Intl.NumberFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.numberformat.prototype.resolvedoptions -// 1.3.7 Intl.NumberFormat.prototype.resolvedOptions ( ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-number-format-functions +// 15.3.7 Intl.NumberFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.numberformat.prototype.resolvedoptions JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::resolved_options) { auto& realm = *vm.current_realm(); diff --git a/Userland/Libraries/LibJS/Runtime/Intl/PluralRules.cpp b/Userland/Libraries/LibJS/Runtime/Intl/PluralRules.cpp index ca4e0ce2e9..b6c676a9b3 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/PluralRules.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/PluralRules.cpp @@ -92,7 +92,6 @@ PluralRules::PluralRules(Object& prototype) } // 16.5.3 ResolvePlural ( pluralRules, n ), https://tc39.es/ecma402/#sec-resolveplural -// 1.5.3 ResolvePlural ( pluralRules, n ), https://tc39.es/proposal-intl-numberformat-v3/out/pluralrules/proposed.html#sec-resolveplural ThrowCompletionOr<ResolvedPlurality> resolve_plural(VM& vm, PluralRules const& plural_rules, Value number) { return resolve_plural(vm, plural_rules, plural_rules.type(), number); @@ -132,13 +131,13 @@ ThrowCompletionOr<ResolvedPlurality> resolve_plural(VM& vm, NumberFormatBase con return ResolvedPlurality { plural_category, move(string) }; } -// 1.5.4 PluralRuleSelectRange ( locale, type, xp, yp ), https://tc39.es/proposal-intl-numberformat-v3/out/pluralrules/proposed.html#sec-pluralruleselectrange +// 16.5.4 PluralRuleSelectRange ( locale, type, xp, yp ), https://tc39.es/ecma402/#sec-resolveplural ::Locale::PluralCategory plural_rule_select_range(StringView locale, ::Locale::PluralForm, ::Locale::PluralCategory start, ::Locale::PluralCategory end) { return ::Locale::determine_plural_range(locale, start, end); } -// 1.5.5 ResolvePluralRange ( pluralRules, x, y ), https://tc39.es/proposal-intl-numberformat-v3/out/pluralrules/proposed.html#sec-resolvepluralrange +// 16.5.5 ResolvePluralRange ( pluralRules, x, y ), https://tc39.es/ecma402/#sec-resolveplural ThrowCompletionOr<::Locale::PluralCategory> resolve_plural_range(VM& vm, PluralRules const& plural_rules, Value start, Value end) { // 1. Assert: Type(pluralRules) is Object. diff --git a/Userland/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.cpp index f52fd4e42a..08a3b48801 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.cpp @@ -36,7 +36,6 @@ ThrowCompletionOr<void> PluralRulesPrototype::initialize(Realm& realm) } // 16.3.3 Intl.PluralRules.prototype.select ( value ), https://tc39.es/ecma402/#sec-intl.pluralrules.prototype.select -// 1.3.3 Intl.PluralRules.prototype.select ( value ), https://tc39.es/proposal-intl-numberformat-v3/out/pluralrules/proposed.html#sec-intl.pluralrules.prototype.select JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::select) { // 1. Let pr be the this value. @@ -51,7 +50,7 @@ JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::select) return MUST_OR_THROW_OOM(PrimitiveString::create(vm, ::Locale::plural_category_to_string(plurality.plural_category))); } -// 1.3.4 Intl.PluralRules.prototype.selectRange ( start, end ), https://tc39.es/proposal-intl-numberformat-v3/out/pluralrules/proposed.html#sec-intl.pluralrules.prototype.selectrange +// 16.3.4 Intl.PluralRules.prototype.selectRange ( start, end ), https://tc39.es/ecma402/#sec-intl.pluralrules.prototype.selectrange JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::select_range) { auto start = vm.argument(0); @@ -78,8 +77,7 @@ JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::select_range) return MUST_OR_THROW_OOM(PrimitiveString::create(vm, ::Locale::plural_category_to_string(plurality))); } -// 16.3.4 Intl.PluralRules.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.pluralrules.prototype.resolvedoptions -// 1.3.5 Intl.PluralRules.prototype.resolvedOptions ( ), https://tc39.es/proposal-intl-numberformat-v3/out/pluralrules/proposed.html#sec-intl.pluralrules.prototype.resolvedoptions +// 16.3.5 Intl.PluralRules.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.pluralrules.prototype.resolvedoptions JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::resolved_options) { auto& realm = *vm.current_realm(); diff --git a/Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.cpp b/Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.cpp index 1693e55ef5..c2c84c77cc 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.cpp @@ -178,7 +178,7 @@ ThrowCompletionOr<Vector<PatternPartitionWithUnit>> partition_relative_time_patt // 20. Let fv be ! PartitionNumberPattern(relativeTimeFormat.[[NumberFormat]], value). auto value_partitions = MUST_OR_THROW_OOM(partition_number_pattern(vm, relative_time_format.number_format(), Value(value))); - // 21. Let pr be ! ResolvePlural(relativeTimeFormat.[[PluralRules]], value). + // 21. Let pr be ! ResolvePlural(relativeTimeFormat.[[PluralRules]], value).[[PluralCategory]]. auto plurality = MUST_OR_THROW_OOM(resolve_plural(vm, relative_time_format.plural_rules(), Value(value))); // 22. Let pattern be po.[[<pr>]]. |