Commit be123e40 authored by Frank Tang's avatar Frank Tang Committed by Commit Bot

Sync DisplayNames with latest spec

Make locales and options required
and no default for type in options.

Bug: v8:10623
Change-Id: I5df065a95e82ecb3b8b036d1b4738f296aa7243f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2291617Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Frank Tang <ftang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68854}
parent cb0e1242
......@@ -36,6 +36,7 @@ namespace {
//
// ecma402/#sec-properties-of-intl-displaynames-instances
enum class Type {
kUndefined,
kLanguage,
kRegion,
kScript,
......@@ -498,41 +499,34 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate,
std::vector<std::string> requested_locales =
maybe_requested_locales.FromJust();
// 4. If options is undefined, then
if (input_options->IsUndefined(isolate)) {
// 4. a. Let options be ObjectCreate(null).
options = factory->NewJSObjectWithNullProto();
// 5. Else
} else {
// 5. a. Let options be ? ToObject(options).
ASSIGN_RETURN_ON_EXCEPTION(isolate, options,
Object::ToObject(isolate, input_options),
JSDisplayNames);
}
// 4. Let options be ? ToObject(options).
ASSIGN_RETURN_ON_EXCEPTION(isolate, options,
Object::ToObject(isolate, input_options),
JSDisplayNames);
// Note: No need to create a record. It's not observable.
// 6. Let opt be a new Record.
// 5. Let opt be a new Record.
// 7. Let localeData be %DisplayNames%.[[LocaleData]].
// 6. Let localeData be %DisplayNames%.[[LocaleData]].
// 8. Let matcher be ? GetOption(options, "localeMatcher", "string", «
// 7. Let matcher be ? GetOption(options, "localeMatcher", "string", «
// "lookup", "best fit" », "best fit").
Maybe<Intl::MatcherOption> maybe_locale_matcher =
Intl::GetLocaleMatcher(isolate, options, "Intl.DisplayNames");
MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSDisplayNames>());
// 9. Set opt.[[localeMatcher]] to matcher.
// 8. Set opt.[[localeMatcher]] to matcher.
Intl::MatcherOption matcher = maybe_locale_matcher.FromJust();
std::unique_ptr<char[]> calendar_str = nullptr;
if (FLAG_harmony_intl_displaynames_date_types) {
const std::vector<const char*> empty_values = {};
// 10. Let calendar be ? GetOption(options, "calendar",
// Let calendar be ? GetOption(options, "calendar",
// "string", undefined, undefined).
Maybe<bool> maybe_calendar = Intl::GetStringOption(
isolate, options, "calendar", empty_values, service, &calendar_str);
MAYBE_RETURN(maybe_calendar, MaybeHandle<JSDisplayNames>());
// 11. If calendar is not undefined, then
// If calendar is not undefined, then
if (maybe_calendar.FromJust() && calendar_str != nullptr) {
// a. If calendar does not match the (3*8alphanum) *("-" (3*8alphanum))
// sequence, throw a RangeError exception.
......@@ -547,14 +541,14 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate,
}
}
// 12. Set opt.[[ca]] to calendar.
// Set opt.[[ca]] to calendar.
// ecma402/#sec-Intl.DisplayNames-internal-slots
// The value of the [[RelevantExtensionKeys]] internal slot is
// « "ca" ».
std::set<std::string> relevant_extension_keys_ca = {"ca"};
std::set<std::string> relevant_extension_keys = {};
// 13. Let r be ResolveLocale(%DisplayNames%.[[AvailableLocales]],
// 9. Let r be ResolveLocale(%DisplayNames%.[[AvailableLocales]],
// requestedLocales, opt, %DisplayNames%.[[RelevantExtensionKeys]]).
Maybe<Intl::ResolvedLocale> maybe_resolve_locale = Intl::ResolveLocale(
isolate, JSDisplayNames::GetAvailableLocales(), requested_locales,
......@@ -575,7 +569,7 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate,
CHECK(U_SUCCESS(status));
}
// 14. Let s be ? GetOption(options, "style", "string",
// 10. Let s be ? GetOption(options, "style", "string",
// «"long", "short", "narrow"», "long").
Maybe<Style> maybe_style = Intl::GetStringOption<Style>(
isolate, options, "style", "Intl.DisplayNames",
......@@ -584,11 +578,11 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate,
MAYBE_RETURN(maybe_style, MaybeHandle<JSDisplayNames>());
Style style_enum = maybe_style.FromJust();
// 15. Set displayNames.[[Style]] to style.
// 11. Set displayNames.[[Style]] to style.
// 16. Let type be ? GetOption(options, "type", "string", « "language",
// 12. Let type be ? GetOption(options, "type", "string", « "language",
// "region", "script", "currency", "weekday", "month", "quarter",
// "dayPeriod", "dateTimeField" », "language").
// "dayPeriod", "dateTimeField" », undefined).
Maybe<Type> maybe_type =
FLAG_harmony_intl_displaynames_date_types
? Intl::GetStringOption<Type>(
......@@ -606,7 +600,7 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate,
Type::kDayPeriod,
Type::kDateTimeField,
},
Type::kLanguage)
Type::kUndefined)
: Intl::GetStringOption<Type>(
isolate, options, "type", "Intl.DisplayNames",
{"language", "region", "script", "currency"},
......@@ -616,13 +610,19 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate,
Type::kScript,
Type::kCurrency,
},
Type::kLanguage);
Type::kUndefined);
MAYBE_RETURN(maybe_type, MaybeHandle<JSDisplayNames>());
Type type_enum = maybe_type.FromJust();
// 17. Set displayNames.[[Type]] to type.
// 13. If type is undefined, throw a TypeError exception.
if (type_enum == Type::kUndefined) {
THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kInvalidArgument),
JSDisplayNames);
}
// 14. Set displayNames.[[Type]] to type.
// 18. Let fallback be ? GetOption(options, "fallback", "string",
// 15. Let fallback be ? GetOption(options, "fallback", "string",
// « "code", "none" », "code").
Maybe<Fallback> maybe_fallback = Intl::GetStringOption<Fallback>(
isolate, options, "fallback", "Intl.DisplayNames", {"code", "none"},
......@@ -630,9 +630,9 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate,
MAYBE_RETURN(maybe_fallback, MaybeHandle<JSDisplayNames>());
Fallback fallback_enum = maybe_fallback.FromJust();
// 19. Set displayNames.[[Fallback]] to fallback.
// 16. Set displayNames.[[Fallback]] to fallback.
// 20. Set displayNames.[[Locale]] to the value of r.[[Locale]].
// 17. Set displayNames.[[Locale]] to the value of r.[[Locale]].
// Let calendar be r.[[ca]].
......
......@@ -16,6 +16,7 @@ new Intl.DisplayNames(['en-US'], {
},
get type() {
assertEquals(2, getCount++);
return 'language';
},
get fallback() {
assertEquals(3, getCount++);
......
......@@ -4,20 +4,29 @@
// DisplayNames constructor can't be called as function.
assertThrows(() => Intl.DisplayNames('sr'), TypeError);
assertThrows(() => Intl.DisplayNames('sr', {}), TypeError);
assertThrows(() => Intl.DisplayNames(undefined, {}), TypeError);
assertDoesNotThrow(() => new Intl.DisplayNames('sr', {}));
assertDoesNotThrow(() =>
new Intl.DisplayNames('sr', {type: 'language'}));
assertDoesNotThrow(() => new Intl.DisplayNames([], {}));
assertDoesNotThrow(() =>
new Intl.DisplayNames([], {type: 'language'}));
assertDoesNotThrow(() => new Intl.DisplayNames(['fr', 'ar'], {}));
assertDoesNotThrow(() =>
new Intl.DisplayNames(['fr', 'ar'], {type: 'language'}));
assertDoesNotThrow(() => new Intl.DisplayNames({0: 'ja', 1:'fr'}, {}));
assertDoesNotThrow(() =>
new Intl.DisplayNames({0: 'ja', 1:'fr'}, {type: 'language'}));
assertDoesNotThrow(() => new Intl.DisplayNames({1: 'ja', 2:'fr'}, {}));
assertDoesNotThrow(() =>
new Intl.DisplayNames({1: 'ja', 2:'fr'}, {type: 'language'}));
assertDoesNotThrow(() => new Intl.DisplayNames('sr'));
assertDoesNotThrow(() =>
new Intl.DisplayNames('sr', {type: 'language'}));
assertDoesNotThrow(() => new Intl.DisplayNames());
assertDoesNotThrow(() =>
new Intl.DisplayNames(undefined, {type: 'language'}));
assertDoesNotThrow(
() => new Intl.DisplayNames(
......@@ -30,59 +39,76 @@ assertDoesNotThrow(
assertDoesNotThrow(
() => new Intl.DisplayNames('sr', {localeMatcher: 'lookup'}));
() => new Intl.DisplayNames(
'sr', {localeMatcher: 'lookup', type: 'language'}));
assertDoesNotThrow(
() => new Intl.DisplayNames('sr', {localeMatcher: 'best fit'}));
() => new Intl.DisplayNames(
'sr', {localeMatcher: 'best fit', type: 'language'}));
assertThrows(
() => new Intl.DisplayNames('sr', {localeMatcher: 'hello'}),
() => new Intl.DisplayNames(
'sr', {localeMatcher: 'hello', type: 'language'}),
RangeError);
assertThrows(
() => new Intl.DisplayNames('sr', {localeMatcher: 'look up'}),
() => new Intl.DisplayNames(
'sr', {localeMatcher: 'look up', type: 'language'}),
RangeError);
assertThrows(
() => new Intl.DisplayNames('sr', {localeMatcher: 'bestfit'}),
() => new Intl.DisplayNames(
'sr', {localeMatcher: 'bestfit', type: 'language'}),
RangeError);
assertDoesNotThrow(
() => new Intl.DisplayNames('sr', {style: 'long'}));
() => new Intl.DisplayNames(
'sr', {style: 'long', type: 'language'}));
assertDoesNotThrow(
() => new Intl.DisplayNames('sr', {style: 'short'}));
() => new Intl.DisplayNames(
'sr', {style: 'short', type: 'language'}));
assertDoesNotThrow(
() => new Intl.DisplayNames('sr', {style: 'narrow'}));
() => new Intl.DisplayNames(
'sr', {style: 'narrow', type: 'language'}));
assertThrows(
() => new Intl.DisplayNames('sr', {style: 'giant'}),
() => new Intl.DisplayNames(
'sr', {style: 'giant', type: 'language'}),
RangeError);
assertDoesNotThrow(
() => new Intl.DisplayNames('sr', {fallback: 'code'}));
() => new Intl.DisplayNames(
'sr', {fallback: 'code', type: 'language'}));
assertDoesNotThrow(
() => new Intl.DisplayNames('sr', {fallback: 'none'}));
() => new Intl.DisplayNames(
'sr', {fallback: 'none', type: 'language'}));
assertThrows(
() => new Intl.DisplayNames('sr', {fallback: 'never'}),
() => new Intl.DisplayNames(
'sr', {fallback: 'never', type: 'language'}),
RangeError);
assertDoesNotThrow(
() => new Intl.DisplayNames('sr', {type: 'language'}));
() => new Intl.DisplayNames(
'sr', {type: 'language'}));
assertDoesNotThrow(
() => new Intl.DisplayNames('sr', {type: 'region'}));
() => new Intl.DisplayNames(
'sr', {type: 'region'}));
assertDoesNotThrow(
() => new Intl.DisplayNames('sr', {type: 'script'}));
() => new Intl.DisplayNames(
'sr', {type: 'script'}));
assertDoesNotThrow(
() => new Intl.DisplayNames('sr', {type: 'currency'}));
() => new Intl.DisplayNames(
'sr', {type: 'currency'}));
assertThrows(
() => new Intl.DisplayNames('sr', {type: ''}),
() => new Intl.DisplayNames(
'sr', {type: ''}),
RangeError);
......@@ -2,11 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let displayNames = new Intl.DisplayNames();
let displayNames = new Intl.DisplayNames(undefined, {type: 'language'});
// The default style is 'long'
assertEquals('long', displayNames.resolvedOptions().style);
// The default type is 'language'
assertEquals('language', displayNames.resolvedOptions().type);
// The default fallback is 'code'
......@@ -17,12 +16,6 @@ const types = ["language", "region", "script", "currency"];
const fallbacks = ["code", "none"];
styles.forEach(function(style) {
assertEquals(style,
(new Intl.DisplayNames(['sr'], {style})).resolvedOptions().style);
assertEquals(types[0],
(new Intl.DisplayNames(['sr'], {style})).resolvedOptions().type);
assertEquals(fallbacks[0],
(new Intl.DisplayNames(['sr'], {style})).resolvedOptions().fallback);
types.forEach(function(type) {
assertEquals(style,
(new Intl.DisplayNames(['sr'], {style, type})).resolvedOptions().style);
......
......@@ -665,9 +665,6 @@
# https://crbug.com/v8/10688
'language/expressions/optional-chaining/eval-optional-call': [FAIL],
# https://crbug.com/v8/10623
'intl402/DisplayNames/options-type-invalid-throws': [FAIL],
######################## NEEDS INVESTIGATION ###########################
# https://bugs.chromium.org/p/v8/issues/detail?id=7833
......
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