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

@ -2093,7 +2093,7 @@ Optional<@return_type@> get_regional_@lookup_type@(StringView region)
append_regional_lookup("Weekday"sv, "weekend_end"sv);
generator.append(R"~~~(
static CalendarData const* find_calendar_data(StringView locale, StringView calendar)
static ErrorOr<CalendarData const*> find_calendar_data(StringView locale, StringView calendar)
{
auto locale_value = locale_from_string(locale);
if (!locale_value.has_value())
@ -2120,7 +2120,7 @@ static CalendarData const* find_calendar_data(StringView locale, StringView cale
if (auto const* calendar_data = lookup_calendar(calendar))
return calendar_data;
auto default_calendar = get_preferred_keyword_value_for_locale(locale, "ca"sv);
auto default_calendar = TRY(get_preferred_keyword_value_for_locale(locale, "ca"sv));
if (!default_calendar.has_value())
return nullptr;
@ -2129,7 +2129,7 @@ static CalendarData const* find_calendar_data(StringView locale, StringView cale
ErrorOr<Optional<CalendarFormat>> get_calendar_date_format(StringView locale, StringView calendar)
{
if (auto const* data = find_calendar_data(locale, calendar); data != nullptr) {
if (auto const* data = TRY(find_calendar_data(locale, calendar)); data != nullptr) {
auto const& formats = s_calendar_formats.at(data->date_formats);
return TRY(formats.to_unicode_calendar_format());
}
@ -2138,7 +2138,7 @@ ErrorOr<Optional<CalendarFormat>> get_calendar_date_format(StringView locale, St
ErrorOr<Optional<CalendarFormat>> get_calendar_time_format(StringView locale, StringView calendar)
{
if (auto const* data = find_calendar_data(locale, calendar); data != nullptr) {
if (auto const* data = TRY(find_calendar_data(locale, calendar)); data != nullptr) {
auto const& formats = s_calendar_formats.at(data->time_formats);
return TRY(formats.to_unicode_calendar_format());
}
@ -2147,7 +2147,7 @@ ErrorOr<Optional<CalendarFormat>> get_calendar_time_format(StringView locale, St
ErrorOr<Optional<CalendarFormat>> get_calendar_date_time_format(StringView locale, StringView calendar)
{
if (auto const* data = find_calendar_data(locale, calendar); data != nullptr) {
if (auto const* data = TRY(find_calendar_data(locale, calendar)); data != nullptr) {
auto const& formats = s_calendar_formats.at(data->date_time_formats);
return TRY(formats.to_unicode_calendar_format());
}
@ -2158,7 +2158,7 @@ ErrorOr<Vector<CalendarPattern>> get_calendar_available_formats(StringView local
{
Vector<CalendarPattern> result {};
if (auto const* data = find_calendar_data(locale, calendar); data != nullptr) {
if (auto const* data = TRY(find_calendar_data(locale, calendar)); data != nullptr) {
auto const& available_formats = s_calendar_pattern_lists.at(data->available_formats);
TRY(result.try_ensure_capacity(available_formats.size()));
@ -2171,7 +2171,7 @@ ErrorOr<Vector<CalendarPattern>> get_calendar_available_formats(StringView local
ErrorOr<Optional<CalendarRangePattern>> get_calendar_default_range_format(StringView locale, StringView calendar)
{
if (auto const* data = find_calendar_data(locale, calendar); data != nullptr) {
if (auto const* data = TRY(find_calendar_data(locale, calendar)); data != nullptr) {
auto const& pattern = s_calendar_range_patterns[data->default_range_format];
return TRY(pattern.to_unicode_calendar_range_pattern());
}
@ -2183,7 +2183,7 @@ ErrorOr<Vector<CalendarRangePattern>> get_calendar_range_formats(StringView loca
{
Vector<CalendarRangePattern> result {};
if (auto const* data = find_calendar_data(locale, calendar); data != nullptr) {
if (auto const* data = TRY(find_calendar_data(locale, calendar)); data != nullptr) {
auto const& range_formats = s_calendar_range_pattern_lists.at(data->range_formats);
for (auto format : range_formats) {
@ -2201,7 +2201,7 @@ ErrorOr<Vector<CalendarRangePattern>> get_calendar_range12_formats(StringView lo
{
Vector<CalendarRangePattern> result {};
if (auto const* data = find_calendar_data(locale, calendar); data != nullptr) {
if (auto const* data = TRY(find_calendar_data(locale, calendar)); data != nullptr) {
auto const& range12_formats = s_calendar_range_pattern_lists.at(data->range12_formats);
for (auto format : range12_formats) {
@ -2215,9 +2215,9 @@ ErrorOr<Vector<CalendarRangePattern>> get_calendar_range12_formats(StringView lo
return result;
}
static Span<@string_index_type@ const> find_calendar_symbols(StringView locale, StringView calendar, CalendarSymbol symbol, CalendarPatternStyle style)
static ErrorOr<Span<@string_index_type@ const>> find_calendar_symbols(StringView locale, StringView calendar, CalendarSymbol symbol, CalendarPatternStyle style)
{
if (auto const* data = find_calendar_data(locale, calendar); data != nullptr) {
if (auto const* data = TRY(find_calendar_data(locale, calendar)); data != nullptr) {
auto const& symbols_list = s_calendar_symbol_lists[data->symbols];
auto symbol_index = to_underlying(symbol);
@ -2243,62 +2243,62 @@ static Span<@string_index_type@ const> find_calendar_symbols(StringView locale,
return s_symbol_lists.at(symbol_list_index);
}
return {};
return Span<@string_index_type@ const> {};
}
Optional<StringView> get_calendar_era_symbol(StringView locale, StringView calendar, CalendarPatternStyle style, Era value)
ErrorOr<Optional<StringView>> get_calendar_era_symbol(StringView locale, StringView calendar, CalendarPatternStyle style, Era value)
{
auto symbols = find_calendar_symbols(locale, calendar, CalendarSymbol::Era, style);
auto symbols = TRY(find_calendar_symbols(locale, calendar, CalendarSymbol::Era, style));
if (auto value_index = to_underlying(value); value_index < symbols.size()) {
if (auto symbol_index = symbols.at(value_index); symbol_index != 0)
return decode_string(symbol_index);
return Optional<StringView> { decode_string(symbol_index) };
}
return {};
return OptionalNone {};
}
Optional<StringView> get_calendar_month_symbol(StringView locale, StringView calendar, CalendarPatternStyle style, Month value)
ErrorOr<Optional<StringView>> get_calendar_month_symbol(StringView locale, StringView calendar, CalendarPatternStyle style, Month value)
{
auto symbols = find_calendar_symbols(locale, calendar, CalendarSymbol::Month, style);
auto symbols = TRY(find_calendar_symbols(locale, calendar, CalendarSymbol::Month, style));
if (auto value_index = to_underlying(value); value_index < symbols.size()) {
if (auto symbol_index = symbols.at(value_index); symbol_index != 0)
return decode_string(symbol_index);
return Optional<StringView> { decode_string(symbol_index) };
}
return {};
return OptionalNone {};
}
Optional<StringView> get_calendar_weekday_symbol(StringView locale, StringView calendar, CalendarPatternStyle style, Weekday value)
ErrorOr<Optional<StringView>> get_calendar_weekday_symbol(StringView locale, StringView calendar, CalendarPatternStyle style, Weekday value)
{
auto symbols = find_calendar_symbols(locale, calendar, CalendarSymbol::Weekday, style);
auto symbols = TRY(find_calendar_symbols(locale, calendar, CalendarSymbol::Weekday, style));
if (auto value_index = to_underlying(value); value_index < symbols.size()) {
if (auto symbol_index = symbols.at(value_index); symbol_index != 0)
return decode_string(symbol_index);
return Optional<StringView> { decode_string(symbol_index) };
}
return {};
return OptionalNone {};
}
Optional<StringView> get_calendar_day_period_symbol(StringView locale, StringView calendar, CalendarPatternStyle style, DayPeriod value)
ErrorOr<Optional<StringView>> get_calendar_day_period_symbol(StringView locale, StringView calendar, CalendarPatternStyle style, DayPeriod value)
{
auto symbols = find_calendar_symbols(locale, calendar, CalendarSymbol::DayPeriod, style);
auto symbols = TRY(find_calendar_symbols(locale, calendar, CalendarSymbol::DayPeriod, style));
if (auto value_index = to_underlying(value); value_index < symbols.size()) {
if (auto symbol_index = symbols.at(value_index); symbol_index != 0)
return decode_string(symbol_index);
return Optional<StringView> { decode_string(symbol_index) };
}
return {};
return OptionalNone {};
}
Optional<StringView> get_calendar_day_period_symbol_for_hour(StringView locale, StringView calendar, CalendarPatternStyle style, u8 hour)
ErrorOr<Optional<StringView>> get_calendar_day_period_symbol_for_hour(StringView locale, StringView calendar, CalendarPatternStyle style, u8 hour)
{
auto locale_value = locale_from_string(locale);
if (!locale_value.has_value())
return {};
return OptionalNone {};
auto locale_index = to_underlying(*locale_value) - 1; // Subtract 1 because 0 == Locale::None.

View file

@ -1554,45 +1554,45 @@ static Span<@string_index_type@ const> find_keyword_indices(StringView locale, S
return s_keyword_lists.at(keywords_index);
}
Optional<StringView> get_preferred_keyword_value_for_locale(StringView locale, StringView key)
ErrorOr<Optional<StringView>> get_preferred_keyword_value_for_locale(StringView locale, StringView key)
{
// Hour cycle keywords are region-based rather than locale-based, so they need to be handled specially.
// FIXME: Calendar keywords are also region-based, and will need to be handled here when we support non-Gregorian calendars:
// https://github.com/unicode-org/cldr-json/blob/main/cldr-json/cldr-core/supplemental/calendarPreferenceData.json
if (key == "hc"sv) {
auto hour_cycles = get_locale_hour_cycles(locale);
auto hour_cycles = TRY(get_locale_hour_cycles(locale));
if (hour_cycles.is_empty())
return {};
return OptionalNone {};
return hour_cycle_to_string(hour_cycles[0]);
return Optional<StringView> { hour_cycle_to_string(hour_cycles[0]) };
}
// FIXME: Generate locale-preferred collation data when available in the CLDR.
if (key == "co"sv) {
auto collations = get_available_collation_types();
if (collations.is_empty())
return {};
return OptionalNone {};
return collations[0];
return Optional<StringView> { collations[0] };
}
auto keyword_indices = find_keyword_indices(locale, key);
if (keyword_indices.is_empty())
return {};
return OptionalNone {};
return decode_string(keyword_indices[0]);
return Optional<StringView> { decode_string(keyword_indices[0]) };
}
Vector<StringView> get_keywords_for_locale(StringView locale, StringView key)
ErrorOr<Vector<StringView>> get_keywords_for_locale(StringView locale, StringView key)
{
// Hour cycle keywords are region-based rather than locale-based, so they need to be handled specially.
// FIXME: Calendar keywords are also region-based, and will need to be handled here when we support non-Gregorian calendars:
// https://github.com/unicode-org/cldr-json/blob/main/cldr-json/cldr-core/supplemental/calendarPreferenceData.json
if (key == "hc"sv) {
auto hour_cycles = get_locale_hour_cycles(locale);
auto hour_cycles = TRY(get_locale_hour_cycles(locale));
Vector<StringView> values;
values.ensure_capacity(hour_cycles.size());
TRY(values.try_ensure_capacity(hour_cycles.size()));
for (auto hour_cycle : hour_cycles)
values.unchecked_append(hour_cycle_to_string(hour_cycle));
@ -1607,7 +1607,7 @@ Vector<StringView> get_keywords_for_locale(StringView locale, StringView key)
auto keyword_indices = find_keyword_indices(locale, key);
Vector<StringView> keywords;
keywords.ensure_capacity(keyword_indices.size());
TRY(keywords.try_ensure_capacity(keyword_indices.size()));
for (auto keyword : keyword_indices)
keywords.unchecked_append(decode_string(keyword));

View file

@ -929,7 +929,7 @@ Optional<Span<u32 const>> get_digits_for_number_system(StringView system)
return s_number_systems_digits[number_system_index];
}
static NumberSystemData const* find_number_system(StringView locale, StringView system)
static ErrorOr<NumberSystemData const*> find_number_system(StringView locale, StringView system)
{
auto locale_value = locale_from_string(locale);
if (!locale_value.has_value())
@ -959,44 +959,44 @@ static NumberSystemData const* find_number_system(StringView locale, StringView
if (auto const* number_system = lookup_number_system(system))
return number_system;
auto default_number_system = get_preferred_keyword_value_for_locale(locale, "nu"sv);
auto default_number_system = TRY(get_preferred_keyword_value_for_locale(locale, "nu"sv));
if (!default_number_system.has_value())
return nullptr;
return lookup_number_system(*default_number_system);
}
Optional<StringView> get_number_system_symbol(StringView locale, StringView system, NumericSymbol symbol)
ErrorOr<Optional<StringView>> get_number_system_symbol(StringView locale, StringView system, NumericSymbol symbol)
{
if (auto const* number_system = find_number_system(locale, system); number_system != nullptr) {
if (auto const* number_system = TRY(find_number_system(locale, system)); number_system != nullptr) {
auto symbols = s_numeric_symbol_lists.at(number_system->symbols);
auto symbol_index = to_underlying(symbol);
if (symbol_index >= symbols.size())
return {};
return OptionalNone {};
return decode_string(symbols[symbol_index]);
return Optional<StringView> { decode_string(symbols[symbol_index]) };
}
return {};
return OptionalNone {};
}
Optional<NumberGroupings> get_number_system_groupings(StringView locale, StringView system)
ErrorOr<Optional<NumberGroupings>> get_number_system_groupings(StringView locale, StringView system)
{
auto locale_value = locale_from_string(locale);
if (!locale_value.has_value())
return {};
return OptionalNone {};
u8 minimum_grouping_digits = s_minimum_grouping_digits[to_underlying(*locale_value) - 1];
if (auto const* number_system = find_number_system(locale, system); number_system != nullptr)
if (auto const* number_system = TRY(find_number_system(locale, system)); number_system != nullptr)
return NumberGroupings { minimum_grouping_digits, number_system->primary_grouping_size, number_system->secondary_grouping_size };
return {};
return OptionalNone {};
}
Optional<NumberFormat> get_standard_number_system_format(StringView locale, StringView system, StandardNumberFormatType type)
ErrorOr<Optional<NumberFormat>> get_standard_number_system_format(StringView locale, StringView system, StandardNumberFormatType type)
{
if (auto const* number_system = find_number_system(locale, system); number_system != nullptr) {
if (auto const* number_system = TRY(find_number_system(locale, system)); number_system != nullptr) {
@number_format_index_type@ format_index = 0;
switch (type) {
@ -1020,14 +1020,14 @@ Optional<NumberFormat> get_standard_number_system_format(StringView locale, Stri
return s_number_formats[format_index].to_unicode_number_format();
}
return {};
return OptionalNone {};
}
Vector<NumberFormat> get_compact_number_system_formats(StringView locale, StringView system, CompactNumberFormatType type)
ErrorOr<Vector<NumberFormat>> get_compact_number_system_formats(StringView locale, StringView system, CompactNumberFormatType type)
{
Vector<NumberFormat> formats;
if (auto const* number_system = find_number_system(locale, system); number_system != nullptr) {
if (auto const* number_system = TRY(find_number_system(locale, system)); number_system != nullptr) {
@number_format_list_index_type@ number_format_list_index { 0 };
switch (type) {

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

View file

@ -94,8 +94,8 @@ StringView calendar_pattern_style_to_string(CalendarPatternStyle style)
Optional<HourCycleRegion> __attribute__((weak)) hour_cycle_region_from_string(StringView) { return {}; }
Vector<HourCycle> __attribute__((weak)) get_regional_hour_cycles(StringView) { return {}; }
template<typename GetRegionalValues>
static auto find_regional_values_for_locale(StringView locale, GetRegionalValues&& get_regional_values)
template<typename T, typename GetRegionalValues>
static ErrorOr<T> find_regional_values_for_locale(StringView locale, GetRegionalValues&& get_regional_values)
{
auto has_value = [](auto const& container) {
if constexpr (requires { container.has_value(); })
@ -109,12 +109,12 @@ static auto find_regional_values_for_locale(StringView locale, GetRegionalValues
auto return_default_values = [&]() { return get_regional_values("001"sv); };
auto language = parse_unicode_language_id(locale).release_value_but_fixme_should_propagate_errors();
auto language = TRY(parse_unicode_language_id(locale));
if (!language.has_value())
return return_default_values();
if (!language->region.has_value())
language = add_likely_subtags(*language).release_value_but_fixme_should_propagate_errors();
language = TRY(add_likely_subtags(*language));
if (!language.has_value() || !language->region.has_value())
return return_default_values();
@ -125,48 +125,48 @@ static auto find_regional_values_for_locale(StringView locale, GetRegionalValues
}
// https://unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
Vector<HourCycle> get_locale_hour_cycles(StringView locale)
ErrorOr<Vector<HourCycle>> get_locale_hour_cycles(StringView locale)
{
return find_regional_values_for_locale(locale, get_regional_hour_cycles);
return find_regional_values_for_locale<Vector<HourCycle>>(locale, get_regional_hour_cycles);
}
Optional<HourCycle> get_default_regional_hour_cycle(StringView locale)
ErrorOr<Optional<HourCycle>> get_default_regional_hour_cycle(StringView locale)
{
if (auto hour_cycles = get_locale_hour_cycles(locale); !hour_cycles.is_empty())
if (auto hour_cycles = TRY(get_locale_hour_cycles(locale)); !hour_cycles.is_empty())
return hour_cycles.first();
return {};
return OptionalNone {};
}
Optional<MinimumDaysRegion> __attribute__((weak)) minimum_days_region_from_string(StringView) { return {}; }
Optional<u8> __attribute__((weak)) get_regional_minimum_days(StringView) { return {}; }
Optional<u8> get_locale_minimum_days(StringView locale)
ErrorOr<Optional<u8>> get_locale_minimum_days(StringView locale)
{
return find_regional_values_for_locale(locale, get_regional_minimum_days);
return find_regional_values_for_locale<Optional<u8>>(locale, get_regional_minimum_days);
}
Optional<FirstDayRegion> __attribute__((weak)) first_day_region_from_string(StringView) { return {}; }
Optional<Weekday> __attribute__((weak)) get_regional_first_day(StringView) { return {}; }
Optional<Weekday> get_locale_first_day(StringView locale)
ErrorOr<Optional<Weekday>> get_locale_first_day(StringView locale)
{
return find_regional_values_for_locale(locale, get_regional_first_day);
return find_regional_values_for_locale<Optional<Weekday>>(locale, get_regional_first_day);
}
Optional<WeekendStartRegion> __attribute__((weak)) weekend_start_region_from_string(StringView) { return {}; }
Optional<Weekday> __attribute__((weak)) get_regional_weekend_start(StringView) { return {}; }
Optional<Weekday> get_locale_weekend_start(StringView locale)
ErrorOr<Optional<Weekday>> get_locale_weekend_start(StringView locale)
{
return find_regional_values_for_locale(locale, get_regional_weekend_start);
return find_regional_values_for_locale<Optional<Weekday>>(locale, get_regional_weekend_start);
}
Optional<WeekendEndRegion> __attribute__((weak)) weekend_end_region_from_string(StringView) { return {}; }
Optional<Weekday> __attribute__((weak)) get_regional_weekend_end(StringView) { return {}; }
Optional<Weekday> get_locale_weekend_end(StringView locale)
ErrorOr<Optional<Weekday>> get_locale_weekend_end(StringView locale)
{
return find_regional_values_for_locale(locale, get_regional_weekend_end);
return find_regional_values_for_locale<Optional<Weekday>>(locale, get_regional_weekend_end);
}
ErrorOr<String> combine_skeletons(StringView first, StringView second)
@ -232,11 +232,11 @@ ErrorOr<Vector<CalendarPattern>> __attribute__((weak)) get_calendar_available_fo
ErrorOr<Optional<CalendarRangePattern>> __attribute__((weak)) get_calendar_default_range_format(StringView, StringView) { return OptionalNone {}; }
ErrorOr<Vector<CalendarRangePattern>> __attribute__((weak)) get_calendar_range_formats(StringView, StringView, StringView) { return Vector<CalendarRangePattern> {}; }
ErrorOr<Vector<CalendarRangePattern>> __attribute__((weak)) get_calendar_range12_formats(StringView, StringView, StringView) { return Vector<CalendarRangePattern> {}; }
Optional<StringView> __attribute__((weak)) get_calendar_era_symbol(StringView, StringView, CalendarPatternStyle, Era) { return {}; }
Optional<StringView> __attribute__((weak)) get_calendar_month_symbol(StringView, StringView, CalendarPatternStyle, Month) { return {}; }
Optional<StringView> __attribute__((weak)) get_calendar_weekday_symbol(StringView, StringView, CalendarPatternStyle, Weekday) { return {}; }
Optional<StringView> __attribute__((weak)) get_calendar_day_period_symbol(StringView, StringView, CalendarPatternStyle, DayPeriod) { return {}; }
Optional<StringView> __attribute__((weak)) get_calendar_day_period_symbol_for_hour(StringView, StringView, CalendarPatternStyle, u8) { return {}; }
ErrorOr<Optional<StringView>> __attribute__((weak)) get_calendar_era_symbol(StringView, StringView, CalendarPatternStyle, Era) { return OptionalNone {}; }
ErrorOr<Optional<StringView>> __attribute__((weak)) get_calendar_month_symbol(StringView, StringView, CalendarPatternStyle, Month) { return OptionalNone {}; }
ErrorOr<Optional<StringView>> __attribute__((weak)) get_calendar_weekday_symbol(StringView, StringView, CalendarPatternStyle, Weekday) { return OptionalNone {}; }
ErrorOr<Optional<StringView>> __attribute__((weak)) get_calendar_day_period_symbol(StringView, StringView, CalendarPatternStyle, DayPeriod) { return OptionalNone {}; }
ErrorOr<Optional<StringView>> __attribute__((weak)) get_calendar_day_period_symbol_for_hour(StringView, StringView, CalendarPatternStyle, u8) { return OptionalNone {}; }
Optional<StringView> __attribute__((weak)) get_time_zone_name(StringView, StringView, CalendarPatternStyle, TimeZone::InDST) { return {}; }
Optional<TimeZoneFormat> __attribute__((weak)) get_time_zone_format(StringView) { return {}; }
@ -247,7 +247,7 @@ static ErrorOr<Optional<String>> format_time_zone_offset(StringView locale, Cale
if (!formats.has_value())
return OptionalNone {};
auto number_system = get_preferred_keyword_value_for_locale(locale, "nu"sv);
auto number_system = TRY(get_preferred_keyword_value_for_locale(locale, "nu"sv));
if (!number_system.has_value())
return OptionalNone {};

View file

@ -190,24 +190,24 @@ StringView calendar_pattern_style_to_string(CalendarPatternStyle style);
Optional<HourCycleRegion> hour_cycle_region_from_string(StringView hour_cycle_region);
Vector<HourCycle> get_regional_hour_cycles(StringView region);
Vector<HourCycle> get_locale_hour_cycles(StringView locale);
Optional<HourCycle> get_default_regional_hour_cycle(StringView locale);
ErrorOr<Vector<HourCycle>> get_locale_hour_cycles(StringView locale);
ErrorOr<Optional<HourCycle>> get_default_regional_hour_cycle(StringView locale);
Optional<MinimumDaysRegion> minimum_days_region_from_string(StringView minimum_days_region);
Optional<u8> get_regional_minimum_days(StringView region);
Optional<u8> get_locale_minimum_days(StringView region);
ErrorOr<Optional<u8>> get_locale_minimum_days(StringView locale);
Optional<FirstDayRegion> first_day_region_from_string(StringView first_day_region);
Optional<Weekday> get_regional_first_day(StringView region);
Optional<Weekday> get_locale_first_day(StringView region);
ErrorOr<Optional<Weekday>> get_locale_first_day(StringView locale);
Optional<WeekendStartRegion> weekend_start_region_from_string(StringView weekend_start_region);
Optional<Weekday> get_regional_weekend_start(StringView region);
Optional<Weekday> get_locale_weekend_start(StringView region);
ErrorOr<Optional<Weekday>> get_locale_weekend_start(StringView locale);
Optional<WeekendEndRegion> weekend_end_region_from_string(StringView weekend_end_region);
Optional<Weekday> get_regional_weekend_end(StringView region);
Optional<Weekday> get_locale_weekend_end(StringView region);
ErrorOr<Optional<Weekday>> get_locale_weekend_end(StringView locale);
ErrorOr<String> combine_skeletons(StringView first, StringView second);
@ -220,11 +220,11 @@ ErrorOr<Optional<CalendarRangePattern>> get_calendar_default_range_format(String
ErrorOr<Vector<CalendarRangePattern>> get_calendar_range_formats(StringView locale, StringView calendar, StringView skeleton);
ErrorOr<Vector<CalendarRangePattern>> get_calendar_range12_formats(StringView locale, StringView calendar, StringView skeleton);
Optional<StringView> get_calendar_era_symbol(StringView locale, StringView calendar, CalendarPatternStyle style, Era value);
Optional<StringView> get_calendar_month_symbol(StringView locale, StringView calendar, CalendarPatternStyle style, Month value);
Optional<StringView> get_calendar_weekday_symbol(StringView locale, StringView calendar, CalendarPatternStyle style, Weekday value);
Optional<StringView> get_calendar_day_period_symbol(StringView locale, StringView calendar, CalendarPatternStyle style, DayPeriod value);
Optional<StringView> get_calendar_day_period_symbol_for_hour(StringView locale, StringView calendar, CalendarPatternStyle style, u8 hour);
ErrorOr<Optional<StringView>> get_calendar_era_symbol(StringView locale, StringView calendar, CalendarPatternStyle style, Era value);
ErrorOr<Optional<StringView>> get_calendar_month_symbol(StringView locale, StringView calendar, CalendarPatternStyle style, Month value);
ErrorOr<Optional<StringView>> get_calendar_weekday_symbol(StringView locale, StringView calendar, CalendarPatternStyle style, Weekday value);
ErrorOr<Optional<StringView>> get_calendar_day_period_symbol(StringView locale, StringView calendar, CalendarPatternStyle style, DayPeriod value);
ErrorOr<Optional<StringView>> get_calendar_day_period_symbol_for_hour(StringView locale, StringView calendar, CalendarPatternStyle style, u8 hour);
ErrorOr<String> format_time_zone(StringView locale, StringView time_zone, CalendarPatternStyle style, AK::Time time);
Optional<StringView> get_time_zone_name(StringView locale, StringView time_zone, CalendarPatternStyle style, TimeZone::InDST in_dst);

View file

@ -808,8 +808,8 @@ Optional<KeywordHours> __attribute__((weak)) keyword_hc_from_string(StringView)
Optional<KeywordColCaseFirst> __attribute__((weak)) keyword_kf_from_string(StringView) { return {}; }
Optional<KeywordColNumeric> __attribute__((weak)) keyword_kn_from_string(StringView) { return {}; }
Optional<KeywordNumbers> __attribute__((weak)) keyword_nu_from_string(StringView) { return {}; }
Vector<StringView> __attribute__((weak)) get_keywords_for_locale(StringView, StringView) { return {}; }
Optional<StringView> __attribute__((weak)) get_preferred_keyword_value_for_locale(StringView, StringView) { return {}; }
ErrorOr<Vector<StringView>> __attribute__((weak)) get_keywords_for_locale(StringView, StringView) { return Vector<StringView> {}; }
ErrorOr<Optional<StringView>> __attribute__((weak)) get_preferred_keyword_value_for_locale(StringView, StringView) { return OptionalNone {}; }
Optional<DisplayPattern> __attribute__((weak)) get_locale_display_patterns(StringView) { return {}; }
Optional<StringView> __attribute__((weak)) get_locale_language_mapping(StringView, StringView) { return {}; }
Optional<StringView> __attribute__((weak)) get_locale_territory_mapping(StringView, StringView) { return {}; }

View file

@ -173,8 +173,8 @@ Optional<KeywordHours> keyword_hc_from_string(StringView hc);
Optional<KeywordColCaseFirst> keyword_kf_from_string(StringView kf);
Optional<KeywordColNumeric> keyword_kn_from_string(StringView kn);
Optional<KeywordNumbers> keyword_nu_from_string(StringView nu);
Vector<StringView> get_keywords_for_locale(StringView locale, StringView key);
Optional<StringView> get_preferred_keyword_value_for_locale(StringView locale, StringView key);
ErrorOr<Vector<StringView>> get_keywords_for_locale(StringView locale, StringView key);
ErrorOr<Optional<StringView>> get_preferred_keyword_value_for_locale(StringView locale, StringView key);
Optional<DisplayPattern> get_locale_display_patterns(StringView locale);
ErrorOr<Optional<String>> format_locale_for_display(StringView locale, LocaleID locale_id);

View file

@ -16,10 +16,10 @@
namespace Locale {
Optional<StringView> __attribute__((weak)) get_number_system_symbol(StringView, StringView, NumericSymbol) { return {}; }
Optional<NumberGroupings> __attribute__((weak)) get_number_system_groupings(StringView, StringView) { return {}; }
Optional<NumberFormat> __attribute__((weak)) get_standard_number_system_format(StringView, StringView, StandardNumberFormatType) { return {}; }
Vector<NumberFormat> __attribute__((weak)) get_compact_number_system_formats(StringView, StringView, CompactNumberFormatType) { return {}; }
ErrorOr<Optional<StringView>> __attribute__((weak)) get_number_system_symbol(StringView, StringView, NumericSymbol) { return OptionalNone {}; }
ErrorOr<Optional<NumberGroupings>> __attribute__((weak)) get_number_system_groupings(StringView, StringView) { return OptionalNone {}; }
ErrorOr<Optional<NumberFormat>> __attribute__((weak)) get_standard_number_system_format(StringView, StringView, StandardNumberFormatType) { return OptionalNone {}; }
ErrorOr<Vector<NumberFormat>> __attribute__((weak)) get_compact_number_system_formats(StringView, StringView, CompactNumberFormatType) { return Vector<NumberFormat> {}; }
Vector<NumberFormat> __attribute__((weak)) get_unit_formats(StringView, StringView, Style) { return {}; }
Optional<Span<u32 const>> __attribute__((weak)) get_digits_for_number_system(StringView)

View file

@ -61,14 +61,14 @@ enum class NumericSymbol : u8 {
TimeSeparator,
};
Optional<StringView> get_number_system_symbol(StringView locale, StringView system, NumericSymbol symbol);
Optional<NumberGroupings> get_number_system_groupings(StringView locale, StringView system);
ErrorOr<Optional<StringView>> get_number_system_symbol(StringView locale, StringView system, NumericSymbol symbol);
ErrorOr<Optional<NumberGroupings>> get_number_system_groupings(StringView locale, StringView system);
Optional<Span<u32 const>> get_digits_for_number_system(StringView system);
ErrorOr<String> replace_digits_for_number_system(StringView system, StringView number);
Optional<NumberFormat> get_standard_number_system_format(StringView locale, StringView system, StandardNumberFormatType type);
Vector<NumberFormat> get_compact_number_system_formats(StringView locale, StringView system, CompactNumberFormatType type);
ErrorOr<Optional<NumberFormat>> get_standard_number_system_format(StringView locale, StringView system, StandardNumberFormatType type);
ErrorOr<Vector<NumberFormat>> get_compact_number_system_formats(StringView locale, StringView system, CompactNumberFormatType type);
Vector<NumberFormat> get_unit_formats(StringView locale, StringView unit, Style style);
ErrorOr<Optional<String>> augment_currency_format_pattern(StringView currency_display, StringView base_pattern);