Commit 1faa8c8b authored by Frank Tang's avatar Frank Tang Committed by Commit Bot

[intl] correct Locale (min|max)imize

The revised spec in
https://tc39.es/ecma402/#sec-Intl.Locale.prototype.maximize

now set the minimal or maximal to the %Locale% without
the same opeartion as in Intl.Locale(tag, [option])

Bug: v8:10489
Change-Id: I08c45879b158a84e8cba19922423666e2b98412b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2174976Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Frank Tang <ftang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67548}
parent f90446a1
......@@ -604,23 +604,35 @@ BUILTIN(ListFormatSupportedLocalesOf) {
JSListFormat::GetAvailableLocales(), locales, options));
}
namespace {
// Intl.Locale implementation
BUILTIN(LocaleConstructor) {
HandleScope scope(isolate);
isolate->CountUsage(v8::Isolate::UseCounterFeature::kLocale);
if (args.new_target()->IsUndefined(isolate)) { // [[Call]]
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kConstructorNotFunction,
isolate->factory()->NewStringFromAsciiChecked(
"Intl.Locale")));
}
// [[Construct]]
Handle<JSFunction> target = args.target();
Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
Handle<Object> tag = args.atOrUndefined(isolate, 1);
Handle<Object> options = args.atOrUndefined(isolate, 2);
MaybeHandle<JSLocale> CreateLocale(Isolate* isolate,
Handle<JSFunction> constructor,
Handle<JSReceiver> new_target,
Handle<Object> tag, Handle<Object> options) {
Handle<Map> map;
// 6. Let locale be ? OrdinaryCreateFromConstructor(NewTarget,
// %LocalePrototype%, internalSlotsList).
ASSIGN_RETURN_ON_EXCEPTION(
isolate, map, JSFunction::GetDerivedMap(isolate, constructor, new_target),
JSLocale);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, map, JSFunction::GetDerivedMap(isolate, target, new_target));
// 7. If Type(tag) is not String or Object, throw a TypeError exception.
if (!tag->IsString() && !tag->IsJSReceiver()) {
THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kLocaleNotEmpty),
JSLocale);
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kLocaleNotEmpty));
}
Handle<String> locale_string;
......@@ -631,8 +643,8 @@ MaybeHandle<JSLocale> CreateLocale(Isolate* isolate,
locale_string = JSLocale::ToString(isolate, Handle<JSLocale>::cast(tag));
} else { // 9. Else,
// a. Let tag be ? ToString(tag).
ASSIGN_RETURN_ON_EXCEPTION(isolate, locale_string,
Object::ToString(isolate, tag), JSLocale);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, locale_string,
Object::ToString(isolate, tag));
}
Handle<JSReceiver> options_object;
......@@ -642,60 +654,24 @@ MaybeHandle<JSLocale> CreateLocale(Isolate* isolate,
options_object = isolate->factory()->NewJSObjectWithNullProto();
} else { // 11. Else
// a. Let options be ? ToObject(options).
ASSIGN_RETURN_ON_EXCEPTION(isolate, options_object,
Object::ToObject(isolate, options), JSLocale);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, options_object,
Object::ToObject(isolate, options));
}
return JSLocale::New(isolate, map, locale_string, options_object);
}
} // namespace
// Intl.Locale implementation
BUILTIN(LocaleConstructor) {
HandleScope scope(isolate);
isolate->CountUsage(v8::Isolate::UseCounterFeature::kLocale);
if (args.new_target()->IsUndefined(isolate)) { // [[Call]]
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kConstructorNotFunction,
isolate->factory()->NewStringFromAsciiChecked(
"Intl.Locale")));
}
// [[Construct]]
Handle<JSFunction> target = args.target();
Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
Handle<Object> tag = args.atOrUndefined(isolate, 1);
Handle<Object> options = args.atOrUndefined(isolate, 2);
RETURN_RESULT_OR_FAILURE(
isolate, CreateLocale(isolate, target, new_target, tag, options));
isolate, JSLocale::New(isolate, map, locale_string, options_object));
}
BUILTIN(LocalePrototypeMaximize) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.maximize");
Handle<JSFunction> constructor(
isolate->native_context()->intl_locale_function(), isolate);
Handle<String> locale_str = JSLocale::ToString(isolate, locale);
RETURN_RESULT_OR_FAILURE(
isolate, CreateLocale(isolate, constructor, constructor,
JSLocale::Maximize(isolate, *locale_str),
isolate->factory()->NewJSObjectWithNullProto()));
RETURN_RESULT_OR_FAILURE(isolate, JSLocale::Maximize(isolate, locale));
}
BUILTIN(LocalePrototypeMinimize) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.minimize");
Handle<JSFunction> constructor(
isolate->native_context()->intl_locale_function(), isolate);
Handle<String> locale_str = JSLocale::ToString(isolate, locale);
RETURN_RESULT_OR_FAILURE(
isolate, CreateLocale(isolate, constructor, constructor,
JSLocale::Minimize(isolate, *locale_str),
isolate->factory()->NewJSObjectWithNullProto()));
RETURN_RESULT_OR_FAILURE(isolate, JSLocale::Minimize(isolate, locale));
}
BUILTIN(RelativeTimeFormatSupportedLocalesOf) {
......
......@@ -365,38 +365,47 @@ MaybeHandle<JSLocale> JSLocale::New(Isolate* isolate, Handle<Map> map,
}
namespace {
Handle<String> MorphLocale(Isolate* isolate, String locale,
void (*morph_func)(icu::Locale*, UErrorCode*)) {
UErrorCode status = U_ZERO_ERROR;
icu::Locale icu_locale =
icu::Locale::forLanguageTag(locale.ToCString().get(), status);
// TODO(ftang): Remove the following lines after ICU-8420 fixed.
// Due to ICU-8420 "und" is turn into "" by forLanguageTag,
// we have to work around to use icu::Locale("und") directly
if (icu_locale.getName()[0] == '\0') icu_locale = icu::Locale("und");
CHECK(U_SUCCESS(status));
CHECK(!icu_locale.isBogus());
(*morph_func)(&icu_locale, &status);
CHECK(U_SUCCESS(status));
CHECK(!icu_locale.isBogus());
std::string locale_str = Intl::ToLanguageTag(icu_locale).FromJust();
return isolate->factory()->NewStringFromAsciiChecked(locale_str.c_str());
MaybeHandle<JSLocale> Construct(Isolate* isolate,
const icu::Locale& icu_locale) {
Handle<Managed<icu::Locale>> managed_locale =
Managed<icu::Locale>::FromRawPtr(isolate, 0, icu_locale.clone());
Handle<JSFunction> constructor(
isolate->native_context()->intl_locale_function(), isolate);
Handle<Map> map;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, map,
JSFunction::GetDerivedMap(isolate, constructor, constructor), JSLocale);
Handle<JSLocale> locale = Handle<JSLocale>::cast(
isolate->factory()->NewFastOrSlowJSObjectFromMap(map));
DisallowHeapAllocation no_gc;
locale->set_icu_locale(*managed_locale);
return locale;
}
} // namespace
Handle<String> JSLocale::Maximize(Isolate* isolate, String locale) {
return MorphLocale(isolate, locale,
[](icu::Locale* icu_locale, UErrorCode* status) {
icu_locale->addLikelySubtags(*status);
});
MaybeHandle<JSLocale> JSLocale::Maximize(Isolate* isolate,
Handle<JSLocale> locale) {
icu::Locale icu_locale(*(locale->icu_locale().raw()));
UErrorCode status = U_ZERO_ERROR;
icu_locale.addLikelySubtags(status);
DCHECK(U_SUCCESS(status));
DCHECK(!icu_locale.isBogus());
return Construct(isolate, icu_locale);
}
Handle<String> JSLocale::Minimize(Isolate* isolate, String locale) {
return MorphLocale(isolate, locale,
[](icu::Locale* icu_locale, UErrorCode* status) {
icu_locale->minimizeSubtags(*status);
});
MaybeHandle<JSLocale> JSLocale::Minimize(Isolate* isolate,
Handle<JSLocale> locale) {
icu::Locale icu_locale(*(locale->icu_locale().raw()));
UErrorCode status = U_ZERO_ERROR;
icu_locale.minimizeSubtags(status);
DCHECK(U_SUCCESS(status));
DCHECK(!icu_locale.isBogus());
return Construct(isolate, icu_locale);
}
Handle<Object> JSLocale::Language(Isolate* isolate, Handle<JSLocale> locale) {
......
......@@ -32,8 +32,11 @@ class JSLocale : public JSObject {
static MaybeHandle<JSLocale> New(Isolate* isolate, Handle<Map> map,
Handle<String> locale,
Handle<JSReceiver> options);
static Handle<String> Maximize(Isolate* isolate, String locale);
static Handle<String> Minimize(Isolate* isolate, String locale);
static MaybeHandle<JSLocale> Maximize(Isolate* isolate,
Handle<JSLocale> locale);
static MaybeHandle<JSLocale> Minimize(Isolate* isolate,
Handle<JSLocale> locale);
static Handle<Object> Language(Isolate* isolate, Handle<JSLocale> locale);
static Handle<Object> Script(Isolate* isolate, Handle<JSLocale> 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