Commit 50d7cbf6 authored by Frank Tang's avatar Frank Tang Committed by Commit Bot

[Intl] Decentralize GetAvailableLocales

Remove ICUService and decentralize GetAvailableLocales to each class.
Refactor part of the Intl::GetAvailableLocales into Intl::BuildLocaleSet
as helper function.

Bug: v8:5751
Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng
Change-Id: Ic82d919cbf7ec840a7df3b0fa040561534c105a1
Reviewed-on: https://chromium-review.googlesource.com/c/1295934
Commit-Queue: Frank Tang <ftang@chromium.org>
Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56923}
parent e99349a9
...@@ -57,9 +57,9 @@ BUILTIN(V8BreakIteratorSupportedLocalesOf) { ...@@ -57,9 +57,9 @@ BUILTIN(V8BreakIteratorSupportedLocalesOf) {
Handle<Object> options = args.atOrUndefined(isolate, 2); Handle<Object> options = args.atOrUndefined(isolate, 2);
RETURN_RESULT_OR_FAILURE( RETURN_RESULT_OR_FAILURE(
isolate, isolate, Intl::SupportedLocalesOf(
Intl::SupportedLocalesOf(isolate, Intl::ICUService::kBreakIterator, isolate, "Intl.v8BreakIterator.supportedLocalesOf",
locales, options)); JSV8BreakIterator::GetAvailableLocales(), locales, options));
} }
BUILTIN(NumberFormatSupportedLocalesOf) { BUILTIN(NumberFormatSupportedLocalesOf) {
...@@ -69,7 +69,8 @@ BUILTIN(NumberFormatSupportedLocalesOf) { ...@@ -69,7 +69,8 @@ BUILTIN(NumberFormatSupportedLocalesOf) {
RETURN_RESULT_OR_FAILURE( RETURN_RESULT_OR_FAILURE(
isolate, Intl::SupportedLocalesOf( isolate, Intl::SupportedLocalesOf(
isolate, Intl::ICUService::kNumberFormat, locales, options)); isolate, "Intl.NumberFormat.supportedLocalesOf",
JSNumberFormat::GetAvailableLocales(), locales, options));
} }
BUILTIN(NumberFormatPrototypeFormatToParts) { BUILTIN(NumberFormatPrototypeFormatToParts) {
...@@ -110,8 +111,9 @@ BUILTIN(DateTimeFormatSupportedLocalesOf) { ...@@ -110,8 +111,9 @@ BUILTIN(DateTimeFormatSupportedLocalesOf) {
Handle<Object> options = args.atOrUndefined(isolate, 2); Handle<Object> options = args.atOrUndefined(isolate, 2);
RETURN_RESULT_OR_FAILURE( RETURN_RESULT_OR_FAILURE(
isolate, Intl::SupportedLocalesOf(isolate, Intl::ICUService::kDateFormat, isolate, Intl::SupportedLocalesOf(
locales, options)); isolate, "Intl.DateTimeFormat.supportedLocalesOf",
JSDateTimeFormat::GetAvailableLocales(), locales, options));
} }
BUILTIN(DateTimeFormatPrototypeFormatToParts) { BUILTIN(DateTimeFormatPrototypeFormatToParts) {
...@@ -461,9 +463,9 @@ BUILTIN(ListFormatSupportedLocalesOf) { ...@@ -461,9 +463,9 @@ BUILTIN(ListFormatSupportedLocalesOf) {
Handle<Object> options = args.atOrUndefined(isolate, 2); Handle<Object> options = args.atOrUndefined(isolate, 2);
RETURN_RESULT_OR_FAILURE( RETURN_RESULT_OR_FAILURE(
isolate, isolate, Intl::SupportedLocalesOf(
Intl::SupportedLocalesOf(isolate, Intl::ICUService::kListFormatter, isolate, "Intl.ListFormat.supportedLocalesOf",
locales, options)); JSListFormat::GetAvailableLocales(), locales, options));
} }
namespace { namespace {
...@@ -569,9 +571,10 @@ BUILTIN(RelativeTimeFormatSupportedLocalesOf) { ...@@ -569,9 +571,10 @@ BUILTIN(RelativeTimeFormatSupportedLocalesOf) {
Handle<Object> options = args.atOrUndefined(isolate, 2); Handle<Object> options = args.atOrUndefined(isolate, 2);
RETURN_RESULT_OR_FAILURE( RETURN_RESULT_OR_FAILURE(
isolate, Intl::SupportedLocalesOf( isolate,
isolate, Intl::ICUService::kRelativeDateTimeFormatter, Intl::SupportedLocalesOf(
locales, options)); isolate, "Intl.RelativeTimeFormat.supportedLocalesOf",
JSRelativeTimeFormat::GetAvailableLocales(), locales, options));
} }
BUILTIN(RelativeTimeFormatPrototypeFormat) { BUILTIN(RelativeTimeFormatPrototypeFormat) {
...@@ -834,8 +837,9 @@ BUILTIN(PluralRulesSupportedLocalesOf) { ...@@ -834,8 +837,9 @@ BUILTIN(PluralRulesSupportedLocalesOf) {
Handle<Object> options = args.atOrUndefined(isolate, 2); Handle<Object> options = args.atOrUndefined(isolate, 2);
RETURN_RESULT_OR_FAILURE( RETURN_RESULT_OR_FAILURE(
isolate, Intl::SupportedLocalesOf(isolate, Intl::ICUService::kPluralRules, isolate, Intl::SupportedLocalesOf(
locales, options)); isolate, "Intl.PluralRules.supportedLocalesOf",
JSPluralRules::GetAvailableLocales(), locales, options));
} }
BUILTIN(CollatorConstructor) { BUILTIN(CollatorConstructor) {
...@@ -884,8 +888,9 @@ BUILTIN(CollatorSupportedLocalesOf) { ...@@ -884,8 +888,9 @@ BUILTIN(CollatorSupportedLocalesOf) {
Handle<Object> options = args.atOrUndefined(isolate, 2); Handle<Object> options = args.atOrUndefined(isolate, 2);
RETURN_RESULT_OR_FAILURE( RETURN_RESULT_OR_FAILURE(
isolate, Intl::SupportedLocalesOf(isolate, Intl::ICUService::kCollator, isolate, Intl::SupportedLocalesOf(
locales, options)); isolate, "Intl.Collator.supportedLocalesOf",
JSCollator::GetAvailableLocales(), locales, options));
} }
BUILTIN(CollatorPrototypeCompare) { BUILTIN(CollatorPrototypeCompare) {
...@@ -1040,8 +1045,9 @@ BUILTIN(SegmenterSupportedLocalesOf) { ...@@ -1040,8 +1045,9 @@ BUILTIN(SegmenterSupportedLocalesOf) {
Handle<Object> options = args.atOrUndefined(isolate, 2); Handle<Object> options = args.atOrUndefined(isolate, 2);
RETURN_RESULT_OR_FAILURE( RETURN_RESULT_OR_FAILURE(
isolate, Intl::SupportedLocalesOf(isolate, Intl::ICUService::kSegmenter, isolate, Intl::SupportedLocalesOf(
locales, options)); isolate, "Intl.Segmenter.supportedLocalesOf",
JSSegmenter::GetAvailableLocales(), locales, options));
} }
BUILTIN(SegmenterPrototypeResolvedOptions) { BUILTIN(SegmenterPrototypeResolvedOptions) {
......
...@@ -511,44 +511,9 @@ bool RemoveLocaleScriptTag(const std::string& icu_locale, ...@@ -511,44 +511,9 @@ bool RemoveLocaleScriptTag(const std::string& icu_locale,
} // namespace } // namespace
std::set<std::string> Intl::GetAvailableLocales(Intl::ICUService service) { std::set<std::string> Intl::BuildLocaleSet(
const icu::Locale* icu_available_locales = nullptr; const icu::Locale* icu_available_locales, int32_t count) {
int32_t count = 0;
std::set<std::string> locales; std::set<std::string> locales;
switch (service) {
case Intl::ICUService::kBreakIterator:
case Intl::ICUService::kSegmenter:
icu_available_locales = icu::BreakIterator::getAvailableLocales(count);
break;
case Intl::ICUService::kCollator:
icu_available_locales = icu::Collator::getAvailableLocales(count);
break;
case Intl::ICUService::kRelativeDateTimeFormatter:
case Intl::ICUService::kDateFormat:
icu_available_locales = icu::DateFormat::getAvailableLocales(count);
break;
case Intl::ICUService::kNumberFormat:
icu_available_locales = icu::NumberFormat::getAvailableLocales(count);
break;
case Intl::ICUService::kPluralRules:
// TODO(littledan): For PluralRules, filter out locales that
// don't support PluralRules.
// PluralRules is missing an appropriate getAvailableLocales method,
// so we should filter from all locales, but it's not clear how; see
// https://ssl.icu-project.org/trac/ticket/12756
icu_available_locales = icu::Locale::getAvailableLocales(count);
break;
case Intl::ICUService::kListFormatter: {
// TODO(ftang): for now just use
// icu::Locale::getAvailableLocales(count) until we migrate to
// Intl::GetAvailableLocales().
// ICU FR at https://unicode-org.atlassian.net/browse/ICU-20015
icu_available_locales = icu::Locale::getAvailableLocales(count);
break;
}
}
UErrorCode error = U_ZERO_ERROR; UErrorCode error = U_ZERO_ERROR;
char result[ULOC_FULLNAME_CAPACITY]; char result[ULOC_FULLNAME_CAPACITY];
...@@ -575,32 +540,6 @@ std::set<std::string> Intl::GetAvailableLocales(Intl::ICUService service) { ...@@ -575,32 +540,6 @@ std::set<std::string> Intl::GetAvailableLocales(Intl::ICUService service) {
return locales; return locales;
} }
namespace {
const char* ICUServiceToString(Intl::ICUService service) {
switch (service) {
case Intl::ICUService::kCollator:
return "Intl.Collator";
case Intl::ICUService::kNumberFormat:
return "Intl.NumberFormat";
case Intl::ICUService::kDateFormat:
return "Intl.DateFormat";
case Intl::ICUService::kBreakIterator:
return "Intl.v8BreakIterator";
case Intl::ICUService::kPluralRules:
return "Intl.PluralRules";
case Intl::ICUService::kRelativeDateTimeFormatter:
return "Intl.RelativeTimeFormat";
case Intl::ICUService::kListFormatter:
return "Intl.kListFormat";
case Intl::ICUService::kSegmenter:
return "Intl.kSegmenter";
}
UNREACHABLE();
}
} // namespace
std::string Intl::DefaultLocale(Isolate* isolate) { std::string Intl::DefaultLocale(Isolate* isolate) {
if (isolate->default_locale().empty()) { if (isolate->default_locale().empty()) {
icu::Locale default_locale; icu::Locale default_locale;
...@@ -1620,7 +1559,7 @@ MaybeHandle<JSObject> CreateReadOnlyArray(Isolate* isolate, ...@@ -1620,7 +1559,7 @@ MaybeHandle<JSObject> CreateReadOnlyArray(Isolate* isolate,
// ECMA 402 9.2.9 SupportedLocales(availableLocales, requestedLocales, options) // ECMA 402 9.2.9 SupportedLocales(availableLocales, requestedLocales, options)
// https://tc39.github.io/ecma402/#sec-supportedlocales // https://tc39.github.io/ecma402/#sec-supportedlocales
MaybeHandle<JSObject> SupportedLocales( MaybeHandle<JSObject> SupportedLocales(
Isolate* isolate, Intl::ICUService service, Isolate* isolate, const char* method,
const std::set<std::string>& available_locales, const std::set<std::string>& available_locales,
const std::vector<std::string>& requested_locales, Handle<Object> options) { const std::vector<std::string>& requested_locales, Handle<Object> options) {
std::vector<std::string> supported_locales; std::vector<std::string> supported_locales;
...@@ -1637,8 +1576,8 @@ MaybeHandle<JSObject> SupportedLocales( ...@@ -1637,8 +1576,8 @@ MaybeHandle<JSObject> SupportedLocales(
// 1. b. Let matcher be ? GetOption(options, "localeMatcher", "string", // 1. b. Let matcher be ? GetOption(options, "localeMatcher", "string",
// « "lookup", "best fit" », "best fit"). // « "lookup", "best fit" », "best fit").
Maybe<Intl::MatcherOption> maybe_locale_matcher = Intl::GetLocaleMatcher( Maybe<Intl::MatcherOption> maybe_locale_matcher =
isolate, options_obj, ICUServiceToString(service)); Intl::GetLocaleMatcher(isolate, options_obj, method);
MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSObject>()); MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSObject>());
matcher = maybe_locale_matcher.FromJust(); matcher = maybe_locale_matcher.FromJust();
} }
...@@ -1690,12 +1629,11 @@ MaybeHandle<JSArray> Intl::GetCanonicalLocales(Isolate* isolate, ...@@ -1690,12 +1629,11 @@ MaybeHandle<JSArray> Intl::GetCanonicalLocales(Isolate* isolate,
} }
// ECMA 402 Intl.*.supportedLocalesOf // ECMA 402 Intl.*.supportedLocalesOf
MaybeHandle<JSObject> Intl::SupportedLocalesOf(Isolate* isolate, MaybeHandle<JSObject> Intl::SupportedLocalesOf(
Intl::ICUService service, Isolate* isolate, const char* method,
Handle<Object> locales, const std::set<std::string>& available_locales, Handle<Object> locales,
Handle<Object> options) { Handle<Object> options) {
// Let availableLocales be %Collator%.[[AvailableLocales]]. // Let availableLocales be %Collator%.[[AvailableLocales]].
std::set<std::string> available_locales = GetAvailableLocales(service);
// Let requestedLocales be ? CanonicalizeLocaleList(locales). // Let requestedLocales be ? CanonicalizeLocaleList(locales).
Maybe<std::vector<std::string>> requested_locales = Maybe<std::vector<std::string>> requested_locales =
...@@ -1703,7 +1641,7 @@ MaybeHandle<JSObject> Intl::SupportedLocalesOf(Isolate* isolate, ...@@ -1703,7 +1641,7 @@ MaybeHandle<JSObject> Intl::SupportedLocalesOf(Isolate* isolate,
MAYBE_RETURN(requested_locales, MaybeHandle<JSObject>()); MAYBE_RETURN(requested_locales, MaybeHandle<JSObject>());
// Return ? SupportedLocales(availableLocales, requestedLocales, options). // Return ? SupportedLocales(availableLocales, requestedLocales, options).
return SupportedLocales(isolate, service, available_locales, return SupportedLocales(isolate, method, available_locales,
requested_locales.FromJust(), options); requested_locales.FromJust(), options);
} }
......
...@@ -41,22 +41,12 @@ class Intl { ...@@ -41,22 +41,12 @@ class Intl {
kLength kLength
}; };
enum class ICUService { // Build a set of ICU locales from a list of Locales. If there is a locale
kBreakIterator, // with a script tag then the locales also include a locale without the
kCollator, // script; eg, pa_Guru_IN (language=Panjabi, script=Gurmukhi, country-India)
kDateFormat, // would include pa_IN.
kNumberFormat, static std::set<std::string> BuildLocaleSet(
kPluralRules, const icu::Locale* icu_available_locales, int32_t count);
kRelativeDateTimeFormatter,
kListFormatter,
kSegmenter
};
// Gets the ICU locales for a given service. If there is a locale with a
// script tag then the locales also include a locale without the script; eg,
// pa_Guru_IN (language=Panjabi, script=Gurmukhi, country-India) would include
// pa_IN.
static std::set<std::string> GetAvailableLocales(ICUService service);
// Get the name of the numbering system from locale. // Get the name of the numbering system from locale.
// ICU doesn't expose numbering system in any way, so we have to assume that // ICU doesn't expose numbering system in any way, so we have to assume that
...@@ -65,7 +55,8 @@ class Intl { ...@@ -65,7 +55,8 @@ class Intl {
static std::string GetNumberingSystem(const icu::Locale& icu_locale); static std::string GetNumberingSystem(const icu::Locale& icu_locale);
static V8_WARN_UNUSED_RESULT MaybeHandle<JSObject> SupportedLocalesOf( static V8_WARN_UNUSED_RESULT MaybeHandle<JSObject> SupportedLocalesOf(
Isolate* isolate, ICUService service, Handle<Object> locales_in, Isolate* isolate, const char* method,
const std::set<std::string>& available_locales, Handle<Object> locales_in,
Handle<Object> options_in); Handle<Object> options_in);
static std::string DefaultLocale(Isolate* isolate); static std::string DefaultLocale(Isolate* isolate);
......
...@@ -51,10 +51,9 @@ MaybeHandle<JSV8BreakIterator> JSV8BreakIterator::Initialize( ...@@ -51,10 +51,9 @@ MaybeHandle<JSV8BreakIterator> JSV8BreakIterator::Initialize(
MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSV8BreakIterator>()); MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSV8BreakIterator>());
Intl::MatcherOption matcher = maybe_locale_matcher.FromJust(); Intl::MatcherOption matcher = maybe_locale_matcher.FromJust();
std::set<std::string> available_locales = Intl::ResolvedLocale r =
Intl::GetAvailableLocales(Intl::ICUService::kBreakIterator); Intl::ResolveLocale(isolate, JSV8BreakIterator::GetAvailableLocales(),
Intl::ResolvedLocale r = Intl::ResolveLocale(isolate, available_locales, requested_locales, matcher, {});
requested_locales, matcher, {});
// Extract type from options // Extract type from options
std::unique_ptr<char[]> type_str = nullptr; std::unique_ptr<char[]> type_str = nullptr;
...@@ -200,5 +199,12 @@ String* JSV8BreakIterator::BreakType(Isolate* isolate, ...@@ -200,5 +199,12 @@ String* JSV8BreakIterator::BreakType(Isolate* isolate,
return ReadOnlyRoots(isolate).unknown_string(); return ReadOnlyRoots(isolate).unknown_string();
} }
std::set<std::string> JSV8BreakIterator::GetAvailableLocales() {
int32_t num_locales = 0;
const icu::Locale* icu_available_locales =
icu::BreakIterator::getAvailableLocales(num_locales);
return Intl::BuildLocaleSet(icu_available_locales, num_locales);
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -9,6 +9,9 @@ ...@@ -9,6 +9,9 @@
#ifndef V8_OBJECTS_JS_BREAK_ITERATOR_H_ #ifndef V8_OBJECTS_JS_BREAK_ITERATOR_H_
#define V8_OBJECTS_JS_BREAK_ITERATOR_H_ #define V8_OBJECTS_JS_BREAK_ITERATOR_H_
#include <set>
#include <string>
#include "src/objects.h" #include "src/objects.h"
#include "src/objects/intl-objects.h" #include "src/objects/intl-objects.h"
#include "src/objects/managed.h" #include "src/objects/managed.h"
...@@ -32,6 +35,8 @@ class JSV8BreakIterator : public JSObject { ...@@ -32,6 +35,8 @@ class JSV8BreakIterator : public JSObject {
static Handle<JSObject> ResolvedOptions( static Handle<JSObject> ResolvedOptions(
Isolate* isolate, Handle<JSV8BreakIterator> break_iterator); Isolate* isolate, Handle<JSV8BreakIterator> break_iterator);
static std::set<std::string> GetAvailableLocales();
static void AdoptText(Isolate* isolate, static void AdoptText(Isolate* isolate,
Handle<JSV8BreakIterator> break_iterator, Handle<JSV8BreakIterator> break_iterator,
Handle<String> text); Handle<String> text);
......
...@@ -300,11 +300,9 @@ MaybeHandle<JSCollator> JSCollator::Initialize(Isolate* isolate, ...@@ -300,11 +300,9 @@ MaybeHandle<JSCollator> JSCollator::Initialize(Isolate* isolate,
// 17. Let r be ResolveLocale(%Collator%.[[AvailableLocales]], // 17. Let r be ResolveLocale(%Collator%.[[AvailableLocales]],
// requestedLocales, opt, %Collator%.[[RelevantExtensionKeys]], // requestedLocales, opt, %Collator%.[[RelevantExtensionKeys]],
// localeData). // localeData).
std::set<std::string> available_locales =
Intl::GetAvailableLocales(Intl::ICUService::kCollator);
Intl::ResolvedLocale r = Intl::ResolvedLocale r =
Intl::ResolveLocale(isolate, available_locales, requested_locales, Intl::ResolveLocale(isolate, JSCollator::GetAvailableLocales(),
matcher, relevant_extension_keys); requested_locales, matcher, relevant_extension_keys);
// 18. Set collator.[[Locale]] to r.[[locale]]. // 18. Set collator.[[Locale]] to r.[[locale]].
icu::Locale icu_locale = r.icu_locale; icu::Locale icu_locale = r.icu_locale;
...@@ -494,5 +492,12 @@ MaybeHandle<JSCollator> JSCollator::Initialize(Isolate* isolate, ...@@ -494,5 +492,12 @@ MaybeHandle<JSCollator> JSCollator::Initialize(Isolate* isolate,
return collator; return collator;
} }
std::set<std::string> JSCollator::GetAvailableLocales() {
int32_t num_locales = 0;
const icu::Locale* icu_available_locales =
icu::Collator::getAvailableLocales(num_locales);
return Intl::BuildLocaleSet(icu_available_locales, num_locales);
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -9,6 +9,9 @@ ...@@ -9,6 +9,9 @@
#ifndef V8_OBJECTS_JS_COLLATOR_H_ #ifndef V8_OBJECTS_JS_COLLATOR_H_
#define V8_OBJECTS_JS_COLLATOR_H_ #define V8_OBJECTS_JS_COLLATOR_H_
#include <set>
#include <string>
#include "src/heap/factory.h" #include "src/heap/factory.h"
#include "src/isolate.h" #include "src/isolate.h"
#include "src/objects.h" #include "src/objects.h"
...@@ -36,6 +39,8 @@ class JSCollator : public JSObject { ...@@ -36,6 +39,8 @@ class JSCollator : public JSObject {
static Handle<JSObject> ResolvedOptions(Isolate* isolate, static Handle<JSObject> ResolvedOptions(Isolate* isolate,
Handle<JSCollator> collator); Handle<JSCollator> collator);
static std::set<std::string> GetAvailableLocales();
DECL_CAST(JSCollator) DECL_CAST(JSCollator)
DECL_PRINTER(JSCollator) DECL_PRINTER(JSCollator)
DECL_VERIFIER(JSCollator) DECL_VERIFIER(JSCollator)
......
...@@ -775,10 +775,9 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize( ...@@ -775,10 +775,9 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize(
// 11. Let r be ResolveLocale( %DateTimeFormat%.[[AvailableLocales]], // 11. Let r be ResolveLocale( %DateTimeFormat%.[[AvailableLocales]],
// requestedLocales, opt, %DateTimeFormat%.[[RelevantExtensionKeys]], // requestedLocales, opt, %DateTimeFormat%.[[RelevantExtensionKeys]],
// localeData). // localeData).
std::set<std::string> available_locales = Intl::ResolvedLocale r =
Intl::GetAvailableLocales(Intl::ICUService::kDateFormat); Intl::ResolveLocale(isolate, JSDateTimeFormat::GetAvailableLocales(),
Intl::ResolvedLocale r = Intl::ResolveLocale( requested_locales, locale_matcher, {"nu"});
isolate, available_locales, requested_locales, locale_matcher, {"nu"});
// TODO(ftang): Make sure that "nu" key doesn't have "native", // TODO(ftang): Make sure that "nu" key doesn't have "native",
// "traditio" or "finance" values. // "traditio" or "finance" values.
...@@ -977,5 +976,13 @@ MaybeHandle<Object> JSDateTimeFormat::FormatToParts( ...@@ -977,5 +976,13 @@ MaybeHandle<Object> JSDateTimeFormat::FormatToParts(
JSObject::ValidateElements(*result); JSObject::ValidateElements(*result);
return result; return result;
} }
std::set<std::string> JSDateTimeFormat::GetAvailableLocales() {
int32_t num_locales = 0;
const icu::Locale* icu_available_locales =
icu::DateFormat::getAvailableLocales(num_locales);
return Intl::BuildLocaleSet(icu_available_locales, num_locales);
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -9,6 +9,9 @@ ...@@ -9,6 +9,9 @@
#ifndef V8_OBJECTS_JS_DATE_TIME_FORMAT_H_ #ifndef V8_OBJECTS_JS_DATE_TIME_FORMAT_H_
#define V8_OBJECTS_JS_DATE_TIME_FORMAT_H_ #define V8_OBJECTS_JS_DATE_TIME_FORMAT_H_
#include <set>
#include <string>
#include "src/isolate.h" #include "src/isolate.h"
#include "src/objects/managed.h" #include "src/objects/managed.h"
...@@ -67,6 +70,8 @@ class JSDateTimeFormat : public JSObject { ...@@ -67,6 +70,8 @@ class JSDateTimeFormat : public JSObject {
Handle<Object> options, RequiredOption required, DefaultsOption defaults, Handle<Object> options, RequiredOption required, DefaultsOption defaults,
const char* service); const char* service);
static std::set<std::string> GetAvailableLocales();
DECL_CAST(JSDateTimeFormat) DECL_CAST(JSDateTimeFormat)
// Layout description. // Layout description.
......
...@@ -193,10 +193,9 @@ MaybeHandle<JSListFormat> JSListFormat::Initialize( ...@@ -193,10 +193,9 @@ MaybeHandle<JSListFormat> JSListFormat::Initialize(
// 15. Let r be ResolveLocale(%ListFormat%.[[AvailableLocales]], // 15. Let r be ResolveLocale(%ListFormat%.[[AvailableLocales]],
// requestedLocales, opt, undefined, localeData). // requestedLocales, opt, undefined, localeData).
std::set<std::string> available_locales = Intl::ResolvedLocale r =
Intl::GetAvailableLocales(Intl::ICUService::kListFormatter); Intl::ResolveLocale(isolate, JSListFormat::GetAvailableLocales(),
Intl::ResolvedLocale r = Intl::ResolveLocale(isolate, available_locales, requested_locales, matcher, {});
requested_locales, matcher, {});
// 24. Set listFormat.[[Locale]] to r.[[Locale]]. // 24. Set listFormat.[[Locale]] to r.[[Locale]].
Handle<String> locale_str = Handle<String> locale_str =
...@@ -402,5 +401,16 @@ MaybeHandle<JSArray> JSListFormat::FormatListToParts( ...@@ -402,5 +401,16 @@ MaybeHandle<JSArray> JSListFormat::FormatListToParts(
return GenerateListFormatParts(isolate, formatted, array.get(), length); return GenerateListFormatParts(isolate, formatted, array.get(), length);
} }
std::set<std::string> JSListFormat::GetAvailableLocales() {
int32_t num_locales = 0;
// TODO(ftang): for now just use
// icu::Locale::getAvailableLocales(count) until we migrate to
// Intl::GetAvailableLocales().
// ICU FR at https://unicode-org.atlassian.net/browse/ICU-20015
const icu::Locale* icu_available_locales =
icu::Locale::getAvailableLocales(num_locales);
return Intl::BuildLocaleSet(icu_available_locales, num_locales);
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -9,6 +9,9 @@ ...@@ -9,6 +9,9 @@
#ifndef V8_OBJECTS_JS_LIST_FORMAT_H_ #ifndef V8_OBJECTS_JS_LIST_FORMAT_H_
#define V8_OBJECTS_JS_LIST_FORMAT_H_ #define V8_OBJECTS_JS_LIST_FORMAT_H_
#include <set>
#include <string>
#include "src/heap/factory.h" #include "src/heap/factory.h"
#include "src/isolate.h" #include "src/isolate.h"
#include "src/objects.h" #include "src/objects.h"
...@@ -46,6 +49,8 @@ class JSListFormat : public JSObject { ...@@ -46,6 +49,8 @@ class JSListFormat : public JSObject {
Isolate* isolate, Handle<JSListFormat> format_holder, Isolate* isolate, Handle<JSListFormat> format_holder,
Handle<JSArray> list); Handle<JSArray> list);
static std::set<std::string> GetAvailableLocales();
Handle<String> StyleAsString() const; Handle<String> StyleAsString() const;
Handle<String> TypeAsString() const; Handle<String> TypeAsString() const;
......
...@@ -225,12 +225,10 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize( ...@@ -225,12 +225,10 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize(
// 8. Let r be ResolveLocale(%NumberFormat%.[[AvailableLocales]], // 8. Let r be ResolveLocale(%NumberFormat%.[[AvailableLocales]],
// requestedLocales, opt, %NumberFormat%.[[RelevantExtensionKeys]], // requestedLocales, opt, %NumberFormat%.[[RelevantExtensionKeys]],
// localeData). // localeData).
std::set<std::string> available_locales =
Intl::GetAvailableLocales(Intl::ICUService::kNumberFormat);
std::set<std::string> relevant_extension_keys{"nu"}; std::set<std::string> relevant_extension_keys{"nu"};
Intl::ResolvedLocale r = Intl::ResolvedLocale r =
Intl::ResolveLocale(isolate, available_locales, requested_locales, Intl::ResolveLocale(isolate, JSNumberFormat::GetAvailableLocales(),
matcher, relevant_extension_keys); requested_locales, matcher, relevant_extension_keys);
// 9. Set numberFormat.[[Locale]] to r.[[locale]]. // 9. Set numberFormat.[[Locale]] to r.[[locale]].
Handle<String> locale_str = Handle<String> locale_str =
...@@ -696,5 +694,12 @@ MaybeHandle<JSArray> JSNumberFormat::FormatToParts( ...@@ -696,5 +694,12 @@ MaybeHandle<JSArray> JSNumberFormat::FormatToParts(
return result; return result;
} }
std::set<std::string> JSNumberFormat::GetAvailableLocales() {
int32_t num_locales = 0;
const icu::Locale* icu_available_locales =
icu::NumberFormat::getAvailableLocales(num_locales);
return Intl::BuildLocaleSet(icu_available_locales, num_locales);
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -9,6 +9,9 @@ ...@@ -9,6 +9,9 @@
#ifndef V8_OBJECTS_JS_NUMBER_FORMAT_H_ #ifndef V8_OBJECTS_JS_NUMBER_FORMAT_H_
#define V8_OBJECTS_JS_NUMBER_FORMAT_H_ #define V8_OBJECTS_JS_NUMBER_FORMAT_H_
#include <set>
#include <string>
#include "src/heap/factory.h" #include "src/heap/factory.h"
#include "src/isolate.h" #include "src/isolate.h"
#include "src/objects.h" #include "src/objects.h"
...@@ -46,6 +49,8 @@ class JSNumberFormat : public JSObject { ...@@ -46,6 +49,8 @@ class JSNumberFormat : public JSObject {
V8_WARN_UNUSED_RESULT static MaybeHandle<String> FormatNumber( V8_WARN_UNUSED_RESULT static MaybeHandle<String> FormatNumber(
Isolate* isolate, Handle<JSNumberFormat> number_format, double number); Isolate* isolate, Handle<JSNumberFormat> number_format, double number);
static std::set<std::string> GetAvailableLocales();
Handle<String> StyleAsString() const; Handle<String> StyleAsString() const;
Handle<String> CurrencyDisplayAsString() const; Handle<String> CurrencyDisplayAsString() const;
......
...@@ -157,10 +157,9 @@ MaybeHandle<JSPluralRules> JSPluralRules::Initialize( ...@@ -157,10 +157,9 @@ MaybeHandle<JSPluralRules> JSPluralRules::Initialize(
// 11. Let r be ResolveLocale(%PluralRules%.[[AvailableLocales]], // 11. Let r be ResolveLocale(%PluralRules%.[[AvailableLocales]],
// requestedLocales, opt, %PluralRules%.[[RelevantExtensionKeys]], // requestedLocales, opt, %PluralRules%.[[RelevantExtensionKeys]],
// localeData). // localeData).
std::set<std::string> available_locales = Intl::ResolvedLocale r =
Intl::GetAvailableLocales(Intl::ICUService::kPluralRules); Intl::ResolveLocale(isolate, JSPluralRules::GetAvailableLocales(),
Intl::ResolvedLocale r = Intl::ResolveLocale(isolate, available_locales, requested_locales, matcher, {});
requested_locales, matcher, {});
// 18. Set collator.[[Locale]] to r.[[locale]]. // 18. Set collator.[[Locale]] to r.[[locale]].
icu::Locale icu_locale = r.icu_locale; icu::Locale icu_locale = r.icu_locale;
...@@ -331,5 +330,17 @@ Handle<JSObject> JSPluralRules::ResolvedOptions( ...@@ -331,5 +330,17 @@ Handle<JSObject> JSPluralRules::ResolvedOptions(
return options; return options;
} }
std::set<std::string> JSPluralRules::GetAvailableLocales() {
int32_t num_locales = 0;
// TODO(ftang): For PluralRules, filter out locales that
// don't support PluralRules.
// PluralRules is missing an appropriate getAvailableLocales method,
// so we should filter from all locales, but it's not clear how; see
// https://ssl.icu-project.org/trac/ticket/12756
const icu::Locale* icu_available_locales =
icu::Locale::getAvailableLocales(num_locales);
return Intl::BuildLocaleSet(icu_available_locales, num_locales);
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -9,6 +9,9 @@ ...@@ -9,6 +9,9 @@
#ifndef V8_OBJECTS_JS_PLURAL_RULES_H_ #ifndef V8_OBJECTS_JS_PLURAL_RULES_H_
#define V8_OBJECTS_JS_PLURAL_RULES_H_ #define V8_OBJECTS_JS_PLURAL_RULES_H_
#include <set>
#include <string>
#include "src/heap/factory.h" #include "src/heap/factory.h"
#include "src/isolate.h" #include "src/isolate.h"
#include "src/objects.h" #include "src/objects.h"
...@@ -37,6 +40,8 @@ class JSPluralRules : public JSObject { ...@@ -37,6 +40,8 @@ class JSPluralRules : public JSObject {
V8_WARN_UNUSED_RESULT static MaybeHandle<String> ResolvePlural( V8_WARN_UNUSED_RESULT static MaybeHandle<String> ResolvePlural(
Isolate* isolate, Handle<JSPluralRules> plural_rules, double number); Isolate* isolate, Handle<JSPluralRules> plural_rules, double number);
static std::set<std::string> GetAvailableLocales();
// [[Type]] is one of the values "cardinal" or "ordinal", // [[Type]] is one of the values "cardinal" or "ordinal",
// identifying the plural rules used. // identifying the plural rules used.
enum class Type { enum class Type {
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "src/objects-inl.h" #include "src/objects-inl.h"
#include "src/objects/intl-objects.h" #include "src/objects/intl-objects.h"
#include "src/objects/js-relative-time-format-inl.h" #include "src/objects/js-relative-time-format-inl.h"
#include "unicode/datefmt.h"
#include "unicode/numfmt.h" #include "unicode/numfmt.h"
#include "unicode/reldatefmt.h" #include "unicode/reldatefmt.h"
#include "unicode/uvernum.h" // for U_ICU_VERSION_MAJOR_NUM #include "unicode/uvernum.h" // for U_ICU_VERSION_MAJOR_NUM
...@@ -93,10 +94,9 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::Initialize( ...@@ -93,10 +94,9 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::Initialize(
// ResolveLocale(%RelativeTimeFormat%.[[AvailableLocales]], // ResolveLocale(%RelativeTimeFormat%.[[AvailableLocales]],
// requestedLocales, opt, // requestedLocales, opt,
// %RelativeTimeFormat%.[[RelevantExtensionKeys]], localeData). // %RelativeTimeFormat%.[[RelevantExtensionKeys]], localeData).
std::set<std::string> available_locales = Intl::ResolvedLocale r =
Intl::GetAvailableLocales(Intl::ICUService::kRelativeDateTimeFormatter); Intl::ResolveLocale(isolate, JSRelativeTimeFormat::GetAvailableLocales(),
Intl::ResolvedLocale r = Intl::ResolveLocale(isolate, available_locales, requested_locales, matcher, {});
requested_locales, matcher, {});
// 9. Let locale be r.[[Locale]]. // 9. Let locale be r.[[Locale]].
// 10. Set relativeTimeFormat.[[Locale]] to locale. // 10. Set relativeTimeFormat.[[Locale]] to locale.
...@@ -423,5 +423,12 @@ MaybeHandle<Object> JSRelativeTimeFormat::Format( ...@@ -423,5 +423,12 @@ MaybeHandle<Object> JSRelativeTimeFormat::Format(
formatted.length())); formatted.length()));
} }
std::set<std::string> JSRelativeTimeFormat::GetAvailableLocales() {
int32_t num_locales = 0;
const icu::Locale* icu_available_locales =
icu::DateFormat::getAvailableLocales(num_locales);
return Intl::BuildLocaleSet(icu_available_locales, num_locales);
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -9,6 +9,9 @@ ...@@ -9,6 +9,9 @@
#ifndef V8_OBJECTS_JS_RELATIVE_TIME_FORMAT_H_ #ifndef V8_OBJECTS_JS_RELATIVE_TIME_FORMAT_H_
#define V8_OBJECTS_JS_RELATIVE_TIME_FORMAT_H_ #define V8_OBJECTS_JS_RELATIVE_TIME_FORMAT_H_
#include <set>
#include <string>
#include "src/heap/factory.h" #include "src/heap/factory.h"
#include "src/isolate.h" #include "src/isolate.h"
#include "src/objects.h" #include "src/objects.h"
...@@ -47,6 +50,8 @@ class JSRelativeTimeFormat : public JSObject { ...@@ -47,6 +50,8 @@ class JSRelativeTimeFormat : public JSObject {
Handle<JSRelativeTimeFormat> format_holder, const char* func_name, Handle<JSRelativeTimeFormat> format_holder, const char* func_name,
bool to_parts); bool to_parts);
static std::set<std::string> GetAvailableLocales();
DECL_CAST(JSRelativeTimeFormat) DECL_CAST(JSRelativeTimeFormat)
// RelativeTimeFormat accessors. // RelativeTimeFormat accessors.
......
...@@ -76,10 +76,9 @@ MaybeHandle<JSSegmenter> JSSegmenter::Initialize( ...@@ -76,10 +76,9 @@ MaybeHandle<JSSegmenter> JSSegmenter::Initialize(
// 9. Let r be ResolveLocale(%Segmenter%.[[AvailableLocales]], // 9. Let r be ResolveLocale(%Segmenter%.[[AvailableLocales]],
// requestedLocales, opt, %Segmenter%.[[RelevantExtensionKeys]]). // requestedLocales, opt, %Segmenter%.[[RelevantExtensionKeys]]).
std::set<std::string> available_locales = Intl::ResolvedLocale r =
Intl::GetAvailableLocales(Intl::ICUService::kSegmenter); Intl::ResolveLocale(isolate, JSSegmenter::GetAvailableLocales(),
Intl::ResolvedLocale r = Intl::ResolveLocale(isolate, available_locales, requested_locales, matcher, {});
requested_locales, matcher, {});
// 7. Let lineBreakStyle be ? GetOption(options, "lineBreakStyle", "string", « // 7. Let lineBreakStyle be ? GetOption(options, "lineBreakStyle", "string", «
// "strict", "normal", "loose" », "normal"). // "strict", "normal", "loose" », "normal").
...@@ -236,5 +235,12 @@ Handle<String> JSSegmenter::GranularityAsString() const { ...@@ -236,5 +235,12 @@ Handle<String> JSSegmenter::GranularityAsString() const {
} }
} }
std::set<std::string> JSSegmenter::GetAvailableLocales() {
int32_t num_locales = 0;
const icu::Locale* icu_available_locales =
icu::BreakIterator::getAvailableLocales(num_locales);
return Intl::BuildLocaleSet(icu_available_locales, num_locales);
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -9,6 +9,9 @@ ...@@ -9,6 +9,9 @@
#ifndef V8_OBJECTS_JS_SEGMENTER_H_ #ifndef V8_OBJECTS_JS_SEGMENTER_H_
#define V8_OBJECTS_JS_SEGMENTER_H_ #define V8_OBJECTS_JS_SEGMENTER_H_
#include <set>
#include <string>
#include "src/heap/factory.h" #include "src/heap/factory.h"
#include "src/isolate.h" #include "src/isolate.h"
#include "src/objects.h" #include "src/objects.h"
...@@ -36,6 +39,8 @@ class JSSegmenter : public JSObject { ...@@ -36,6 +39,8 @@ class JSSegmenter : public JSObject {
V8_WARN_UNUSED_RESULT static Handle<JSObject> ResolvedOptions( V8_WARN_UNUSED_RESULT static Handle<JSObject> ResolvedOptions(
Isolate* isolate, Handle<JSSegmenter> segmenter_holder); Isolate* isolate, Handle<JSSegmenter> segmenter_holder);
static std::set<std::string> GetAvailableLocales();
Handle<String> LineBreakStyleAsString() const; Handle<String> LineBreakStyleAsString() const;
const char* LineBreakStyleAsCString() const; const char* LineBreakStyleAsCString() const;
Handle<String> GranularityAsString() const; Handle<String> GranularityAsString() const;
......
...@@ -7,7 +7,14 @@ ...@@ -7,7 +7,14 @@
#include "src/lookup.h" #include "src/lookup.h"
#include "src/objects-inl.h" #include "src/objects-inl.h"
#include "src/objects/intl-objects.h" #include "src/objects/intl-objects.h"
#include "src/objects/js-break-iterator.h"
#include "src/objects/js-collator.h"
#include "src/objects/js-date-time-format.h"
#include "src/objects/js-list-format.h"
#include "src/objects/js-number-format.h" #include "src/objects/js-number-format.h"
#include "src/objects/js-plural-rules.h"
#include "src/objects/js-relative-time-format.h"
#include "src/objects/js-segmenter.h"
#include "test/cctest/cctest.h" #include "test/cctest/cctest.h"
namespace v8 { namespace v8 {
...@@ -211,25 +218,31 @@ TEST(GetBoolOption) { ...@@ -211,25 +218,31 @@ TEST(GetBoolOption) {
TEST(GetAvailableLocales) { TEST(GetAvailableLocales) {
std::set<std::string> locales; std::set<std::string> locales;
locales = Intl::GetAvailableLocales(Intl::ICUService::kBreakIterator); locales = JSV8BreakIterator::GetAvailableLocales();
CHECK(locales.count("en-US")); CHECK(locales.count("en-US"));
CHECK(!locales.count("abcdefg")); CHECK(!locales.count("abcdefg"));
locales = Intl::GetAvailableLocales(Intl::ICUService::kCollator); locales = JSCollator::GetAvailableLocales();
CHECK(locales.count("en-US")); CHECK(locales.count("en-US"));
locales = Intl::GetAvailableLocales(Intl::ICUService::kDateFormat); locales = JSDateTimeFormat::GetAvailableLocales();
CHECK(locales.count("en-US")); CHECK(locales.count("en-US"));
locales = Intl::GetAvailableLocales(Intl::ICUService::kNumberFormat); locales = JSListFormat::GetAvailableLocales();
CHECK(locales.count("en-US")); CHECK(locales.count("en-US"));
locales = Intl::GetAvailableLocales(Intl::ICUService::kPluralRules); locales = JSNumberFormat::GetAvailableLocales();
CHECK(locales.count("en-US")); CHECK(locales.count("en-US"));
locales = locales = JSPluralRules::GetAvailableLocales();
Intl::GetAvailableLocales(Intl::ICUService::kRelativeDateTimeFormatter);
CHECK(locales.count("en-US")); CHECK(locales.count("en-US"));
locales = JSRelativeTimeFormat::GetAvailableLocales();
CHECK(locales.count("en-US"));
locales = JSSegmenter::GetAvailableLocales();
CHECK(locales.count("en-US"));
CHECK(!locales.count("abcdefg"));
} }
} // namespace internal } // namespace internal
......
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