LibJS: Convert FilterLocales and CoerceOptionsToObject to GC::Ref

These never return nullptr.
This commit is contained in:
Timothy Flynn 2025-04-07 17:46:22 -04:00
parent f032ec5e67
commit f8a63a4657
4 changed files with 25 additions and 25 deletions

View file

@ -612,9 +612,9 @@ ThrowCompletionOr<ResolvedOptions> resolve_options(VM& vm, IntlObject& object, V
// 3. If specialBehaviours is present and contains COERCE-OPTIONS, set options to ? CoerceOptionsToObject(options).
// Otherwise, set options to ? GetOptionsObject(options).
GC::Ref<Object> options = has_flag(special_behaviours, SpecialBehaviors::CoerceOptions)
? *TRY(coerce_options_to_object(vm, options_value))
: *TRY(get_options_object(vm, options_value));
auto options = has_flag(special_behaviours, SpecialBehaviors::CoerceOptions)
? TRY(coerce_options_to_object(vm, options_value))
: TRY(get_options_object(vm, options_value));
// 4. Let matcher be ? GetOption(options, "localeMatcher", STRING, « "lookup", "best fit" », "best fit").
auto matcher = TRY(get_option(vm, options, vm.names.localeMatcher, OptionType::String, { "lookup"sv, "best fit"sv }, "best fit"sv));
@ -669,15 +669,15 @@ ThrowCompletionOr<ResolvedOptions> resolve_options(VM& vm, IntlObject& object, V
}
// 9.2.9 FilterLocales ( availableLocales, requestedLocales, options ), https://tc39.es/ecma402/#sec-lookupsupportedlocales
ThrowCompletionOr<Array*> filter_locales(VM& vm, ReadonlySpan<String> requested_locales, Value options)
ThrowCompletionOr<GC::Ref<Array>> filter_locales(VM& vm, ReadonlySpan<String> requested_locales, Value options_value)
{
auto& realm = *vm.current_realm();
// 1. Set options to ? CoerceOptionsToObject(options).
auto* options_object = TRY(coerce_options_to_object(vm, options));
auto options = TRY(coerce_options_to_object(vm, options_value));
// 2. Let matcher be ? GetOption(options, "localeMatcher", string, « "lookup", "best fit" », "best fit").
auto matcher = TRY(get_option(vm, *options_object, vm.names.localeMatcher, OptionType::String, { "lookup"sv, "best fit"sv }, "best fit"sv));
auto matcher = TRY(get_option(vm, options, vm.names.localeMatcher, OptionType::String, { "lookup"sv, "best fit"sv }, "best fit"sv));
// 3. Let subset be a new empty List.
Vector<String> subset;
@ -703,22 +703,22 @@ ThrowCompletionOr<Array*> filter_locales(VM& vm, ReadonlySpan<String> requested_
}
// 5. Return CreateArrayFromList(subset).
return Array::create_from<String>(realm, subset, [&vm](auto& locale) { return PrimitiveString::create(vm, move(locale)); }).ptr();
return Array::create_from<String>(realm, subset, [&vm](auto& locale) { return PrimitiveString::create(vm, move(locale)); });
}
// 9.2.11 CoerceOptionsToObject ( options ), https://tc39.es/ecma402/#sec-coerceoptionstoobject
ThrowCompletionOr<Object*> coerce_options_to_object(VM& vm, Value options)
ThrowCompletionOr<GC::Ref<Object>> coerce_options_to_object(VM& vm, Value options)
{
auto& realm = *vm.current_realm();
// 1. If options is undefined, then
if (options.is_undefined()) {
// a. Return OrdinaryObjectCreate(null).
return Object::create(realm, nullptr).ptr();
return Object::create(realm, nullptr);
}
// 2. Return ? ToObject(options).
return TRY(options.to_object(vm)).ptr();
return TRY(options.to_object(vm));
}
// NOTE: 9.2.12 GetOption has been removed and is being pulled in from ECMA-262 in the Temporal proposal.

View file

@ -75,8 +75,8 @@ Optional<MatchedLocale> lookup_matching_locale_by_best_fit(ReadonlySpan<String>
String insert_unicode_extension_and_canonicalize(Unicode::LocaleID locale_id, Vector<String> attributes, Vector<Unicode::Keyword> keywords);
ResolvedLocale resolve_locale(ReadonlySpan<String> requested_locales, LocaleOptions const& options, ReadonlySpan<StringView> relevant_extension_keys);
ThrowCompletionOr<ResolvedOptions> resolve_options(VM& vm, IntlObject& object, Value locales, Value options_value, SpecialBehaviors special_behaviours = SpecialBehaviors::None, Function<void(LocaleOptions&)> modify_resolution_options = {});
ThrowCompletionOr<Array*> filter_locales(VM& vm, ReadonlySpan<String> requested_locales, Value options);
ThrowCompletionOr<Object*> coerce_options_to_object(VM&, Value options);
ThrowCompletionOr<GC::Ref<Array>> filter_locales(VM& vm, ReadonlySpan<String> requested_locales, Value options);
ThrowCompletionOr<GC::Ref<Object>> coerce_options_to_object(VM&, Value options);
ThrowCompletionOr<StringOrBoolean> get_boolean_or_string_number_format_option(VM& vm, Object const& options, PropertyKey const& property, ReadonlySpan<StringView> string_values, StringOrBoolean fallback);
ThrowCompletionOr<Optional<int>> default_number_option(VM&, Value value, int minimum, int maximum, Optional<int> fallback);
ThrowCompletionOr<Optional<int>> get_number_option(VM&, Object const& options, PropertyKey const& property, int minimum, int maximum, Optional<int> fallback);

View file

@ -63,10 +63,10 @@ ThrowCompletionOr<GC::Ref<Object>> CollatorConstructor::construct(FunctionObject
auto requested_locales = TRY(canonicalize_locale_list(vm, locales_value));
// 6. Set options to ? CoerceOptionsToObject(options).
auto* options = TRY(coerce_options_to_object(vm, options_value));
auto options = TRY(coerce_options_to_object(vm, options_value));
// 7. Let usage be ? GetOption(options, "usage", string, « "sort", "search" », "sort").
auto usage = TRY(get_option(vm, *options, vm.names.usage, OptionType::String, { "sort"sv, "search"sv }, "sort"sv));
auto usage = TRY(get_option(vm, options, vm.names.usage, OptionType::String, { "sort"sv, "search"sv }, "sort"sv));
// 8. Set collator.[[Usage]] to usage.
collator->set_usage(usage.as_string().utf8_string_view());
@ -109,7 +109,7 @@ ThrowCompletionOr<GC::Ref<Object>> CollatorConstructor::construct(FunctionObject
auto default_sensitivity = collator->usage() == Unicode::Usage::Sort ? "variant"sv : OptionDefault {};
// 20. Set collator.[[Sensitivity]] to ? GetOption(options, "sensitivity", string, « "base", "accent", "case", "variant" », defaultSensitivity).
auto sensitivity_value = TRY(get_option(vm, *options, vm.names.sensitivity, OptionType::String, { "base"sv, "accent"sv, "case"sv, "variant"sv }, default_sensitivity));
auto sensitivity_value = TRY(get_option(vm, options, vm.names.sensitivity, OptionType::String, { "base"sv, "accent"sv, "case"sv, "variant"sv }, default_sensitivity));
Optional<Unicode::Sensitivity> sensitivity;
if (!sensitivity_value.is_undefined())
@ -120,7 +120,7 @@ ThrowCompletionOr<GC::Ref<Object>> CollatorConstructor::construct(FunctionObject
// default value if an override was not provided here.
// 22. Set collator.[[IgnorePunctuation]] to ? GetOption(options, "ignorePunctuation", boolean, empty, defaultIgnorePunctuation).
auto ignore_punctuation_value = TRY(get_option(vm, *options, vm.names.ignorePunctuation, OptionType::Boolean, {}, Empty {}));
auto ignore_punctuation_value = TRY(get_option(vm, options, vm.names.ignorePunctuation, OptionType::Boolean, {}, Empty {}));
Optional<bool> ignore_punctuation;
if (!ignore_punctuation_value.is_undefined())

View file

@ -282,10 +282,10 @@ ThrowCompletionOr<GC::Ref<Object>> LocaleConstructor::construct(FunctionObject&
}
// 10. Set options to ? CoerceOptionsToObject(options).
auto* options = TRY(coerce_options_to_object(vm, options_value));
auto options = TRY(coerce_options_to_object(vm, options_value));
// 11. Set tag to ? ApplyOptionsToTag(tag, options).
tag = TRY(apply_options_to_tag(vm, tag, *options));
tag = TRY(apply_options_to_tag(vm, tag, options));
// 12. Let opt be a new Record.
LocaleAndKeys opt {};
@ -294,16 +294,16 @@ ThrowCompletionOr<GC::Ref<Object>> LocaleConstructor::construct(FunctionObject&
// 14. If calendar is not undefined, then
// a. If calendar does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
// 15. Set opt.[[ca]] to calendar.
opt.ca = TRY(get_string_option(vm, *options, vm.names.calendar, Unicode::is_type_identifier));
opt.ca = TRY(get_string_option(vm, options, vm.names.calendar, Unicode::is_type_identifier));
// 16. Let collation be ? GetOption(options, "collation", string, empty, undefined).
// 17. If collation is not undefined, then
// a. If collation does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
// 18. Set opt.[[co]] to collation.
opt.co = TRY(get_string_option(vm, *options, vm.names.collation, Unicode::is_type_identifier));
opt.co = TRY(get_string_option(vm, options, vm.names.collation, Unicode::is_type_identifier));
// 19. Let fw be ? Let fw be ? GetOption(options, "firstDayOfWeek", "string", undefined, undefined).
auto first_day_of_week = TRY(get_string_option(vm, *options, vm.names.firstDayOfWeek, nullptr));
auto first_day_of_week = TRY(get_string_option(vm, options, vm.names.firstDayOfWeek, nullptr));
// 20. If fw is not undefined, then
if (first_day_of_week.has_value()) {
@ -320,14 +320,14 @@ ThrowCompletionOr<GC::Ref<Object>> LocaleConstructor::construct(FunctionObject&
// 22. Let hc be ? GetOption(options, "hourCycle", string, « "h11", "h12", "h23", "h24" », undefined).
// 23. Set opt.[[hc]] to hc.
opt.hc = TRY(get_string_option(vm, *options, vm.names.hourCycle, nullptr, AK::Array { "h11"sv, "h12"sv, "h23"sv, "h24"sv }));
opt.hc = TRY(get_string_option(vm, options, vm.names.hourCycle, nullptr, AK::Array { "h11"sv, "h12"sv, "h23"sv, "h24"sv }));
// 24. Let kf be ? GetOption(options, "caseFirst", string, « "upper", "lower", "false" », undefined).
// 25. Set opt.[[kf]] to kf.
opt.kf = TRY(get_string_option(vm, *options, vm.names.caseFirst, nullptr, AK::Array { "upper"sv, "lower"sv, "false"sv }));
opt.kf = TRY(get_string_option(vm, options, vm.names.caseFirst, nullptr, AK::Array { "upper"sv, "lower"sv, "false"sv }));
// 26. Let kn be ? GetOption(options, "numeric", boolean, empty, undefined).
auto kn = TRY(get_option(vm, *options, vm.names.numeric, OptionType::Boolean, {}, Empty {}));
auto kn = TRY(get_option(vm, options, vm.names.numeric, OptionType::Boolean, {}, Empty {}));
// 27. If kn is not undefined, set kn to ! ToString(kn).
// 28. Set opt.[[kn]] to kn.
@ -338,7 +338,7 @@ ThrowCompletionOr<GC::Ref<Object>> LocaleConstructor::construct(FunctionObject&
// 30. If numberingSystem is not undefined, then
// a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
// 31. Set opt.[[nu]] to numberingSystem.
opt.nu = TRY(get_string_option(vm, *options, vm.names.numberingSystem, Unicode::is_type_identifier));
opt.nu = TRY(get_string_option(vm, options, vm.names.numberingSystem, Unicode::is_type_identifier));
// 32. Let r be ! ApplyUnicodeExtensionToTag(tag, opt, localeExtensionKeys).
auto result = apply_unicode_extension_to_tag(tag, move(opt), locale_extension_keys);