Commit 43fff26f authored by Brian Stell's avatar Brian Stell Committed by Commit Bot

Implement ECMA 402 10.2.2 Intl.*.supportedLocalesOf

Bug: v8:7955, v8:5751
Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng
Change-Id: I2dbba859472059e684ec2c631b7e96d1289f39f0
Reviewed-on: https://chromium-review.googlesource.com/1173165Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Commit-Queue: Brian Stell <bstell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55178}
parent a1c69e8d
...@@ -226,89 +226,6 @@ function GetTimezoneNameLocationPartRE() { ...@@ -226,89 +226,6 @@ function GetTimezoneNameLocationPartRE() {
} }
/**
* Returns an intersection of locales and service supported locales.
* Parameter locales is treated as a priority list.
*/
function supportedLocalesOf(service, locales, options) {
if (IS_NULL(%regexp_internal_match(GetServiceRE(), service))) {
throw %make_error(kWrongServiceType, service);
}
// Provide defaults if matcher was not specified.
if (IS_UNDEFINED(options)) {
options = {__proto__: null};
} else {
options = TO_OBJECT(options);
}
var matcher = options.localeMatcher;
if (!IS_UNDEFINED(matcher)) {
matcher = TO_STRING(matcher);
if (matcher !== 'lookup' && matcher !== 'best fit') {
throw %make_range_error(kLocaleMatcher, matcher);
}
} else {
matcher = 'best fit';
}
var requestedLocales = initializeLocaleList(locales);
var availableLocales = getAvailableLocalesOf(service);
// Use either best fit or lookup algorithm to match locales.
if (matcher === 'best fit') {
return initializeLocaleList(bestFitSupportedLocalesOf(
requestedLocales, availableLocales));
}
return initializeLocaleList(lookupSupportedLocalesOf(
requestedLocales, availableLocales));
}
/**
* Returns the subset of the provided BCP 47 language priority list for which
* this service has a matching locale when using the BCP 47 Lookup algorithm.
* Locales appear in the same order in the returned list as in the input list.
*/
function lookupSupportedLocalesOf(requestedLocales, availableLocales) {
var matchedLocales = new InternalArray();
for (var i = 0; i < requestedLocales.length; ++i) {
// Remove -u- extension.
var locale = %RegExpInternalReplace(
GetUnicodeExtensionRE(), requestedLocales[i], '');
do {
if (!IS_UNDEFINED(availableLocales[locale])) {
// Push requested locale not the resolved one.
%_Call(ArrayPush, matchedLocales, requestedLocales[i]);
break;
}
// Truncate locale if possible, if not break.
var pos = %StringLastIndexOf(locale, '-');
if (pos === -1) {
break;
}
locale = %_Call(StringSubstring, locale, 0, pos);
} while (true);
}
return matchedLocales;
}
/**
* Returns the subset of the provided BCP 47 language priority list for which
* this service has a matching locale when using the implementation
* dependent algorithm.
* Locales appear in the same order in the returned list as in the input list.
*/
function bestFitSupportedLocalesOf(requestedLocales, availableLocales) {
// TODO(cira): implement better best fit algorithm.
return lookupSupportedLocalesOf(requestedLocales, availableLocales);
}
/** /**
* Returns a getOption function that extracts property value for given * Returns a getOption function that extracts property value for given
* options object. If property is missing it returns defaultValue. If value * options object. If property is missing it returns defaultValue. If value
...@@ -751,7 +668,7 @@ DEFINE_METHOD( ...@@ -751,7 +668,7 @@ DEFINE_METHOD(
DEFINE_METHOD( DEFINE_METHOD(
GlobalIntlCollator, GlobalIntlCollator,
supportedLocalesOf(locales) { supportedLocalesOf(locales) {
return supportedLocalesOf('collator', locales, arguments[1]); return %SupportedLocalesOf('collator', locales, arguments[1]);
} }
); );
...@@ -766,7 +683,7 @@ DEFINE_METHOD( ...@@ -766,7 +683,7 @@ DEFINE_METHOD(
DEFINE_METHOD( DEFINE_METHOD(
GlobalIntlPluralRules, GlobalIntlPluralRules,
supportedLocalesOf(locales) { supportedLocalesOf(locales) {
return supportedLocalesOf('pluralrules', locales, arguments[1]); return %SupportedLocalesOf('pluralrules', locales, arguments[1]);
} }
); );
...@@ -970,7 +887,7 @@ DEFINE_METHOD( ...@@ -970,7 +887,7 @@ DEFINE_METHOD(
DEFINE_METHOD( DEFINE_METHOD(
GlobalIntlNumberFormat, GlobalIntlNumberFormat,
supportedLocalesOf(locales) { supportedLocalesOf(locales) {
return supportedLocalesOf('numberformat', locales, arguments[1]); return %SupportedLocalesOf('numberformat', locales, arguments[1]);
} }
); );
...@@ -1334,7 +1251,7 @@ DEFINE_METHOD( ...@@ -1334,7 +1251,7 @@ DEFINE_METHOD(
DEFINE_METHOD( DEFINE_METHOD(
GlobalIntlDateTimeFormat, GlobalIntlDateTimeFormat,
supportedLocalesOf(locales) { supportedLocalesOf(locales) {
return supportedLocalesOf('dateformat', locales, arguments[1]); return %SupportedLocalesOf('dateformat', locales, arguments[1]);
} }
); );
...@@ -1488,7 +1405,7 @@ DEFINE_METHOD( ...@@ -1488,7 +1405,7 @@ DEFINE_METHOD(
throw %make_type_error(kOrdinaryFunctionCalledAsConstructor); throw %make_type_error(kOrdinaryFunctionCalledAsConstructor);
} }
return supportedLocalesOf('breakiterator', locales, arguments[1]); return %SupportedLocalesOf('breakiterator', locales, arguments[1]);
} }
); );
......
This diff is collapsed.
...@@ -179,6 +179,8 @@ class Intl { ...@@ -179,6 +179,8 @@ class Intl {
static bool IsObjectOfType(Isolate* isolate, Handle<Object> object, static bool IsObjectOfType(Isolate* isolate, Handle<Object> object,
Intl::Type expected_type); Intl::Type expected_type);
static IcuService StringToIcuService(Handle<String> service);
// Gets the ICU locales for a given service. If there is a locale with a // 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, // 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_Guru_IN (language=Panjabi, script=Gurmukhi, country-India) would include
...@@ -188,6 +190,11 @@ class Intl { ...@@ -188,6 +190,11 @@ class Intl {
static V8_WARN_UNUSED_RESULT MaybeHandle<JSObject> AvailableLocalesOf( static V8_WARN_UNUSED_RESULT MaybeHandle<JSObject> AvailableLocalesOf(
Isolate* isolate, Handle<String> service); Isolate* isolate, Handle<String> service);
static MaybeHandle<JSObject> SupportedLocalesOf(Isolate* isolate,
Handle<String> service,
Handle<Object> locales_in,
Handle<Object> options_in);
static std::string DefaultLocale(Isolate* isolate); static std::string DefaultLocale(Isolate* isolate);
static void DefineWEProperty(Isolate* isolate, Handle<JSObject> target, static void DefineWEProperty(Isolate* isolate, Handle<JSObject> target,
......
...@@ -535,5 +535,18 @@ RUNTIME_FUNCTION(Runtime_IntlUnwrapReceiver) { ...@@ -535,5 +535,18 @@ RUNTIME_FUNCTION(Runtime_IntlUnwrapReceiver) {
check_legacy_constructor)); check_legacy_constructor));
} }
RUNTIME_FUNCTION(Runtime_SupportedLocalesOf) {
HandleScope scope(isolate);
DCHECK_EQ(args.length(), 3);
CONVERT_ARG_HANDLE_CHECKED(String, service, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, locales, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, options, 2);
RETURN_RESULT_OR_FAILURE(
isolate, Intl::SupportedLocalesOf(isolate, service, locales, options));
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -230,7 +230,9 @@ namespace internal { ...@@ -230,7 +230,9 @@ namespace internal {
F(PluralRulesResolvedOptions, 1, 1) \ F(PluralRulesResolvedOptions, 1, 1) \
F(PluralRulesSelect, 2, 1) \ F(PluralRulesSelect, 2, 1) \
F(StringToLowerCaseIntl, 1, 1) \ F(StringToLowerCaseIntl, 1, 1) \
F(StringToUpperCaseIntl, 1, 1) F(StringToUpperCaseIntl, 1, 1) \
F(SupportedLocalesOf, 3, 1) \
// End of macro.
#else #else
#define FOR_EACH_INTRINSIC_INTL(F) #define FOR_EACH_INTRINSIC_INTL(F)
#endif // V8_INTL_SUPPORT #endif // V8_INTL_SUPPORT
......
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