1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-28 05:17:34 +00:00

LibJS+LibLocale: Propagate errors from find_regional_values_for_locale

This had quite the footprint.
This commit is contained in:
Timothy Flynn 2023-01-27 11:12:01 -05:00 committed by Linus Groh
parent b2097f4059
commit 5e29e04122
16 changed files with 184 additions and 183 deletions

View file

@ -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 "".

View file

@ -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) {

View file

@ -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()) {

View file

@ -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)) });

View file

@ -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;
}

View file

@ -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;

View file

@ -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);