Commit 1a225459 authored by Brian Stell's avatar Brian Stell Committed by Commit Bot

Implement ResolveLocale in C++.

Bug: v8:8065, v8:5751
Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng
Change-Id: Id9dc16455d63b7c436126c21758d64fae0ec8de9
Reviewed-on: https://chromium-review.googlesource.com/1211402Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55925}
parent 24a232e2
...@@ -96,7 +96,6 @@ enum ContextLookupFlags { ...@@ -96,7 +96,6 @@ enum ContextLookupFlags {
V(REFERENCE_ERROR_FUNCTION_INDEX, JSFunction, reference_error_function) \ V(REFERENCE_ERROR_FUNCTION_INDEX, JSFunction, reference_error_function) \
V(CACHED_OR_NEW_SERVICE_LOCALE_FUNCTION_INDEX, JSFunction, \ V(CACHED_OR_NEW_SERVICE_LOCALE_FUNCTION_INDEX, JSFunction, \
cached_or_new_service) \ cached_or_new_service) \
V(RESOLVE_LOCALE_FUNCTION_INDEX, JSFunction, resolve_locale) \
V(SET_ADD_INDEX, JSFunction, set_add) \ V(SET_ADD_INDEX, JSFunction, set_add) \
V(SET_DELETE_INDEX, JSFunction, set_delete) \ V(SET_DELETE_INDEX, JSFunction, set_delete) \
V(SET_HAS_INDEX, JSFunction, set_has) \ V(SET_HAS_INDEX, JSFunction, set_has) \
......
This diff is collapsed.
This diff is collapsed.
...@@ -89,6 +89,13 @@ class Intl { ...@@ -89,6 +89,13 @@ class Intl {
static bool RemoveLocaleScriptTag(const std::string& icu_locale, static bool RemoveLocaleScriptTag(const std::string& icu_locale,
std::string* locale_less_script); std::string* locale_less_script);
struct ResolvedLocale {
std::string locale; // The bcp47 locale to use.
std::string unicode_extensions;
std::map<std::string, std::string> extensions;
std::string locale_with_extensions;
};
// The ResolveLocale abstract operation compares a BCP 47 language // The ResolveLocale abstract operation compares a BCP 47 language
// priority list requestedLocales against the locales in // priority list requestedLocales against the locales in
// availableLocales and determines the best available language to // availableLocales and determines the best available language to
...@@ -98,14 +105,15 @@ class Intl { ...@@ -98,14 +105,15 @@ class Intl {
// //
// #ecma402/sec-partitiondatetimepattern // #ecma402/sec-partitiondatetimepattern
// //
// Returns a JSObject with two properties: // Returns an object with two properties:
// (1) locale // (1) locale
// (2) extension // (2) extension
// V8_WARN_UNUSED_RESULT static Maybe<ResolvedLocale*> ResolveLocale(
// To access either, use JSObject::GetDataProperty. Isolate* isolate, const char* service,
V8_WARN_UNUSED_RESULT static MaybeHandle<JSObject> ResolveLocale( const std::set<std::string>& available_locales,
Isolate* isolate, const char* service, Handle<Object> requestedLocales, const std::vector<std::string>& requested_locales,
Handle<Object> options); const std::set<std::string>& relevant_extension_keys,
Handle<JSReceiver> options);
// This currently calls out to the JavaScript implementation of // This currently calls out to the JavaScript implementation of
// CanonicalizeLocaleList. // CanonicalizeLocaleList.
......
...@@ -28,6 +28,9 @@ MaybeHandle<JSV8BreakIterator> JSV8BreakIterator::InitializeV8BreakIterator( ...@@ -28,6 +28,9 @@ MaybeHandle<JSV8BreakIterator> JSV8BreakIterator::InitializeV8BreakIterator(
Isolate* isolate, Handle<JSV8BreakIterator> break_iterator_holder, Isolate* isolate, Handle<JSV8BreakIterator> break_iterator_holder,
Handle<Object> locales, Handle<Object> options_obj) { Handle<Object> locales, Handle<Object> options_obj) {
Factory* factory = isolate->factory(); Factory* factory = isolate->factory();
Maybe<std::vector<std::string>> requested_locales =
Intl::CanonicalizeLocaleList(isolate, locales, false);
MAYBE_RETURN(requested_locales, MaybeHandle<JSV8BreakIterator>());
Handle<JSReceiver> options; Handle<JSReceiver> options;
if (options_obj->IsUndefined(isolate)) { if (options_obj->IsUndefined(isolate)) {
...@@ -40,15 +43,18 @@ MaybeHandle<JSV8BreakIterator> JSV8BreakIterator::InitializeV8BreakIterator( ...@@ -40,15 +43,18 @@ MaybeHandle<JSV8BreakIterator> JSV8BreakIterator::InitializeV8BreakIterator(
} }
// Extract locale string // Extract locale string
Handle<JSObject> r; const std::set<std::string> relevant_extension_keys;
ASSIGN_RETURN_ON_EXCEPTION( std::set<std::string> available_locales =
isolate, r, Intl::GetAvailableLocales(IcuService::kListFormatter);
Intl::ResolveLocale(isolate, "breakiterator", locales, options), Maybe<Intl::ResolvedLocale*> maybe_resolved_locale = Intl::ResolveLocale(
JSV8BreakIterator); isolate, "breakiterator", available_locales, requested_locales.FromJust(),
Handle<Object> locale_obj = relevant_extension_keys, options);
JSObject::GetDataProperty(r, factory->locale_string()); MAYBE_RETURN(maybe_resolved_locale, MaybeHandle<JSV8BreakIterator>());
CHECK(locale_obj->IsString()); std::unique_ptr<Intl::ResolvedLocale> r(maybe_resolved_locale.FromJust());
Handle<String> locale = Handle<String>::cast(locale_obj); CHECK_NOT_NULL(r.get());
Handle<String> locale =
isolate->factory()->NewStringFromAsciiChecked(r.get()->locale.c_str());
// Extract type from options // Extract type from options
std::unique_ptr<char[]> type_str = nullptr; std::unique_ptr<char[]> type_str = nullptr;
......
...@@ -221,10 +221,9 @@ MaybeHandle<JSCollator> JSCollator::InitializeCollator( ...@@ -221,10 +221,9 @@ MaybeHandle<JSCollator> JSCollator::InitializeCollator(
Isolate* isolate, Handle<JSCollator> collator, Handle<Object> locales, Isolate* isolate, Handle<JSCollator> collator, Handle<Object> locales,
Handle<Object> options_obj) { Handle<Object> options_obj) {
// 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
Handle<JSObject> requested_locales; Maybe<std::vector<std::string>> requested_locales =
ASSIGN_RETURN_ON_EXCEPTION(isolate, requested_locales, Intl::CanonicalizeLocaleList(isolate, locales, false);
Intl::CanonicalizeLocaleListJS(isolate, locales), MAYBE_RETURN(requested_locales, MaybeHandle<JSCollator>());
JSCollator);
// 2. If options is undefined, then // 2. If options is undefined, then
if (options_obj->IsUndefined(isolate)) { if (options_obj->IsUndefined(isolate)) {
...@@ -257,10 +256,7 @@ MaybeHandle<JSCollator> JSCollator::InitializeCollator( ...@@ -257,10 +256,7 @@ MaybeHandle<JSCollator> JSCollator::InitializeCollator(
} }
} }
// TODO(gsathya): This is currently done as part of the // Steps 9 and 10 are done as part of the Intl::ResolveLocale call below.
// Intl::ResolveLocale call below. Fix this once resolveLocale is
// changed to not do the lookup.
//
// 9. Let matcher be ? GetOption(options, "localeMatcher", "string", // 9. Let matcher be ? GetOption(options, "localeMatcher", "string",
// « "lookup", "best fit" », "best fit"). // « "lookup", "best fit" », "best fit").
// 10. Set opt.[[localeMatcher]] to matcher. // 10. Set opt.[[localeMatcher]] to matcher.
...@@ -316,25 +312,20 @@ MaybeHandle<JSCollator> JSCollator::InitializeCollator( ...@@ -316,25 +312,20 @@ MaybeHandle<JSCollator> JSCollator::InitializeCollator(
// requestedLocales, opt, %Collator%.[[RelevantExtensionKeys]], // requestedLocales, opt, %Collator%.[[RelevantExtensionKeys]],
// localeData). // localeData).
// 18. Set collator.[[Locale]] to r.[[locale]]. // 18. Set collator.[[Locale]] to r.[[locale]].
Handle<JSObject> r; std::set<std::string> available_locales =
ASSIGN_RETURN_ON_EXCEPTION( Intl::GetAvailableLocales(IcuService::kCollator);
isolate, r, Maybe<Intl::ResolvedLocale*> maybe_resolved_locale = Intl::ResolveLocale(
Intl::ResolveLocale(isolate, "collator", requested_locales, options), isolate, "collator", available_locales, requested_locales.FromJust(),
JSCollator); relevant_extension_keys, options);
MAYBE_RETURN(maybe_resolved_locale, MaybeHandle<JSCollator>());
Handle<String> locale_with_extension_str = std::unique_ptr<Intl::ResolvedLocale> r(maybe_resolved_locale.FromJust());
isolate->factory()->NewStringFromStaticChars("localeWithExtension"); CHECK_NOT_NULL(r.get());
Handle<Object> locale_with_extension_obj =
JSObject::GetDataProperty(r, locale_with_extension_str); std::string locale_with_extension = r.get()->locale_with_extensions;
Handle<String> locale = isolate->factory()->NewStringFromAsciiChecked(
// The locale_with_extension has to be a string. Either a user locale_with_extension.c_str());
// provided canonicalized string or the default locale.
CHECK(locale_with_extension_obj->IsString()); icu::Locale icu_locale = Intl::CreateICULocale(isolate, locale);
Handle<String> locale_with_extension =
Handle<String>::cast(locale_with_extension_obj);
icu::Locale icu_locale =
Intl::CreateICULocale(isolate, locale_with_extension);
DCHECK(!icu_locale.isBogus()); DCHECK(!icu_locale.isBogus());
std::map<std::string, std::string> extensions = std::map<std::string, std::string> extensions =
......
...@@ -775,7 +775,12 @@ enum FormatMatcherOption { kBestFit, kBasic }; ...@@ -775,7 +775,12 @@ enum FormatMatcherOption { kBestFit, kBasic };
// ecma402/#sec-initializedatetimeformat // ecma402/#sec-initializedatetimeformat
MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize( MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize(
Isolate* isolate, Handle<JSDateTimeFormat> date_time_format, Isolate* isolate, Handle<JSDateTimeFormat> date_time_format,
Handle<Object> requested_locales, Handle<Object> input_options) { Handle<Object> locales, Handle<Object> input_options) {
// 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
Maybe<std::vector<std::string>> requested_locales =
Intl::CanonicalizeLocaleList(isolate, locales, false);
MAYBE_RETURN(requested_locales, MaybeHandle<JSDateTimeFormat>());
// 2. Let options be ? ToDateTimeOptions(options, "any", "date"). // 2. Let options be ? ToDateTimeOptions(options, "any", "date").
Handle<JSObject> options; Handle<JSObject> options;
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(
...@@ -784,29 +789,26 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize( ...@@ -784,29 +789,26 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize(
isolate, input_options, RequiredOption::kAny, DefaultsOption::kDate), isolate, input_options, RequiredOption::kAny, DefaultsOption::kDate),
JSDateTimeFormat); JSDateTimeFormat);
const std::set<std::string> relevant_extension_keys{"ca", "nu", "hc"};
// 11. Let r be ResolveLocale( %DateTimeFormat%.[[AvailableLocales]], // 11. Let r be ResolveLocale( %DateTimeFormat%.[[AvailableLocales]],
// requestedLocales, opt, %DateTimeFormat%.[[RelevantExtensionKeys]], // requestedLocales, opt, %DateTimeFormat%.[[RelevantExtensionKeys]],
// localeData). // localeData).
const char* kService = "Intl.DateTimeFormat"; const char* kService = "Intl.DateTimeFormat";
Handle<JSObject> r; std::set<std::string> available_locales =
ASSIGN_RETURN_ON_EXCEPTION( Intl::GetAvailableLocales(IcuService::kRelativeDateTimeFormatter);
isolate, r, Maybe<Intl::ResolvedLocale*> maybe_resolved_locale = Intl::ResolveLocale(
Intl::ResolveLocale(isolate, "dateformat", requested_locales, options), isolate, "datetimeformat", available_locales,
JSDateTimeFormat); requested_locales.FromJust(), relevant_extension_keys, options);
MAYBE_RETURN(maybe_resolved_locale, MaybeHandle<JSDateTimeFormat>());
Handle<String> locale_with_extension_str = std::unique_ptr<Intl::ResolvedLocale> r(maybe_resolved_locale.FromJust());
isolate->factory()->NewStringFromStaticChars("localeWithExtension"); CHECK_NOT_NULL(r.get());
Handle<Object> locale_with_extension_obj =
JSObject::GetDataProperty(r, locale_with_extension_str); std::string locale_with_extension = r.get()->locale_with_extensions;
Handle<String> locale = isolate->factory()->NewStringFromAsciiChecked(
// The locale_with_extension has to be a string. Either a user locale_with_extension.c_str());
// provided canonicalized string or the default locale.
CHECK(locale_with_extension_obj->IsString()); icu::Locale icu_locale = Intl::CreateICULocale(isolate, locale);
Handle<String> locale_with_extension =
Handle<String>::cast(locale_with_extension_obj);
icu::Locale icu_locale =
Intl::CreateICULocale(isolate, locale_with_extension);
DCHECK(!icu_locale.isBogus()); DCHECK(!icu_locale.isBogus());
// We implement only best fit algorithm, but still need to check // We implement only best fit algorithm, but still need to check
......
...@@ -122,7 +122,10 @@ JSListFormat::Type get_type(const char* str) { ...@@ -122,7 +122,10 @@ JSListFormat::Type get_type(const char* str) {
MaybeHandle<JSListFormat> JSListFormat::InitializeListFormat( MaybeHandle<JSListFormat> JSListFormat::InitializeListFormat(
Isolate* isolate, Handle<JSListFormat> list_format_holder, Isolate* isolate, Handle<JSListFormat> list_format_holder,
Handle<Object> input_locales, Handle<Object> input_options) { Handle<Object> input_locales, Handle<Object> input_options) {
Factory* factory = isolate->factory(); Maybe<std::vector<std::string>> requested_locales =
Intl::CanonicalizeLocaleList(isolate, input_locales, false);
MAYBE_RETURN(requested_locales, MaybeHandle<JSListFormat>());
list_format_holder->set_flags(0); list_format_holder->set_flags(0);
Handle<JSReceiver> options; Handle<JSReceiver> options;
...@@ -170,23 +173,23 @@ MaybeHandle<JSListFormat> JSListFormat::InitializeListFormat( ...@@ -170,23 +173,23 @@ MaybeHandle<JSListFormat> JSListFormat::InitializeListFormat(
// 10. Let r be ResolveLocale(%ListFormat%.[[AvailableLocales]], // 10. Let r be ResolveLocale(%ListFormat%.[[AvailableLocales]],
// requestedLocales, opt, undefined, localeData). // requestedLocales, opt, undefined, localeData).
Handle<JSObject> r; const std::set<std::string> relevant_extension_keys;
ASSIGN_RETURN_ON_EXCEPTION( std::set<std::string> available_locales =
isolate, r, Intl::GetAvailableLocales(IcuService::kListFormatter);
Intl::ResolveLocale(isolate, "listformat", input_locales, options), Maybe<Intl::ResolvedLocale*> maybe_resolved_locale = Intl::ResolveLocale(
JSListFormat); isolate, "listformatter", available_locales, requested_locales.FromJust(),
relevant_extension_keys, options);
Handle<Object> locale_obj = MAYBE_RETURN(maybe_resolved_locale, MaybeHandle<JSListFormat>());
JSObject::GetDataProperty(r, factory->locale_string()); std::unique_ptr<Intl::ResolvedLocale> r(maybe_resolved_locale.FromJust());
Handle<String> locale; CHECK_NOT_NULL(r.get());
ASSIGN_RETURN_ON_EXCEPTION(
isolate, locale, Object::ToString(isolate, locale_obj), JSListFormat); Handle<String> locale =
isolate->factory()->NewStringFromAsciiChecked(r.get()->locale.c_str());
// 18. Set listFormat.[[Locale]] to the value of r.[[Locale]]. // 18. Set listFormat.[[Locale]] to the value of r.[[Locale]].
list_format_holder->set_locale(*locale); list_format_holder->set_locale(*locale);
std::unique_ptr<char[]> locale_name = locale->ToCString(); icu::Locale icu_locale(r.get()->locale.c_str());
icu::Locale icu_locale(locale_name.get());
UErrorCode status = U_ZERO_ERROR; UErrorCode status = U_ZERO_ERROR;
icu::ListFormatter* formatter = icu::ListFormatter::createInstance( icu::ListFormatter* formatter = icu::ListFormatter::createInstance(
icu_locale, GetIcuStyleString(style_enum, type_enum), status); icu_locale, GetIcuStyleString(style_enum, type_enum), status);
......
...@@ -189,10 +189,9 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize( ...@@ -189,10 +189,9 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize(
number_format->set_flags(0); number_format->set_flags(0);
Factory* factory = isolate->factory(); Factory* factory = isolate->factory();
// 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
Handle<JSObject> requested_locales; Maybe<std::vector<std::string>> requested_locales =
ASSIGN_RETURN_ON_EXCEPTION(isolate, requested_locales, Intl::CanonicalizeLocaleList(isolate, locales, false);
Intl::CanonicalizeLocaleListJS(isolate, locales), MAYBE_RETURN(requested_locales, MaybeHandle<JSNumberFormat>());
JSNumberFormat);
// 2. If options is undefined, then // 2. If options is undefined, then
if (options_obj->IsUndefined(isolate)) { if (options_obj->IsUndefined(isolate)) {
...@@ -212,6 +211,8 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize( ...@@ -212,6 +211,8 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize(
// 4. Let opt be a new Record. // 4. Let opt be a new Record.
// //
// Steps 5 and 6 are currently done as part of the
// Intl::ResolveLocale call below.
// 5. Let matcher be ? GetOption(options, "localeMatcher", "string", « // 5. Let matcher be ? GetOption(options, "localeMatcher", "string", «
// "lookup", "best fit" », "best fit"). // "lookup", "best fit" », "best fit").
// //
...@@ -225,29 +226,26 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize( ...@@ -225,29 +226,26 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize(
// //
// 9. Set numberFormat.[[Locale]] to r.[[locale]]. // 9. Set numberFormat.[[Locale]] to r.[[locale]].
Handle<JSObject> r; std::set<std::string> available_locales =
ASSIGN_RETURN_ON_EXCEPTION( Intl::GetAvailableLocales(IcuService::kNumberFormat);
isolate, r, // 13.3.3 Internal slots
Intl::ResolveLocale(isolate, "numberformat", requested_locales, options), // https://tc39.github.io/ecma402/#sec-intl.numberformat-internal-slots
JSNumberFormat); const std::set<std::string> relevant_extension_keys{"nu"};
Maybe<Intl::ResolvedLocale*> maybe_resolved_locale = Intl::ResolveLocale(
Handle<String> locale_with_extension_str = isolate, "numberformat", available_locales, requested_locales.FromJust(),
isolate->factory()->NewStringFromStaticChars("localeWithExtension"); relevant_extension_keys, options);
Handle<Object> locale_with_extension_obj = MAYBE_RETURN(maybe_resolved_locale, MaybeHandle<JSNumberFormat>());
JSObject::GetDataProperty(r, locale_with_extension_str); std::unique_ptr<Intl::ResolvedLocale> r(maybe_resolved_locale.FromJust());
CHECK_NOT_NULL(r.get());
// The locale_with_extension has to be a string. Either a user
// provided canonicalized string or the default locale. std::string locale_with_extension = r.get()->locale_with_extensions;
CHECK(locale_with_extension_obj->IsString()); Handle<String> locale = isolate->factory()->NewStringFromAsciiChecked(
Handle<String> locale_with_extension = locale_with_extension.c_str());
Handle<String>::cast(locale_with_extension_obj);
icu::Locale icu_locale = Intl::CreateICULocale(isolate, locale);
icu::Locale icu_locale = number_format->set_locale(*locale);
Intl::CreateICULocale(isolate, locale_with_extension);
number_format->set_locale(*locale_with_extension);
DCHECK(!icu_locale.isBogus()); DCHECK(!icu_locale.isBogus());
std::set<std::string> relevant_extension_keys{"nu"};
std::map<std::string, std::string> extensions = std::map<std::string, std::string> extensions =
Intl::LookupUnicodeExtensions(icu_locale, relevant_extension_keys); Intl::LookupUnicodeExtensions(icu_locale, relevant_extension_keys);
......
...@@ -89,12 +89,9 @@ MaybeHandle<JSPluralRules> JSPluralRules::InitializePluralRules( ...@@ -89,12 +89,9 @@ MaybeHandle<JSPluralRules> JSPluralRules::InitializePluralRules(
Isolate* isolate, Handle<JSPluralRules> plural_rules, Isolate* isolate, Handle<JSPluralRules> plural_rules,
Handle<Object> locales, Handle<Object> options_obj) { Handle<Object> locales, Handle<Object> options_obj) {
// 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
// TODO(jkummerow): Port ResolveLocale, then use the C++ version of Maybe<std::vector<std::string>> requested_locales =
// CanonicalizeLocaleList here. Intl::CanonicalizeLocaleList(isolate, locales, false);
Handle<JSObject> requested_locales; MAYBE_RETURN(requested_locales, MaybeHandle<JSPluralRules>());
ASSIGN_RETURN_ON_EXCEPTION(isolate, requested_locales,
Intl::CanonicalizeLocaleListJS(isolate, locales),
JSPluralRules);
// 2. If options is undefined, then // 2. If options is undefined, then
if (options_obj->IsUndefined(isolate)) { if (options_obj->IsUndefined(isolate)) {
...@@ -112,10 +109,8 @@ MaybeHandle<JSPluralRules> JSPluralRules::InitializePluralRules( ...@@ -112,10 +109,8 @@ MaybeHandle<JSPluralRules> JSPluralRules::InitializePluralRules(
// At this point, options_obj can either be a JSObject or a JSProxy only. // At this point, options_obj can either be a JSObject or a JSProxy only.
Handle<JSReceiver> options = Handle<JSReceiver>::cast(options_obj); Handle<JSReceiver> options = Handle<JSReceiver>::cast(options_obj);
// TODO(gsathya): This is currently done as part of the // Steps 5 and 6 are currently done as part of the
// Intl::ResolveLocale call below. Fix this once resolveLocale is // Intl::ResolveLocale call below.
// changed to not do the lookup.
//
// 5. Let matcher be ? GetOption(options, "localeMatcher", "string", // 5. Let matcher be ? GetOption(options, "localeMatcher", "string",
// « "lookup", "best fit" », "best fit"). // « "lookup", "best fit" », "best fit").
// 6. Set opt.[[localeMatcher]] to matcher. // 6. Set opt.[[localeMatcher]] to matcher.
...@@ -146,19 +141,21 @@ MaybeHandle<JSPluralRules> JSPluralRules::InitializePluralRules( ...@@ -146,19 +141,21 @@ MaybeHandle<JSPluralRules> JSPluralRules::InitializePluralRules(
// 11. Let r be ResolveLocale(%PluralRules%.[[AvailableLocales]], // 11. Let r be ResolveLocale(%PluralRules%.[[AvailableLocales]],
// requestedLocales, opt, %PluralRules%.[[RelevantExtensionKeys]], // requestedLocales, opt, %PluralRules%.[[RelevantExtensionKeys]],
// localeData). // localeData).
Handle<JSObject> r; std::set<std::string> available_locales =
ASSIGN_RETURN_ON_EXCEPTION( Intl::GetAvailableLocales(IcuService::kPluralRules);
isolate, r, // 13.3.3 Internal slots
Intl::ResolveLocale(isolate, "pluralrules", requested_locales, options), // https://tc39.github.io/ecma402/#sec-intl.pluralrules-internal-slots
JSPluralRules); // The value of the [[RelevantExtensionKeys]] internal slot is [].
const std::set<std::string> relevant_extension_keys;
Handle<String> locale_str = isolate->factory()->locale_string(); Maybe<Intl::ResolvedLocale*> maybe_resolved_locale = Intl::ResolveLocale(
Handle<Object> locale_obj = JSObject::GetDataProperty(r, locale_str); isolate, "pluralrules", available_locales, requested_locales.FromJust(),
relevant_extension_keys, options);
// The locale has to be a string. Either a user provided MAYBE_RETURN(maybe_resolved_locale, MaybeHandle<JSPluralRules>());
// canonicalized string or the default locale. std::unique_ptr<Intl::ResolvedLocale> r(maybe_resolved_locale.FromJust());
CHECK(locale_obj->IsString()); CHECK_NOT_NULL(r.get());
Handle<String> locale = Handle<String>::cast(locale_obj);
Handle<String> locale =
isolate->factory()->NewStringFromAsciiChecked(r.get()->locale.c_str());
// 12. Set pluralRules.[[Locale]] to the value of r.[[locale]]. // 12. Set pluralRules.[[Locale]] to the value of r.[[locale]].
plural_rules->set_locale(*locale); plural_rules->set_locale(*locale);
......
...@@ -59,7 +59,10 @@ MaybeHandle<JSRelativeTimeFormat> ...@@ -59,7 +59,10 @@ MaybeHandle<JSRelativeTimeFormat>
JSRelativeTimeFormat::InitializeRelativeTimeFormat( JSRelativeTimeFormat::InitializeRelativeTimeFormat(
Isolate* isolate, Handle<JSRelativeTimeFormat> relative_time_format_holder, Isolate* isolate, Handle<JSRelativeTimeFormat> relative_time_format_holder,
Handle<Object> input_locales, Handle<Object> input_options) { Handle<Object> input_locales, Handle<Object> input_options) {
Factory* factory = isolate->factory(); Maybe<std::vector<std::string>> requested_locales =
Intl::CanonicalizeLocaleList(isolate, input_locales, false);
MAYBE_RETURN(requested_locales, MaybeHandle<JSRelativeTimeFormat>());
relative_time_format_holder->set_flags(0); relative_time_format_holder->set_flags(0);
// 4. If options is undefined, then // 4. If options is undefined, then
Handle<JSReceiver> options; Handle<JSReceiver> options;
...@@ -78,17 +81,20 @@ JSRelativeTimeFormat::InitializeRelativeTimeFormat( ...@@ -78,17 +81,20 @@ JSRelativeTimeFormat::InitializeRelativeTimeFormat(
// requestedLocales, opt, // requestedLocales, opt,
// %RelativeTimeFormat%.[[RelevantExtensionKeys]], // %RelativeTimeFormat%.[[RelevantExtensionKeys]],
// localeData). // localeData).
Handle<JSObject> r; std::set<std::string> available_locales =
ASSIGN_RETURN_ON_EXCEPTION(isolate, r, Intl::GetAvailableLocales(IcuService::kRelativeDateTimeFormatter);
Intl::ResolveLocale(isolate, "relativetimeformat", // 13.3.3 Internal slots
input_locales, options), // The value of the [[RelevantExtensionKeys]] internal slot is [].
JSRelativeTimeFormat); const std::set<std::string> relevant_extension_keys;
Handle<Object> locale_obj = Maybe<Intl::ResolvedLocale*> maybe_resolved_locale = Intl::ResolveLocale(
JSObject::GetDataProperty(r, factory->locale_string()); isolate, "relativetimeformat", available_locales,
Handle<String> locale; requested_locales.FromJust(), relevant_extension_keys, options);
ASSIGN_RETURN_ON_EXCEPTION(isolate, locale, MAYBE_RETURN(maybe_resolved_locale, MaybeHandle<JSRelativeTimeFormat>());
Object::ToString(isolate, locale_obj), std::unique_ptr<Intl::ResolvedLocale> r(maybe_resolved_locale.FromJust());
JSRelativeTimeFormat); CHECK_NOT_NULL(r.get());
Handle<String> locale =
isolate->factory()->NewStringFromAsciiChecked(r.get()->locale.c_str());
// 11. Let locale be r.[[Locale]]. // 11. Let locale be r.[[Locale]].
// 12. Set relativeTimeFormat.[[Locale]] to locale. // 12. Set relativeTimeFormat.[[Locale]] to locale.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment