mirror of
https://github.com/RGBCube/serenity
synced 2025-07-28 01:07:44 +00:00
LibJS+LibLocale: Propagate errors from find_regional_values_for_locale
This had quite the footprint.
This commit is contained in:
parent
b2097f4059
commit
5e29e04122
16 changed files with 184 additions and 183 deletions
|
@ -433,7 +433,7 @@ ThrowCompletionOr<LocaleResult> resolve_locale(VM& vm, Vector<String> const& req
|
|||
// NOTE: ECMA-402 assumes keyLocaleData is sorted by locale preference. Our list is sorted
|
||||
// alphabetically, so we get the locale's preferred value from LibUnicode.
|
||||
Optional<String> value;
|
||||
if (auto preference = ::Locale::get_preferred_keyword_value_for_locale(found_locale, key); preference.has_value())
|
||||
if (auto preference = TRY_OR_THROW_OOM(vm, ::Locale::get_preferred_keyword_value_for_locale(found_locale, key)); preference.has_value())
|
||||
value = TRY_OR_THROW_OOM(vm, String::from_utf8(*preference));
|
||||
|
||||
// g. Let supportedExtensionAddition be "".
|
||||
|
|
|
@ -510,7 +510,7 @@ static Optional<StyleAndValue> find_calendar_field(StringView name, ::Locale::Ca
|
|||
return {};
|
||||
}
|
||||
|
||||
static Optional<StringView> resolve_day_period(StringView locale, StringView calendar, ::Locale::CalendarPatternStyle style, Span<PatternPartition const> pattern_parts, LocalTime local_time)
|
||||
static ThrowCompletionOr<Optional<StringView>> resolve_day_period(VM& vm, StringView locale, StringView calendar, ::Locale::CalendarPatternStyle style, Span<PatternPartition const> pattern_parts, LocalTime local_time)
|
||||
{
|
||||
// Use the "noon" day period if the locale has it, but only if the time is either exactly 12:00.00 or would be displayed as such.
|
||||
if (local_time.hour == 12) {
|
||||
|
@ -525,13 +525,13 @@ static Optional<StringView> resolve_day_period(StringView locale, StringView cal
|
|||
});
|
||||
|
||||
if (it == pattern_parts.end()) {
|
||||
auto noon_symbol = ::Locale::get_calendar_day_period_symbol(locale, calendar, style, ::Locale::DayPeriod::Noon);
|
||||
auto noon_symbol = TRY_OR_THROW_OOM(vm, ::Locale::get_calendar_day_period_symbol(locale, calendar, style, ::Locale::DayPeriod::Noon));
|
||||
if (noon_symbol.has_value())
|
||||
return *noon_symbol;
|
||||
}
|
||||
}
|
||||
|
||||
return ::Locale::get_calendar_day_period_symbol_for_hour(locale, calendar, style, local_time.hour);
|
||||
return TRY_OR_THROW_OOM(vm, ::Locale::get_calendar_day_period_symbol_for_hour(locale, calendar, style, local_time.hour));
|
||||
}
|
||||
|
||||
// 11.5.6 FormatDateTimePattern ( dateTimeFormat, patternParts, x, rangeFormatOptions ), https://tc39.es/ecma402/#sec-formatdatetimepattern
|
||||
|
@ -638,7 +638,7 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(VM& vm, Dat
|
|||
auto style = date_time_format.day_period();
|
||||
|
||||
// ii. Let fv be a String value representing the day period of tm in the form given by f; the String value depends upon the implementation and the effective locale of dateTimeFormat.
|
||||
auto symbol = resolve_day_period(data_locale, date_time_format.calendar(), style, pattern_parts, local_time);
|
||||
auto symbol = MUST_OR_THROW_OOM(resolve_day_period(vm, data_locale, date_time_format.calendar(), style, pattern_parts, local_time));
|
||||
if (symbol.has_value())
|
||||
formatted_value = TRY_OR_THROW_OOM(vm, String::from_utf8(*symbol));
|
||||
|
||||
|
@ -738,11 +738,11 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(VM& vm, Dat
|
|||
Optional<StringView> symbol;
|
||||
|
||||
if (part == "era"sv)
|
||||
symbol = ::Locale::get_calendar_era_symbol(data_locale, date_time_format.calendar(), style, static_cast<::Locale::Era>(value));
|
||||
symbol = TRY_OR_THROW_OOM(vm, ::Locale::get_calendar_era_symbol(data_locale, date_time_format.calendar(), style, static_cast<::Locale::Era>(value)));
|
||||
else if (part == "month"sv)
|
||||
symbol = ::Locale::get_calendar_month_symbol(data_locale, date_time_format.calendar(), style, static_cast<::Locale::Month>(value - 1));
|
||||
symbol = TRY_OR_THROW_OOM(vm, ::Locale::get_calendar_month_symbol(data_locale, date_time_format.calendar(), style, static_cast<::Locale::Month>(value - 1)));
|
||||
else if (part == "weekday"sv)
|
||||
symbol = ::Locale::get_calendar_weekday_symbol(data_locale, date_time_format.calendar(), style, static_cast<::Locale::Weekday>(value));
|
||||
symbol = TRY_OR_THROW_OOM(vm, ::Locale::get_calendar_weekday_symbol(data_locale, date_time_format.calendar(), style, static_cast<::Locale::Weekday>(value)));
|
||||
|
||||
if (symbol.has_value())
|
||||
formatted_value = TRY_OR_THROW_OOM(vm, String::from_utf8(*symbol));
|
||||
|
@ -770,13 +770,13 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(VM& vm, Dat
|
|||
// ii. If v is greater than 11, then
|
||||
if (value > 11) {
|
||||
// 1. Let fv be an implementation and locale dependent String value representing "post meridiem".
|
||||
auto symbol = ::Locale::get_calendar_day_period_symbol(data_locale, date_time_format.calendar(), ::Locale::CalendarPatternStyle::Short, ::Locale::DayPeriod::PM);
|
||||
auto symbol = TRY_OR_THROW_OOM(vm, ::Locale::get_calendar_day_period_symbol(data_locale, date_time_format.calendar(), ::Locale::CalendarPatternStyle::Short, ::Locale::DayPeriod::PM));
|
||||
formatted_value = TRY_OR_THROW_OOM(vm, String::from_utf8(symbol.value_or("PM"sv)));
|
||||
}
|
||||
// iii. Else,
|
||||
else {
|
||||
// 1. Let fv be an implementation and locale dependent String value representing "ante meridiem".
|
||||
auto symbol = ::Locale::get_calendar_day_period_symbol(data_locale, date_time_format.calendar(), ::Locale::CalendarPatternStyle::Short, ::Locale::DayPeriod::AM);
|
||||
auto symbol = TRY_OR_THROW_OOM(vm, ::Locale::get_calendar_day_period_symbol(data_locale, date_time_format.calendar(), ::Locale::CalendarPatternStyle::Short, ::Locale::DayPeriod::AM));
|
||||
formatted_value = TRY_OR_THROW_OOM(vm, String::from_utf8(symbol.value_or("AM"sv)));
|
||||
}
|
||||
|
||||
|
@ -805,7 +805,7 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(VM& vm, Dat
|
|||
// Non-standard, TR-35 requires the decimal separator before injected {fractionalSecondDigits} partitions
|
||||
// to adhere to the selected locale. This depends on other generated data, so it is deferred to here.
|
||||
else if (part == "decimal"sv) {
|
||||
auto decimal_symbol = ::Locale::get_number_system_symbol(data_locale, date_time_format.numbering_system(), ::Locale::NumericSymbol::Decimal).value_or("."sv);
|
||||
auto decimal_symbol = TRY_OR_THROW_OOM(vm, ::Locale::get_number_system_symbol(data_locale, date_time_format.numbering_system(), ::Locale::NumericSymbol::Decimal)).value_or("."sv);
|
||||
result.append({ "literal"sv, TRY_OR_THROW_OOM(vm, String::from_utf8(decimal_symbol)) });
|
||||
}
|
||||
|
||||
|
@ -892,29 +892,30 @@ ThrowCompletionOr<Array*> format_date_time_to_parts(VM& vm, DateTimeFormat& date
|
|||
}
|
||||
|
||||
template<typename Callback>
|
||||
void for_each_range_pattern_field(LocalTime const& time1, LocalTime const& time2, Callback&& callback)
|
||||
ThrowCompletionOr<void> for_each_range_pattern_field(LocalTime const& time1, LocalTime const& time2, Callback&& callback)
|
||||
{
|
||||
// Table 4: Range pattern fields, https://tc39.es/ecma402/#table-datetimeformat-rangepatternfields
|
||||
if (callback(static_cast<u8>(time1.era), static_cast<u8>(time2.era), ::Locale::CalendarRangePattern::Field::Era) == IterationDecision::Break)
|
||||
return;
|
||||
if (callback(time1.year, time2.year, ::Locale::CalendarRangePattern::Field::Year) == IterationDecision::Break)
|
||||
return;
|
||||
if (callback(time1.month, time2.month, ::Locale::CalendarRangePattern::Field::Month) == IterationDecision::Break)
|
||||
return;
|
||||
if (callback(time1.day, time2.day, ::Locale::CalendarRangePattern::Field::Day) == IterationDecision::Break)
|
||||
return;
|
||||
if (callback(time1.hour, time2.hour, ::Locale::CalendarRangePattern::Field::AmPm) == IterationDecision::Break)
|
||||
return;
|
||||
if (callback(time1.hour, time2.hour, ::Locale::CalendarRangePattern::Field::DayPeriod) == IterationDecision::Break)
|
||||
return;
|
||||
if (callback(time1.hour, time2.hour, ::Locale::CalendarRangePattern::Field::Hour) == IterationDecision::Break)
|
||||
return;
|
||||
if (callback(time1.minute, time2.minute, ::Locale::CalendarRangePattern::Field::Minute) == IterationDecision::Break)
|
||||
return;
|
||||
if (callback(time1.second, time2.second, ::Locale::CalendarRangePattern::Field::Second) == IterationDecision::Break)
|
||||
return;
|
||||
if (callback(time1.millisecond, time2.millisecond, ::Locale::CalendarRangePattern::Field::FractionalSecondDigits) == IterationDecision::Break)
|
||||
return;
|
||||
if (TRY(callback(static_cast<u8>(time1.era), static_cast<u8>(time2.era), ::Locale::CalendarRangePattern::Field::Era)) == IterationDecision::Break)
|
||||
return {};
|
||||
if (TRY(callback(time1.year, time2.year, ::Locale::CalendarRangePattern::Field::Year)) == IterationDecision::Break)
|
||||
return {};
|
||||
if (TRY(callback(time1.month, time2.month, ::Locale::CalendarRangePattern::Field::Month)) == IterationDecision::Break)
|
||||
return {};
|
||||
if (TRY(callback(time1.day, time2.day, ::Locale::CalendarRangePattern::Field::Day)) == IterationDecision::Break)
|
||||
return {};
|
||||
if (TRY(callback(time1.hour, time2.hour, ::Locale::CalendarRangePattern::Field::AmPm)) == IterationDecision::Break)
|
||||
return {};
|
||||
if (TRY(callback(time1.hour, time2.hour, ::Locale::CalendarRangePattern::Field::DayPeriod)) == IterationDecision::Break)
|
||||
return {};
|
||||
if (TRY(callback(time1.hour, time2.hour, ::Locale::CalendarRangePattern::Field::Hour)) == IterationDecision::Break)
|
||||
return {};
|
||||
if (TRY(callback(time1.minute, time2.minute, ::Locale::CalendarRangePattern::Field::Minute)) == IterationDecision::Break)
|
||||
return {};
|
||||
if (TRY(callback(time1.second, time2.second, ::Locale::CalendarRangePattern::Field::Second)) == IterationDecision::Break)
|
||||
return {};
|
||||
if (TRY(callback(time1.millisecond, time2.millisecond, ::Locale::CalendarRangePattern::Field::FractionalSecondDigits)) == IterationDecision::Break)
|
||||
return {};
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename Callback>
|
||||
|
@ -964,7 +965,7 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_
|
|||
bool pattern_contains_larger_date_field = false;
|
||||
|
||||
// 11. While dateFieldsPracticallyEqual is true and patternContainsLargerDateField is false, repeat for each row of Table 4 in order, except the header row:
|
||||
for_each_range_pattern_field(start_local_time, end_local_time, [&](auto start_value, auto end_value, auto field_name) {
|
||||
TRY(for_each_range_pattern_field(start_local_time, end_local_time, [&](auto start_value, auto end_value, auto field_name) -> ThrowCompletionOr<IterationDecision> {
|
||||
// a. Let fieldName be the name given in the Range Pattern Field column of the row.
|
||||
|
||||
// b. If rangePatterns has a field [[<fieldName>]], let rp be rangePatterns.[[<fieldName>]]; else let rp be undefined.
|
||||
|
@ -1003,10 +1004,10 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_
|
|||
// iii. Else if fieldName is equal to [[DayPeriod]], then
|
||||
case ::Locale::CalendarRangePattern::Field::DayPeriod: {
|
||||
// 1. Let v1 be a String value representing the day period of tm1; the String value depends upon the implementation and the effective locale of dateTimeFormat.
|
||||
auto start_period = ::Locale::get_calendar_day_period_symbol_for_hour(date_time_format.data_locale(), date_time_format.calendar(), ::Locale::CalendarPatternStyle::Short, start_value);
|
||||
auto start_period = TRY_OR_THROW_OOM(vm, ::Locale::get_calendar_day_period_symbol_for_hour(date_time_format.data_locale(), date_time_format.calendar(), ::Locale::CalendarPatternStyle::Short, start_value));
|
||||
|
||||
// 2. Let v2 be a String value representing the day period of tm2; the String value depends upon the implementation and the effective locale of dateTimeFormat.
|
||||
auto end_period = ::Locale::get_calendar_day_period_symbol_for_hour(date_time_format.data_locale(), date_time_format.calendar(), ::Locale::CalendarPatternStyle::Short, end_value);
|
||||
auto end_period = TRY_OR_THROW_OOM(vm, ::Locale::get_calendar_day_period_symbol_for_hour(date_time_format.data_locale(), date_time_format.calendar(), ::Locale::CalendarPatternStyle::Short, end_value));
|
||||
|
||||
// 3. If v1 is not equal to v2, then
|
||||
if (start_period != end_period) {
|
||||
|
@ -1066,7 +1067,7 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_
|
|||
if (date_fields_practically_equal && !pattern_contains_larger_date_field)
|
||||
return IterationDecision::Continue;
|
||||
return IterationDecision::Break;
|
||||
});
|
||||
}));
|
||||
|
||||
// 12. If dateFieldsPracticallyEqual is true, then
|
||||
if (date_fields_practically_equal) {
|
||||
|
|
|
@ -166,7 +166,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM& vm, DateTimeF
|
|||
|
||||
// 23. Let dataLocaleData be localeData.[[<dataLocale>]].
|
||||
// 24. Let hcDefault be dataLocaleData.[[hourCycle]].
|
||||
auto default_hour_cycle = ::Locale::get_default_regional_hour_cycle(data_locale);
|
||||
auto default_hour_cycle = TRY_OR_THROW_OOM(vm, ::Locale::get_default_regional_hour_cycle(data_locale));
|
||||
|
||||
// Non-standard, default_hour_cycle will be empty if Unicode data generation is disabled.
|
||||
if (!default_hour_cycle.has_value()) {
|
||||
|
|
|
@ -481,7 +481,7 @@ ThrowCompletionOr<Vector<PatternPartition>> partition_duration_format_pattern(VM
|
|||
// c. If nextValue is not 0 or nextDisplay is not "auto", then
|
||||
if (next_value != 0.0 || next_display != DurationFormat::Display::Auto) {
|
||||
// i. Let separator be dataLocaleData.[[formats]].[[digital]].[[separator]].
|
||||
auto separator = ::Locale::get_number_system_symbol(data_locale, duration_format.numbering_system(), ::Locale::NumericSymbol::TimeSeparator).value_or(":"sv);
|
||||
auto separator = TRY_OR_THROW_OOM(vm, ::Locale::get_number_system_symbol(data_locale, duration_format.numbering_system(), ::Locale::NumericSymbol::TimeSeparator)).value_or(":"sv);
|
||||
|
||||
// ii. Append the new Record { [[Type]]: "literal", [[Value]]: separator} to the end of result.
|
||||
result.append({ "literal"sv, TRY_OR_THROW_OOM(vm, String::from_utf8(separator)) });
|
||||
|
|
|
@ -80,7 +80,7 @@ ThrowCompletionOr<NonnullGCPtr<Array>> calendars_of_locale(VM& vm, Locale const&
|
|||
VERIFY(TRY_OR_THROW_OOM(vm, ::Locale::parse_unicode_locale_id(locale)).has_value());
|
||||
|
||||
// 4. Let list be a List of 1 or more unique canonical calendar identifiers, which must be lower case String values conforming to the type sequence from UTS 35 Unicode Locale Identifier, section 3.2, sorted in descending preference of those in common use for date and time formatting in locale.
|
||||
auto list = ::Locale::get_keywords_for_locale(locale, "ca"sv);
|
||||
auto list = TRY_OR_THROW_OOM(vm, ::Locale::get_keywords_for_locale(locale, "ca"sv));
|
||||
|
||||
// 5. Return ! CreateArrayFromListOrRestricted( list, restricted ).
|
||||
return create_array_from_list_or_restricted(vm, move(list), move(restricted));
|
||||
|
@ -99,7 +99,7 @@ ThrowCompletionOr<NonnullGCPtr<Array>> collations_of_locale(VM& vm, Locale const
|
|||
VERIFY(TRY_OR_THROW_OOM(vm, ::Locale::parse_unicode_locale_id(locale)).has_value());
|
||||
|
||||
// 4. Let list be a List of 1 or more unique canonical collation identifiers, which must be lower case String values conforming to the type sequence from UTS 35 Unicode Locale Identifier, section 3.2, ordered as if an Array of the same values had been sorted, using %Array.prototype.sort% using undefined as comparefn, of those in common use for string comparison in locale. The values "standard" and "search" must be excluded from list.
|
||||
auto list = ::Locale::get_keywords_for_locale(locale, "co"sv);
|
||||
auto list = TRY_OR_THROW_OOM(vm, ::Locale::get_keywords_for_locale(locale, "co"sv));
|
||||
|
||||
// 5. Return ! CreateArrayFromListOrRestricted( list, restricted ).
|
||||
return create_array_from_list_or_restricted(vm, move(list), move(restricted));
|
||||
|
@ -118,7 +118,7 @@ ThrowCompletionOr<NonnullGCPtr<Array>> hour_cycles_of_locale(VM& vm, Locale cons
|
|||
VERIFY(TRY_OR_THROW_OOM(vm, ::Locale::parse_unicode_locale_id(locale)).has_value());
|
||||
|
||||
// 4. Let list be a List of 1 or more unique hour cycle identifiers, which must be lower case String values indicating either the 12-hour format ("h11", "h12") or the 24-hour format ("h23", "h24"), sorted in descending preference of those in common use for date and time formatting in locale.
|
||||
auto list = ::Locale::get_keywords_for_locale(locale, "hc"sv);
|
||||
auto list = TRY_OR_THROW_OOM(vm, ::Locale::get_keywords_for_locale(locale, "hc"sv));
|
||||
|
||||
// 5. Return ! CreateArrayFromListOrRestricted( list, restricted ).
|
||||
return create_array_from_list_or_restricted(vm, move(list), move(restricted));
|
||||
|
@ -137,7 +137,7 @@ ThrowCompletionOr<NonnullGCPtr<Array>> numbering_systems_of_locale(VM& vm, Local
|
|||
VERIFY(TRY_OR_THROW_OOM(vm, ::Locale::parse_unicode_locale_id(locale)).has_value());
|
||||
|
||||
// 4. Let list be a List of 1 or more unique canonical numbering system identifiers, which must be lower case String values conforming to the type sequence from UTS 35 Unicode Locale Identifier, section 3.2, sorted in descending preference of those in common use for formatting numeric values in locale.
|
||||
auto list = ::Locale::get_keywords_for_locale(locale, "nu"sv);
|
||||
auto list = TRY_OR_THROW_OOM(vm, ::Locale::get_keywords_for_locale(locale, "nu"sv));
|
||||
|
||||
// 5. Return ! CreateArrayFromListOrRestricted( list, restricted ).
|
||||
return create_array_from_list_or_restricted(vm, move(list), move(restricted));
|
||||
|
@ -206,17 +206,17 @@ static u8 weekday_to_integer(Optional<::Locale::Weekday> weekday, ::Locale::Week
|
|||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
static Vector<u8> weekend_of_locale(StringView locale)
|
||||
static ThrowCompletionOr<Vector<u8>> weekend_of_locale(VM& vm, StringView locale)
|
||||
{
|
||||
auto weekend_start = weekday_to_integer(::Locale::get_locale_weekend_start(locale), ::Locale::Weekday::Saturday);
|
||||
auto weekend_end = weekday_to_integer(::Locale::get_locale_weekend_end(locale), ::Locale::Weekday::Sunday);
|
||||
auto weekend_start = weekday_to_integer(TRY_OR_THROW_OOM(vm, ::Locale::get_locale_weekend_start(locale)), ::Locale::Weekday::Saturday);
|
||||
auto weekend_end = weekday_to_integer(TRY_OR_THROW_OOM(vm, ::Locale::get_locale_weekend_end(locale)), ::Locale::Weekday::Sunday);
|
||||
|
||||
// There currently aren't any regions in the CLDR which wrap around from Sunday (7) to Monday (1).
|
||||
// If this changes, this logic will need to be updated to handle that.
|
||||
VERIFY(weekend_start <= weekend_end);
|
||||
|
||||
Vector<u8> weekend;
|
||||
weekend.ensure_capacity(weekend_end - weekend_start + 1);
|
||||
TRY_OR_THROW_OOM(vm, weekend.try_ensure_capacity(weekend_end - weekend_start + 1));
|
||||
|
||||
for (auto day = weekend_start; day <= weekend_end; ++day)
|
||||
weekend.unchecked_append(day);
|
||||
|
@ -235,9 +235,9 @@ ThrowCompletionOr<WeekInfo> week_info_of_locale(VM& vm, Locale const& locale_obj
|
|||
|
||||
// 3. Return a record whose fields are defined by Table 1, with values based on locale.
|
||||
WeekInfo week_info {};
|
||||
week_info.minimal_days = ::Locale::get_locale_minimum_days(locale).value_or(1);
|
||||
week_info.first_day = weekday_to_integer(::Locale::get_locale_first_day(locale), ::Locale::Weekday::Monday);
|
||||
week_info.weekend = weekend_of_locale(locale);
|
||||
week_info.minimal_days = TRY_OR_THROW_OOM(vm, ::Locale::get_locale_minimum_days(locale)).value_or(1);
|
||||
week_info.first_day = weekday_to_integer(TRY_OR_THROW_OOM(vm, ::Locale::get_locale_first_day(locale)), ::Locale::Weekday::Monday);
|
||||
week_info.weekend = MUST_OR_THROW_OOM(weekend_of_locale(vm, locale));
|
||||
|
||||
return week_info;
|
||||
}
|
||||
|
|
|
@ -529,13 +529,13 @@ ThrowCompletionOr<Vector<PatternPartition>> partition_number_pattern(VM& vm, Num
|
|||
// 2. If x is not-a-number, then
|
||||
if (number.is_nan()) {
|
||||
// a. Let n be an implementation- and locale-dependent (ILD) String value indicating the NaN value.
|
||||
auto symbol = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::NaN).value_or("NaN"sv);
|
||||
auto symbol = TRY_OR_THROW_OOM(vm, ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::NaN)).value_or("NaN"sv);
|
||||
formatted_string = TRY_OR_THROW_OOM(vm, String::from_utf8(symbol));
|
||||
}
|
||||
// 3. Else if x is positive-infinity, then
|
||||
else if (number.is_positive_infinity()) {
|
||||
// a. Let n be an ILD String value indicating positive infinity.
|
||||
auto symbol = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::Infinity).value_or("infinity"sv);
|
||||
auto symbol = TRY_OR_THROW_OOM(vm, ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::Infinity)).value_or("infinity"sv);
|
||||
formatted_string = TRY_OR_THROW_OOM(vm, String::from_utf8(symbol));
|
||||
}
|
||||
// 4. Else if x is negative-infinity, then
|
||||
|
@ -543,7 +543,7 @@ ThrowCompletionOr<Vector<PatternPartition>> partition_number_pattern(VM& vm, Num
|
|||
// a. Let n be an ILD String value indicating negative infinity.
|
||||
// NOTE: The CLDR does not contain unique strings for negative infinity. The negative sign will
|
||||
// be inserted by the pattern returned from GetNumberFormatPattern.
|
||||
auto symbol = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::Infinity).value_or("infinity"sv);
|
||||
auto symbol = TRY_OR_THROW_OOM(vm, ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::Infinity)).value_or("infinity"sv);
|
||||
formatted_string = TRY_OR_THROW_OOM(vm, String::from_utf8(symbol));
|
||||
}
|
||||
// 5. Else,
|
||||
|
@ -609,7 +609,7 @@ ThrowCompletionOr<Vector<PatternPartition>> partition_number_pattern(VM& vm, Num
|
|||
// d. Else if p is equal to "plusSign", then
|
||||
else if (part == "plusSign"sv) {
|
||||
// i. Let plusSignSymbol be the ILND String representing the plus sign.
|
||||
auto plus_sign_symbol = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::PlusSign).value_or("+"sv);
|
||||
auto plus_sign_symbol = TRY_OR_THROW_OOM(vm, ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::PlusSign)).value_or("+"sv);
|
||||
// ii. Append a new Record { [[Type]]: "plusSign", [[Value]]: plusSignSymbol } as the last element of result.
|
||||
result.append({ "plusSign"sv, TRY_OR_THROW_OOM(vm, String::from_utf8(plus_sign_symbol)) });
|
||||
}
|
||||
|
@ -617,7 +617,7 @@ ThrowCompletionOr<Vector<PatternPartition>> partition_number_pattern(VM& vm, Num
|
|||
// e. Else if p is equal to "minusSign", then
|
||||
else if (part == "minusSign"sv) {
|
||||
// i. Let minusSignSymbol be the ILND String representing the minus sign.
|
||||
auto minus_sign_symbol = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::MinusSign).value_or("-"sv);
|
||||
auto minus_sign_symbol = TRY_OR_THROW_OOM(vm, ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::MinusSign)).value_or("-"sv);
|
||||
// ii. Append a new Record { [[Type]]: "minusSign", [[Value]]: minusSignSymbol } as the last element of result.
|
||||
result.append({ "minusSign"sv, TRY_OR_THROW_OOM(vm, String::from_utf8(minus_sign_symbol)) });
|
||||
}
|
||||
|
@ -625,7 +625,7 @@ ThrowCompletionOr<Vector<PatternPartition>> partition_number_pattern(VM& vm, Num
|
|||
// f. Else if p is equal to "percentSign" and numberFormat.[[Style]] is "percent", then
|
||||
else if ((part == "percentSign"sv) && (number_format.style() == NumberFormat::Style::Percent)) {
|
||||
// i. Let percentSignSymbol be the ILND String representing the percent sign.
|
||||
auto percent_sign_symbol = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::PercentSign).value_or("%"sv);
|
||||
auto percent_sign_symbol = TRY_OR_THROW_OOM(vm, ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::PercentSign)).value_or("%"sv);
|
||||
// ii. Append a new Record { [[Type]]: "percentSign", [[Value]]: percentSignSymbol } as the last element of result.
|
||||
result.append({ "percentSign"sv, TRY_OR_THROW_OOM(vm, String::from_utf8(percent_sign_symbol)) });
|
||||
}
|
||||
|
@ -725,7 +725,7 @@ ThrowCompletionOr<Vector<PatternPartition>> partition_notation_sub_pattern(VM& v
|
|||
// 1. Let result be a new empty List.
|
||||
Vector<PatternPartition> result;
|
||||
|
||||
auto grouping_sizes = ::Locale::get_number_system_groupings(number_format.data_locale(), number_format.numbering_system());
|
||||
auto grouping_sizes = TRY_OR_THROW_OOM(vm, ::Locale::get_number_system_groupings(number_format.data_locale(), number_format.numbering_system()));
|
||||
if (!grouping_sizes.has_value())
|
||||
return Vector<PatternPartition> {};
|
||||
|
||||
|
@ -742,7 +742,7 @@ ThrowCompletionOr<Vector<PatternPartition>> partition_notation_sub_pattern(VM& v
|
|||
// 4. Else,
|
||||
else {
|
||||
// a. Let notationSubPattern be GetNotationSubPattern(numberFormat, exponent).
|
||||
auto notation_sub_pattern = get_notation_sub_pattern(number_format, exponent);
|
||||
auto notation_sub_pattern = MUST_OR_THROW_OOM(get_notation_sub_pattern(vm, number_format, exponent));
|
||||
if (!notation_sub_pattern.has_value())
|
||||
return Vector<PatternPartition> {};
|
||||
|
||||
|
@ -808,7 +808,7 @@ ThrowCompletionOr<Vector<PatternPartition>> partition_notation_sub_pattern(VM& v
|
|||
// 7. Else,
|
||||
else {
|
||||
// a. Let groupSepSymbol be the implementation-, locale-, and numbering system-dependent (ILND) String representing the grouping separator.
|
||||
auto group_sep_symbol = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::Group).value_or(","sv);
|
||||
auto group_sep_symbol = TRY_OR_THROW_OOM(vm, ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::Group)).value_or(","sv);
|
||||
|
||||
// b. Let groups be a List whose elements are, in left to right order, the substrings defined by ILND set of locations within the integer, which may depend on the value of numberFormat.[[UseGrouping]].
|
||||
auto groups = separate_integer_into_groups(*grouping_sizes, integer, number_format.use_grouping());
|
||||
|
@ -835,7 +835,7 @@ ThrowCompletionOr<Vector<PatternPartition>> partition_notation_sub_pattern(VM& v
|
|||
// 8. If fraction is not undefined, then
|
||||
if (fraction.has_value()) {
|
||||
// a. Let decimalSepSymbol be the ILND String representing the decimal separator.
|
||||
auto decimal_sep_symbol = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::Decimal).value_or("."sv);
|
||||
auto decimal_sep_symbol = TRY_OR_THROW_OOM(vm, ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::Decimal)).value_or("."sv);
|
||||
// b. Append a new Record { [[Type]]: "decimal", [[Value]]: decimalSepSymbol } as the last element of result.
|
||||
result.append({ "decimal"sv, TRY_OR_THROW_OOM(vm, String::from_utf8(decimal_sep_symbol)) });
|
||||
// c. Append a new Record { [[Type]]: "fraction", [[Value]]: fraction } as the last element of result.
|
||||
|
@ -859,7 +859,7 @@ ThrowCompletionOr<Vector<PatternPartition>> partition_notation_sub_pattern(VM& v
|
|||
// vi. Else if p is equal to "scientificSeparator", then
|
||||
else if (part == "scientificSeparator"sv) {
|
||||
// 1. Let scientificSeparator be the ILND String representing the exponent separator.
|
||||
auto scientific_separator = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::Exponential).value_or("E"sv);
|
||||
auto scientific_separator = TRY_OR_THROW_OOM(vm, ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::Exponential)).value_or("E"sv);
|
||||
// 2. Append a new Record { [[Type]]: "exponentSeparator", [[Value]]: scientificSeparator } as the last element of result.
|
||||
result.append({ "exponentSeparator"sv, TRY_OR_THROW_OOM(vm, String::from_utf8(scientific_separator)) });
|
||||
}
|
||||
|
@ -868,7 +868,7 @@ ThrowCompletionOr<Vector<PatternPartition>> partition_notation_sub_pattern(VM& v
|
|||
// 1. If exponent < 0, then
|
||||
if (exponent < 0) {
|
||||
// a. Let minusSignSymbol be the ILND String representing the minus sign.
|
||||
auto minus_sign_symbol = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::MinusSign).value_or("-"sv);
|
||||
auto minus_sign_symbol = TRY_OR_THROW_OOM(vm, ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::MinusSign)).value_or("-"sv);
|
||||
|
||||
// b. Append a new Record { [[Type]]: "exponentMinusSign", [[Value]]: minusSignSymbol } as the last element of result.
|
||||
result.append({ "exponentMinusSign"sv, TRY_OR_THROW_OOM(vm, String::from_utf8(minus_sign_symbol)) });
|
||||
|
@ -1292,7 +1292,7 @@ ThrowCompletionOr<Optional<Variant<StringView, String>>> get_number_format_patte
|
|||
// 7. If style is "percent", then
|
||||
case NumberFormat::Style::Percent:
|
||||
// a. Let patterns be patterns.[[percent]].
|
||||
patterns = ::Locale::get_standard_number_system_format(number_format.data_locale(), number_format.numbering_system(), ::Locale::StandardNumberFormatType::Percent);
|
||||
patterns = TRY_OR_THROW_OOM(vm, ::Locale::get_standard_number_system_format(number_format.data_locale(), number_format.numbering_system(), ::Locale::StandardNumberFormatType::Percent));
|
||||
break;
|
||||
|
||||
// 8. Else if style is "unit", then
|
||||
|
@ -1327,7 +1327,7 @@ ThrowCompletionOr<Optional<Variant<StringView, String>>> get_number_format_patte
|
|||
|
||||
// Handling of other [[CurrencyDisplay]] options will occur after [[SignDisplay]].
|
||||
if (number_format.currency_display() == NumberFormat::CurrencyDisplay::Name) {
|
||||
auto formats = ::Locale::get_compact_number_system_formats(number_format.data_locale(), number_format.numbering_system(), ::Locale::CompactNumberFormatType::CurrencyUnit);
|
||||
auto formats = TRY_OR_THROW_OOM(vm, ::Locale::get_compact_number_system_formats(number_format.data_locale(), number_format.numbering_system(), ::Locale::CompactNumberFormatType::CurrencyUnit));
|
||||
auto plurality = MUST_OR_THROW_OOM(resolve_plural(vm, number_format, ::Locale::PluralForm::Cardinal, number.to_value(vm)));
|
||||
|
||||
if (auto it = formats.find_if([&](auto& p) { return p.plurality == plurality; }); it != formats.end()) {
|
||||
|
@ -1338,10 +1338,10 @@ ThrowCompletionOr<Optional<Variant<StringView, String>>> get_number_format_patte
|
|||
|
||||
switch (number_format.currency_sign()) {
|
||||
case NumberFormat::CurrencySign::Standard:
|
||||
patterns = ::Locale::get_standard_number_system_format(number_format.data_locale(), number_format.numbering_system(), ::Locale::StandardNumberFormatType::Currency);
|
||||
patterns = TRY_OR_THROW_OOM(vm, ::Locale::get_standard_number_system_format(number_format.data_locale(), number_format.numbering_system(), ::Locale::StandardNumberFormatType::Currency));
|
||||
break;
|
||||
case NumberFormat::CurrencySign::Accounting:
|
||||
patterns = ::Locale::get_standard_number_system_format(number_format.data_locale(), number_format.numbering_system(), ::Locale::StandardNumberFormatType::Accounting);
|
||||
patterns = TRY_OR_THROW_OOM(vm, ::Locale::get_standard_number_system_format(number_format.data_locale(), number_format.numbering_system(), ::Locale::StandardNumberFormatType::Accounting));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1351,7 +1351,7 @@ ThrowCompletionOr<Optional<Variant<StringView, String>>> get_number_format_patte
|
|||
case NumberFormat::Style::Decimal:
|
||||
// a. Assert: style is "decimal".
|
||||
// b. Let patterns be patterns.[[decimal]].
|
||||
patterns = ::Locale::get_standard_number_system_format(number_format.data_locale(), number_format.numbering_system(), ::Locale::StandardNumberFormatType::Decimal);
|
||||
patterns = TRY_OR_THROW_OOM(vm, ::Locale::get_standard_number_system_format(number_format.data_locale(), number_format.numbering_system(), ::Locale::StandardNumberFormatType::Decimal));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1453,7 +1453,7 @@ ThrowCompletionOr<Optional<Variant<StringView, String>>> get_number_format_patte
|
|||
}
|
||||
|
||||
// 15.5.12 GetNotationSubPattern ( numberFormat, exponent ), https://tc39.es/ecma402/#sec-getnotationsubpattern
|
||||
Optional<StringView> get_notation_sub_pattern(NumberFormat& number_format, int exponent)
|
||||
ThrowCompletionOr<Optional<StringView>> get_notation_sub_pattern(VM& vm, NumberFormat& number_format, int exponent)
|
||||
{
|
||||
// 1. Let localeData be %NumberFormat%.[[LocaleData]].
|
||||
// 2. Let dataLocale be numberFormat.[[DataLocale]].
|
||||
|
@ -1467,9 +1467,9 @@ Optional<StringView> get_notation_sub_pattern(NumberFormat& number_format, int e
|
|||
// 7. If notation is "scientific" or notation is "engineering", then
|
||||
if ((notation == NumberFormat::Notation::Scientific) || (notation == NumberFormat::Notation::Engineering)) {
|
||||
// a. Return notationSubPatterns.[[scientific]].
|
||||
auto notation_sub_patterns = ::Locale::get_standard_number_system_format(number_format.data_locale(), number_format.numbering_system(), ::Locale::StandardNumberFormatType::Scientific);
|
||||
auto notation_sub_patterns = TRY_OR_THROW_OOM(vm, ::Locale::get_standard_number_system_format(number_format.data_locale(), number_format.numbering_system(), ::Locale::StandardNumberFormatType::Scientific));
|
||||
if (!notation_sub_patterns.has_value())
|
||||
return {};
|
||||
return OptionalNone {};
|
||||
|
||||
return notation_sub_patterns->zero_format;
|
||||
}
|
||||
|
@ -1509,7 +1509,7 @@ ThrowCompletionOr<int> compute_exponent(VM& vm, NumberFormat& number_format, Mat
|
|||
int magnitude = number.logarithmic_floor();
|
||||
|
||||
// 4. Let exponent be ComputeExponentForMagnitude(numberFormat, magnitude).
|
||||
int exponent = compute_exponent_for_magnitude(number_format, magnitude);
|
||||
int exponent = MUST_OR_THROW_OOM(compute_exponent_for_magnitude(vm, number_format, magnitude));
|
||||
|
||||
// 5. Let x be x × 10^(-exponent).
|
||||
number = number.multiplied_by_power(-exponent);
|
||||
|
@ -1533,11 +1533,11 @@ ThrowCompletionOr<int> compute_exponent(VM& vm, NumberFormat& number_format, Mat
|
|||
}
|
||||
|
||||
// 10. Return ComputeExponentForMagnitude(numberFormat, magnitude + 1).
|
||||
return compute_exponent_for_magnitude(number_format, magnitude + 1);
|
||||
return MUST_OR_THROW_OOM(compute_exponent_for_magnitude(vm, number_format, magnitude + 1));
|
||||
}
|
||||
|
||||
// 15.5.14 ComputeExponentForMagnitude ( numberFormat, magnitude ), https://tc39.es/ecma402/#sec-computeexponentformagnitude
|
||||
int compute_exponent_for_magnitude(NumberFormat& number_format, int magnitude)
|
||||
ThrowCompletionOr<int> compute_exponent_for_magnitude(VM& vm, NumberFormat& number_format, int magnitude)
|
||||
{
|
||||
// 1. Let notation be numberFormat.[[Notation]].
|
||||
switch (number_format.notation()) {
|
||||
|
@ -1570,11 +1570,11 @@ int compute_exponent_for_magnitude(NumberFormat& number_format, int magnitude)
|
|||
Vector<::Locale::NumberFormat> format_rules;
|
||||
|
||||
if (number_format.style() == NumberFormat::Style::Currency)
|
||||
format_rules = ::Locale::get_compact_number_system_formats(number_format.data_locale(), number_format.numbering_system(), ::Locale::CompactNumberFormatType::CurrencyShort);
|
||||
format_rules = TRY_OR_THROW_OOM(vm, ::Locale::get_compact_number_system_formats(number_format.data_locale(), number_format.numbering_system(), ::Locale::CompactNumberFormatType::CurrencyShort));
|
||||
else if (number_format.compact_display() == NumberFormat::CompactDisplay::Long)
|
||||
format_rules = ::Locale::get_compact_number_system_formats(number_format.data_locale(), number_format.numbering_system(), ::Locale::CompactNumberFormatType::DecimalLong);
|
||||
format_rules = TRY_OR_THROW_OOM(vm, ::Locale::get_compact_number_system_formats(number_format.data_locale(), number_format.numbering_system(), ::Locale::CompactNumberFormatType::DecimalLong));
|
||||
else
|
||||
format_rules = ::Locale::get_compact_number_system_formats(number_format.data_locale(), number_format.numbering_system(), ::Locale::CompactNumberFormatType::DecimalShort);
|
||||
format_rules = TRY_OR_THROW_OOM(vm, ::Locale::get_compact_number_system_formats(number_format.data_locale(), number_format.numbering_system(), ::Locale::CompactNumberFormatType::DecimalShort));
|
||||
|
||||
::Locale::NumberFormat const* best_number_format = nullptr;
|
||||
|
||||
|
@ -1782,7 +1782,7 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_number_range_pat
|
|||
result = move(start_result);
|
||||
|
||||
// 8. Let rangeSeparator be an ILND String value used to separate two numbers.
|
||||
auto range_separator_symbol = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::RangeSeparator).value_or("-"sv);
|
||||
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.
|
||||
|
@ -1812,7 +1812,7 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> format_approximately(VM& v
|
|||
{
|
||||
// 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.
|
||||
auto approximately_sign = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::ApproximatelySign).value_or("~"sv);
|
||||
auto approximately_sign = TRY_OR_THROW_OOM(vm, ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::ApproximatelySign)).value_or("~"sv);
|
||||
|
||||
// 3. Insert a new Record { [[Type]]: "approximatelySign", [[Value]]: approximatelySign } at index i in result.
|
||||
PatternPartitionWithSource partition;
|
||||
|
|
|
@ -284,9 +284,9 @@ ThrowCompletionOr<Array*> format_numeric_to_parts(VM&, NumberFormat&, Mathematic
|
|||
ThrowCompletionOr<RawFormatResult> to_raw_precision(VM&, MathematicalValue const& number, int min_precision, int max_precision, Optional<NumberFormat::UnsignedRoundingMode> const& unsigned_rounding_mode);
|
||||
ThrowCompletionOr<RawFormatResult> to_raw_fixed(VM&, MathematicalValue const& number, int min_fraction, int max_fraction, int rounding_increment, Optional<NumberFormat::UnsignedRoundingMode> const& unsigned_rounding_mode);
|
||||
ThrowCompletionOr<Optional<Variant<StringView, String>>> get_number_format_pattern(VM&, NumberFormat&, MathematicalValue const& number, ::Locale::NumberFormat& found_pattern);
|
||||
Optional<StringView> get_notation_sub_pattern(NumberFormat&, int exponent);
|
||||
ThrowCompletionOr<Optional<StringView>> get_notation_sub_pattern(VM&, NumberFormat&, int exponent);
|
||||
ThrowCompletionOr<int> compute_exponent(VM&, NumberFormat&, MathematicalValue number);
|
||||
int compute_exponent_for_magnitude(NumberFormat&, int magnitude);
|
||||
ThrowCompletionOr<int> compute_exponent_for_magnitude(VM&, NumberFormat&, int magnitude);
|
||||
ThrowCompletionOr<MathematicalValue> to_intl_mathematical_value(VM&, Value value);
|
||||
NumberFormat::UnsignedRoundingMode get_unsigned_rounding_mode(NumberFormat::RoundingMode, bool is_negative);
|
||||
RoundingDecision apply_unsigned_rounding_mode(MathematicalValue const& x, MathematicalValue const& r1, MathematicalValue const& r2, Optional<NumberFormat::UnsignedRoundingMode> const& unsigned_rounding_mode);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue