Commit c0f90e59 authored by Frank Tang's avatar Frank Tang Committed by V8 LUCI CQ

Implement DisplayNames v2

Add "calendar", and "dateTimeField"
Add option for languageDisplay

https://tc39.es/intl-displaynames-v2/
https://chromestatus.com/feature/5082027281874944
Design Doc:
https://docs.google.com/document/d/17hQz4nOC7PJYhxc_MU-BRoT6BnYGZv66XlU1iGX0ywQ/edit#

Bug: v8:11637
Change-Id: Ie7dc80d16956f0e668b11e600e47f5bafb081ff7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2924523
Commit-Queue: Frank Tang <ftang@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75027}
parent c9b1f165
......@@ -280,7 +280,7 @@ DEFINE_BOOL(harmony_shipping, true, "enable all shipped harmony features")
#ifdef V8_INTL_SUPPORT
#define HARMONY_INPROGRESS(V) \
HARMONY_INPROGRESS_BASE(V) \
V(harmony_intl_displaynames_date_types, "Intl.DisplayNames date types")
V(harmony_intl_displaynames_v2, "Intl.DisplayNames v2")
#else
#define HARMONY_INPROGRESS(V) HARMONY_INPROGRESS_BASE(V)
#endif
......
......@@ -4417,7 +4417,7 @@ EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_error_cause)
#ifdef V8_INTL_SUPPORT
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_intl_best_fit_matcher)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_intl_displaynames_date_types)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_intl_displaynames_v2)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_intl_dateformat_day_period)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_intl_more_timezone)
#endif // V8_INTL_SUPPORT
......
......@@ -28,6 +28,7 @@
V(_, day_string, "day") \
V(_, dayPeriod_string, "dayPeriod") \
V(_, decimal_string, "decimal") \
V(_, dialect_string, "dialect") \
V(_, direction_string, "direction") \
V(_, endRange_string, "endRange") \
V(_, engineering_string, "engineering") \
......@@ -62,6 +63,7 @@
V(_, isWordLike_string, "isWordLike") \
V(_, kana_string, "kana") \
V(_, language_string, "language") \
V(_, languageDisplay_string, "languageDisplay") \
V(_, letter_string, "letter") \
V(_, list_string, "list") \
V(_, literal_string, "literal") \
......
......@@ -35,15 +35,23 @@ inline JSDisplayNames::Style JSDisplayNames::style() const {
inline void JSDisplayNames::set_fallback(Fallback fallback) {
DCHECK_GE(FallbackBit::kMax, fallback);
int hints = flags();
hints = FallbackBit::update(hints, fallback);
set_flags(hints);
set_flags(FallbackBit::update(flags(), fallback));
}
inline JSDisplayNames::Fallback JSDisplayNames::fallback() const {
return FallbackBit::decode(flags());
}
inline void JSDisplayNames::set_language_display(
LanguageDisplay language_display) {
DCHECK_GE(LanguageDisplayBit::kMax, language_display);
set_flags(LanguageDisplayBit::update(flags(), language_display));
}
inline JSDisplayNames::LanguageDisplay JSDisplayNames::language_display()
const {
return LanguageDisplayBit::decode(flags());
}
} // namespace internal
} // namespace v8
......
......@@ -6,22 +6,22 @@
#error Internationalization is expected to be enabled.
#endif // V8_INTL_SUPPORT
#include "src/objects/js-display-names.h"
#include <memory>
#include <vector>
#include "src/objects/js-display-names-inl.h"
#include "src/objects/js-display-names.h"
#include "src/execution/isolate.h"
#include "src/heap/factory.h"
#include "src/objects/intl-objects.h"
#include "src/objects/js-display-names-inl.h"
#include "src/objects/managed.h"
#include "src/objects/objects-inl.h"
#include "unicode/dtfmtsym.h"
#include "unicode/dtptngen.h"
#include "unicode/localebuilder.h"
#include "unicode/locdspnm.h"
#include "unicode/measfmt.h"
#include "unicode/timezone.h"
#include "unicode/tznames.h"
#include "unicode/uloc.h"
......@@ -41,10 +41,7 @@ enum class Type {
kRegion,
kScript,
kCurrency,
kWeekday,
kMonth,
kQuarter,
kDayPeriod,
kCalendar,
kDateTimeField
};
......@@ -83,7 +80,6 @@ class DisplayNamesInternal {
virtual icu::Locale locale() const = 0;
virtual Maybe<icu::UnicodeString> of(Isolate* isolate,
const char* code) const = 0;
virtual const char* calendar() const { return nullptr; }
};
namespace {
......@@ -91,12 +87,15 @@ namespace {
class LocaleDisplayNamesCommon : public DisplayNamesInternal {
public:
LocaleDisplayNamesCommon(const icu::Locale& locale,
JSDisplayNames::Style style, bool fallback)
JSDisplayNames::Style style, bool fallback,
bool dialect)
: style_(style) {
UDisplayContext sub =
fallback ? UDISPCTX_SUBSTITUTE : UDISPCTX_NO_SUBSTITUTE;
UDisplayContext dialect_context =
dialect ? UDISPCTX_DIALECT_NAMES : UDISPCTX_STANDARD_NAMES;
UDisplayContext display_context[] = {ToUDisplayContext(style_),
UDISPCTX_DIALECT_NAMES,
dialect_context,
UDISPCTX_CAPITALIZATION_NONE, sub};
ldn_.reset(
icu::LocaleDisplayNames::createInstance(locale, display_context, 4));
......@@ -117,8 +116,8 @@ class LocaleDisplayNamesCommon : public DisplayNamesInternal {
class LanguageNames : public LocaleDisplayNamesCommon {
public:
LanguageNames(const icu::Locale& locale, JSDisplayNames::Style style,
bool fallback)
: LocaleDisplayNamesCommon(locale, style, fallback) {}
bool fallback, bool dialect)
: LocaleDisplayNamesCommon(locale, style, fallback, dialect) {}
~LanguageNames() override = default;
const char* type() const override { return "language"; }
Maybe<icu::UnicodeString> of(Isolate* isolate,
......@@ -151,8 +150,8 @@ class LanguageNames : public LocaleDisplayNamesCommon {
class RegionNames : public LocaleDisplayNamesCommon {
public:
RegionNames(const icu::Locale& locale, JSDisplayNames::Style style,
bool fallback)
: LocaleDisplayNamesCommon(locale, style, fallback) {}
bool fallback, bool dialect)
: LocaleDisplayNamesCommon(locale, style, fallback, dialect) {}
~RegionNames() override = default;
const char* type() const override { return "region"; }
Maybe<icu::UnicodeString> of(Isolate* isolate,
......@@ -173,8 +172,8 @@ class RegionNames : public LocaleDisplayNamesCommon {
class ScriptNames : public LocaleDisplayNamesCommon {
public:
ScriptNames(const icu::Locale& locale, JSDisplayNames::Style style,
bool fallback)
: LocaleDisplayNamesCommon(locale, style, fallback) {}
bool fallback, bool dialect)
: LocaleDisplayNamesCommon(locale, style, fallback, dialect) {}
~ScriptNames() override = default;
const char* type() const override { return "script"; }
Maybe<icu::UnicodeString> of(Isolate* isolate,
......@@ -192,13 +191,33 @@ class ScriptNames : public LocaleDisplayNamesCommon {
}
};
class CurrencyNames : public LocaleDisplayNamesCommon {
class KeyValueDisplayNames : public LocaleDisplayNamesCommon {
public:
KeyValueDisplayNames(const icu::Locale& locale, JSDisplayNames::Style style,
bool fallback, bool dialect, const char* key)
: LocaleDisplayNamesCommon(locale, style, fallback, dialect), key_(key) {}
~KeyValueDisplayNames() override = default;
const char* type() const override { return key_.c_str(); }
Maybe<icu::UnicodeString> of(Isolate* isolate,
const char* code) const override {
std::string code_str(code);
icu::UnicodeString result;
locale_display_names()->keyValueDisplayName(key_.c_str(), code_str.c_str(),
result);
return Just(result);
}
private:
std::string key_;
};
class CurrencyNames : public KeyValueDisplayNames {
public:
CurrencyNames(const icu::Locale& locale, JSDisplayNames::Style style,
bool fallback)
: LocaleDisplayNamesCommon(locale, style, fallback) {}
bool fallback, bool dialect)
: KeyValueDisplayNames(locale, style, fallback, dialect, "currency") {}
~CurrencyNames() override = default;
const char* type() const override { return "currency"; }
Maybe<icu::UnicodeString> of(Isolate* isolate,
const char* code) const override {
std::string code_str(code);
......@@ -207,12 +226,23 @@ class CurrencyNames : public LocaleDisplayNamesCommon {
isolate, NewRangeError(MessageTemplate::kInvalidArgument),
Nothing<icu::UnicodeString>());
}
return KeyValueDisplayNames::of(isolate, code);
}
};
icu::UnicodeString result;
locale_display_names()->keyValueDisplayName("currency", code_str.c_str(),
result);
return Just(result);
class CalendarNames : public KeyValueDisplayNames {
public:
CalendarNames(const icu::Locale& locale, JSDisplayNames::Style style,
bool fallback, bool dialect)
: KeyValueDisplayNames(locale, style, fallback, dialect, "calendar") {}
~CalendarNames() override = default;
Maybe<icu::UnicodeString> of(Isolate* isolate,
const char* code) const override {
return KeyValueDisplayNames::of(isolate, strcmp(code, "gregory") == 0
? "gregorian"
: strcmp(code, "ethioaa") == 0
? "ethiopic-amete-alem"
: code);
}
};
......@@ -263,13 +293,16 @@ UDateTimePatternField StringToUDateTimePatternField(const char* code) {
default:
break;
}
UNREACHABLE();
return UDATPG_FIELD_COUNT;
}
class DateTimeFieldNames : public DisplayNamesInternal {
public:
DateTimeFieldNames(const icu::Locale& locale, JSDisplayNames::Style style)
: locale_(locale), width_(StyleToUDateTimePGDisplayWidth(style)) {
DateTimeFieldNames(const icu::Locale& locale, JSDisplayNames::Style style,
bool fallback)
: locale_(locale),
width_(StyleToUDateTimePGDisplayWidth(style)),
fallback_(fallback) {
UErrorCode status = U_ZERO_ERROR;
generator_.reset(
icu::DateTimePatternGenerator::createInstance(locale_, status));
......@@ -282,6 +315,9 @@ class DateTimeFieldNames : public DisplayNamesInternal {
const char* code) const override {
UDateTimePatternField field = StringToUDateTimePatternField(code);
if (field == UDATPG_FIELD_COUNT) {
if (fallback_) {
return Just(icu::UnicodeString(code, -1, US_INV));
}
THROW_NEW_ERROR_RETURN_VALUE(
isolate, NewRangeError(MessageTemplate::kInvalidArgument),
Nothing<icu::UnicodeString>());
......@@ -293,196 +329,25 @@ class DateTimeFieldNames : public DisplayNamesInternal {
icu::Locale locale_;
UDateTimePGDisplayWidth width_;
std::unique_ptr<icu::DateTimePatternGenerator> generator_;
bool fallback_;
};
icu::DateFormatSymbols::DtWidthType StyleToDtWidthType(
JSDisplayNames::Style style, Type type) {
switch (style) {
case JSDisplayNames::Style::kLong:
return icu::DateFormatSymbols::WIDE;
case JSDisplayNames::Style::kShort:
return icu::DateFormatSymbols::SHORT;
case JSDisplayNames::Style::kNarrow:
if (type == Type::kQuarter) {
return icu::DateFormatSymbols::ABBREVIATED;
} else {
return icu::DateFormatSymbols::NARROW;
}
}
}
class DateFormatSymbolsNames : public DisplayNamesInternal {
public:
DateFormatSymbolsNames(const char* type, const icu::Locale& locale,
const icu::UnicodeString* array, int32_t length,
const char* calendar)
: type_(type),
locale_(locale),
array_(array),
length_(length),
calendar_(calendar) {}
~DateFormatSymbolsNames() override = default;
const char* type() const override { return type_; }
icu::Locale locale() const override { return locale_; }
const char* calendar() const override {
if (calendar_.empty()) {
return nullptr;
}
return calendar_.c_str();
}
virtual int32_t ComputeIndex(const char* code) const = 0;
Maybe<icu::UnicodeString> of(Isolate* isolate,
const char* code) const override {
int32_t index = ComputeIndex(code);
if (index < 0 || index >= length_) {
THROW_NEW_ERROR_RETURN_VALUE(
isolate, NewRangeError(MessageTemplate::kInvalidArgument),
Nothing<icu::UnicodeString>());
}
return Just(array_[index]);
}
private:
const char* type_;
icu::Locale locale_;
const icu::UnicodeString* array_;
int32_t length_;
std::string calendar_;
};
class WeekdayNames : public DateFormatSymbolsNames {
public:
WeekdayNames(const char* type, const icu::Locale& locale,
const icu::UnicodeString* array, int32_t length,
const char* calendar)
: DateFormatSymbolsNames(type, locale, array, length, calendar) {}
~WeekdayNames() override = default;
int32_t ComputeIndex(const char* code) const override {
int32_t i = atoi(code);
if (i == 7) return 1;
if (i > 0 && i < 7) return i + 1;
return -1;
}
};
class MonthNames : public DateFormatSymbolsNames {
public:
MonthNames(const char* type, const icu::Locale& locale,
const icu::UnicodeString* array, int32_t length,
const char* calendar)
: DateFormatSymbolsNames(type, locale, array, length, calendar) {}
~MonthNames() override = default;
int32_t ComputeIndex(const char* code) const override {
return atoi(code) - 1;
}
};
class QuarterNames : public DateFormatSymbolsNames {
public:
QuarterNames(const char* type, const icu::Locale& locale,
const icu::UnicodeString* array, int32_t length,
const char* calendar)
: DateFormatSymbolsNames(type, locale, array, length, calendar) {}
~QuarterNames() override = default;
int32_t ComputeIndex(const char* code) const override {
return atoi(code) - 1;
}
};
class DayPeriodNames : public DateFormatSymbolsNames {
public:
DayPeriodNames(const char* type, const icu::Locale& locale,
const icu::UnicodeString* array, int32_t length,
const char* calendar)
: DateFormatSymbolsNames(type, locale, array, length, calendar) {}
~DayPeriodNames() override = default;
int32_t ComputeIndex(const char* code) const override {
if (strcmp("am", code) == 0) {
return 0;
} else if (strcmp("pm", code) == 0) {
return 1;
} else {
return -1;
}
}
};
const char* gWeekday = "weekday";
const char* gMonth = "month";
const char* gQuarter = "quarter";
const char* gDayPeriod = "dayPeriod";
DateFormatSymbolsNames* CreateDateFormatSymbolsNames(
const icu::Locale& locale, JSDisplayNames::Style style, Type type) {
UErrorCode status = U_ZERO_ERROR;
std::unique_ptr<icu::DateFormatSymbols> symbols(
icu::DateFormatSymbols::createForLocale(locale, status));
if (U_FAILURE(status)) {
return nullptr;
}
icu::DateFormatSymbols::DtWidthType width_type =
StyleToDtWidthType(style, type);
int32_t count = 0;
std::string calendar =
locale.getUnicodeKeywordValue<std::string>("ca", status);
switch (type) {
case Type::kMonth:
return new MonthNames(
gMonth, locale,
symbols->getMonths(count, icu::DateFormatSymbols::STANDALONE,
width_type),
count, calendar.c_str());
case Type::kWeekday:
return new WeekdayNames(
gWeekday, locale,
symbols->getWeekdays(count, icu::DateFormatSymbols::STANDALONE,
width_type),
count, calendar.c_str());
case Type::kQuarter:
return new QuarterNames(
gQuarter, locale,
symbols->getQuarters(count, icu::DateFormatSymbols::STANDALONE,
width_type),
count, calendar.c_str());
case Type::kDayPeriod:
return new DayPeriodNames(gDayPeriod, locale,
symbols->getAmPmStrings(count), count,
calendar.c_str());
default:
UNREACHABLE();
}
}
DisplayNamesInternal* CreateInternal(const icu::Locale& locale,
JSDisplayNames::Style style, Type type,
bool fallback) {
bool fallback, bool dialect) {
switch (type) {
case Type::kLanguage:
return new LanguageNames(locale, style, fallback);
return new LanguageNames(locale, style, fallback, dialect);
case Type::kRegion:
return new RegionNames(locale, style, fallback);
return new RegionNames(locale, style, fallback, false);
case Type::kScript:
return new ScriptNames(locale, style, fallback);
return new ScriptNames(locale, style, fallback, false);
case Type::kCurrency:
return new CurrencyNames(locale, style, fallback);
return new CurrencyNames(locale, style, fallback, false);
case Type::kCalendar:
return new CalendarNames(locale, style, fallback, false);
case Type::kDateTimeField:
return new DateTimeFieldNames(locale, style);
case Type::kMonth:
case Type::kWeekday:
case Type::kQuarter:
case Type::kDayPeriod:
return CreateDateFormatSymbolsNames(locale, style, type);
return new DateTimeFieldNames(locale, style, fallback);
default:
UNREACHABLE();
}
......@@ -525,43 +390,15 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate,
// 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 = {};
// 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>());
// 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.
if (!Intl::IsWellFormedCalendar(calendar_str.get())) {
THROW_NEW_ERROR(
isolate,
NewRangeError(
MessageTemplate::kInvalid, factory->calendar_string(),
factory->NewStringFromAsciiChecked(calendar_str.get())),
JSDisplayNames);
}
}
}
// 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 = {};
// 9. Let r be ResolveLocale(%DisplayNames%.[[AvailableLocales]],
// requestedLocales, opt, %DisplayNames%.[[RelevantExtensionKeys]]).
Maybe<Intl::ResolvedLocale> maybe_resolve_locale = Intl::ResolveLocale(
isolate, JSDisplayNames::GetAvailableLocales(), requested_locales,
matcher,
FLAG_harmony_intl_displaynames_date_types ? relevant_extension_keys_ca
: relevant_extension_keys);
Maybe<Intl::ResolvedLocale> maybe_resolve_locale =
Intl::ResolveLocale(isolate, JSDisplayNames::GetAvailableLocales(),
requested_locales, matcher, relevant_extension_keys);
if (maybe_resolve_locale.IsNothing()) {
THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kIcuError),
JSDisplayNames);
......@@ -569,12 +406,6 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate,
Intl::ResolvedLocale r = maybe_resolve_locale.FromJust();
icu::Locale icu_locale = r.icu_locale;
UErrorCode status = U_ZERO_ERROR;
if (calendar_str != nullptr &&
Intl::IsValidCalendar(icu_locale, calendar_str.get())) {
icu_locale.setUnicodeKeywordValue("ca", calendar_str.get(), status);
DCHECK(U_SUCCESS(status));
}
// 10. Let s be ? GetOption(options, "style", "string",
// «"long", "short", "narrow"», "long").
......@@ -587,25 +418,16 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate,
// 11. Set displayNames.[[Style]] to style.
// 12. Let type be ? GetOption(options, "type", "string", « "language",
// "region", "script", "currency", "weekday", "month", "quarter",
// "dayPeriod", "dateTimeField" », undefined).
// "region", "script", "currency" , "calendar", "dateTimeField", "unit"»,
// undefined).
Maybe<Type> maybe_type =
FLAG_harmony_intl_displaynames_date_types
FLAG_harmony_intl_displaynames_v2
? Intl::GetStringOption<Type>(
isolate, options, "type", service,
{"language", "region", "script", "currency", "weekday", "month",
"quarter", "dayPeriod", "dateTimeField"},
{
Type::kLanguage,
Type::kRegion,
Type::kScript,
Type::kCurrency,
Type::kWeekday,
Type::kMonth,
Type::kQuarter,
Type::kDayPeriod,
Type::kDateTimeField,
},
{"language", "region", "script", "currency", "calendar",
"dateTimeField"},
{Type::kLanguage, Type::kRegion, Type::kScript, Type::kCurrency,
Type::kCalendar, Type::kDateTimeField},
Type::kUndefined)
: Intl::GetStringOption<Type>(
isolate, options, "type", service,
......@@ -638,11 +460,27 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate,
// 16. Set displayNames.[[Fallback]] to fallback.
// 17. Set displayNames.[[Locale]] to the value of r.[[Locale]].
LanguageDisplay language_display_enum = LanguageDisplay::kDialect;
if (FLAG_harmony_intl_displaynames_v2) {
// 24. Let languageDisplay be ? GetOption(options, "languageDisplay",
// "string", « "dialect", "standard" », "dialect").
Maybe<LanguageDisplay> maybe_language_display =
Intl::GetStringOption<LanguageDisplay>(
isolate, options, "languageDisplay", service,
{"dialect", "standard"},
{LanguageDisplay::kDialect, LanguageDisplay::kStandard},
LanguageDisplay::kDialect);
MAYBE_RETURN(maybe_language_display, MaybeHandle<JSDisplayNames>());
// 25. If type is "language", then
if (type_enum == Type::kLanguage) {
// a. Set displayNames.[[LanguageDisplay]] to languageDisplay.
language_display_enum = maybe_language_display.FromJust();
}
}
// Let calendar be r.[[ca]].
// Set displayNames.[[Fallback]] to fallback.
// Set displayNames.[[Calendar]] to calendar.
// 17. Set displayNames.[[Locale]] to the value of r.[[Locale]].
// Let dataLocale be r.[[dataLocale]].
......@@ -663,7 +501,8 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate,
// Set displayNames.[[Fields]] to styleFields.
DisplayNamesInternal* internal = CreateInternal(
icu_locale, style_enum, type_enum, fallback_enum == Fallback::kCode);
icu_locale, style_enum, type_enum, fallback_enum == Fallback::kCode,
language_display_enum == LanguageDisplay::kDialect);
if (internal == nullptr) {
THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kIcuError),
JSDisplayNames);
......@@ -677,6 +516,7 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate,
display_names->set_flags(0);
display_names->set_style(style_enum);
display_names->set_fallback(fallback_enum);
display_names->set_language_display(language_display_enum);
DisallowGarbageCollection no_gc;
display_names->set_internal(*managed_internal);
......@@ -701,19 +541,13 @@ Handle<JSObject> JSDisplayNames::ResolvedOptions(
Handle<String> style = display_names->StyleAsString();
Handle<String> type = factory->NewStringFromAsciiChecked(internal->type());
Handle<String> fallback = display_names->FallbackAsString();
Handle<String> language_display = display_names->LanguageDisplayAsString();
Maybe<bool> maybe_create_locale = JSReceiver::CreateDataProperty(
isolate, options, factory->locale_string(), locale, Just(kDontThrow));
DCHECK(maybe_create_locale.FromJust());
USE(maybe_create_locale);
if (internal->calendar() != nullptr) {
Maybe<bool> maybe_create_calendar = JSReceiver::CreateDataProperty(
isolate, options, factory->calendar_string(),
factory->NewStringFromAsciiChecked(internal->calendar()),
Just(kDontThrow));
DCHECK(maybe_create_calendar.FromJust());
USE(maybe_create_calendar);
}
Maybe<bool> maybe_create_style = JSReceiver::CreateDataProperty(
isolate, options, factory->style_string(), style, Just(kDontThrow));
DCHECK(maybe_create_style.FromJust());
......@@ -729,6 +563,17 @@ Handle<JSObject> JSDisplayNames::ResolvedOptions(
DCHECK(maybe_create_fallback.FromJust());
USE(maybe_create_fallback);
if (FLAG_harmony_intl_displaynames_v2) {
if (std::strcmp("language", internal->type()) == 0) {
Maybe<bool> maybe_create_language_display =
JSReceiver::CreateDataProperty(isolate, options,
factory->languageDisplay_string(),
language_display, Just(kDontThrow));
DCHECK(maybe_create_language_display.FromJust());
USE(maybe_create_language_display);
}
}
return options;
}
......@@ -787,5 +632,15 @@ Handle<String> JSDisplayNames::FallbackAsString() const {
UNREACHABLE();
}
Handle<String> JSDisplayNames::LanguageDisplayAsString() const {
switch (language_display()) {
case LanguageDisplay::kDialect:
return GetReadOnlyRoots().dialect_string_handle();
case LanguageDisplay::kStandard:
return GetReadOnlyRoots().standard_string_handle();
}
UNREACHABLE();
}
} // namespace internal
} // namespace v8
......@@ -46,6 +46,7 @@ class JSDisplayNames
Handle<String> StyleAsString() const;
Handle<String> FallbackAsString() const;
Handle<String> LanguageDisplayAsString() const;
// Style: identifying the display names style used.
//
......@@ -68,6 +69,13 @@ class JSDisplayNames
inline void set_fallback(Fallback fallback);
inline Fallback fallback() const;
enum class LanguageDisplay {
kDialect,
kStandard,
};
inline void set_language_display(LanguageDisplay language_display);
inline LanguageDisplay language_display() const;
// Bit positions in |flags|.
DEFINE_TORQUE_GENERATED_JS_DISPLAY_NAMES_FLAGS()
......@@ -76,6 +84,8 @@ class JSDisplayNames
STATIC_ASSERT(Style::kNarrow <= StyleBits::kMax);
STATIC_ASSERT(Fallback::kCode <= FallbackBit::kMax);
STATIC_ASSERT(Fallback::kNone <= FallbackBit::kMax);
STATIC_ASSERT(LanguageDisplay::kDialect <= LanguageDisplayBit::kMax);
STATIC_ASSERT(LanguageDisplay::kStandard <= LanguageDisplayBit::kMax);
DECL_ACCESSORS(internal, Managed<DisplayNamesInternal>)
......
......@@ -7,9 +7,12 @@
type JSDisplayNamesStyle extends int32 constexpr 'JSDisplayNames::Style';
type JSDisplayNamesFallback extends int32
constexpr 'JSDisplayNames::Fallback';
type JSDisplayNamesLanguageDisplay extends int32
constexpr 'JSDisplayNames::LanguageDisplay';
bitfield struct JSDisplayNamesFlags extends uint31 {
style: JSDisplayNamesStyle: 2 bit;
fallback: JSDisplayNamesFallback: 1 bit;
language_display: JSDisplayNamesLanguageDisplay: 1 bit;
}
@generateCppClass
......
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.islamic'
// Flags: --harmony_intl_displaynames_v2
const calendars = [
'buddhist', 'chinese', 'coptic', 'dangi', 'ethioaa', 'ethiopic-amete-alem',
'ethiopic', 'gregory', 'hebrew', 'indian', 'islamic', 'islamic-umalqura',
'islamic-tbla', 'islamic-civil', 'islamic-rgsa', 'iso8601', 'japanese',
'persian', 'roc'
];
let en = new Intl.DisplayNames("en", {type: 'calendar'});
let zh = new Intl.DisplayNames("zh", {type: 'calendar'});
calendars.forEach(function(calendar) {
assertFalse(en.of(calendar) == zh.of(calendar),
calendar + ":" + en.of(calendar) + " == " +
zh.of(calendar));
});
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony_intl_displaynames_v2
// Throws only once during construction.
// Check for all getters to prevent regression.
// Preserve the order of getter initialization.
let getCount = 0;
new Intl.DisplayNames(['en-US'], {
get localeMatcher() {
assertEquals(0, getCount++);
},
get style() {
assertEquals(1, getCount++);
},
get type() {
assertEquals(2, getCount++);
return 'language';
},
get fallback() {
assertEquals(3, getCount++);
},
get languageDisplay() {
assertEquals(4, getCount++);
},
});
assertEquals(5, getCount);
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony_intl_displaynames_v2
assertDoesNotThrow(
() => new Intl.DisplayNames(
'sr', {type: 'calendar'}));
assertDoesNotThrow(
() => new Intl.DisplayNames(
'sr', {type: 'dateTimeField'}));
assertDoesNotThrow(
() => new Intl.DisplayNames(
'sr', {type: 'language', languageDisplay: 'standard'}));
assertDoesNotThrow(
() => new Intl.DisplayNames(
'sr', {type: 'language', languageDisplay: 'dialect'}));
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony_intl_displaynames_v2
const dateTimeFields = [
'era', 'year', 'quarter', 'month', 'weekOfYear', 'weekday', 'day',
'dayPeriod', 'hour', 'minute', 'second', 'timeZoneName'
];
let en = new Intl.DisplayNames("en", {type: 'dateTimeField'});
let zh = new Intl.DisplayNames("zh", {type: 'dateTimeField'});
dateTimeFields.forEach(function(dateTimeField) {
assertFalse(en.of(dateTimeField) == zh.of(dateTimeField),
dateTimeField + ":" + en.of(dateTimeField) + " == " +
zh.of(dateTimeField));
});
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony_intl_displaynames_v2
let displayNames = new Intl.DisplayNames(undefined, {type: 'language'});
// The default languageDisplay is 'dialect' if type is 'language'
assertEquals('dialect', displayNames.resolvedOptions().languageDisplay);
['region', 'script', 'calendar', 'dateTimeField', 'currency'].forEach(
function(type) {
let dn = new Intl.DisplayNames(undefined, {type});
assertEquals(undefined, dn.resolvedOptions().languageDisplay);
});
const styles = ["long", "short", "narrow"];
const types = ["calendar", "dateTimeField"];
const fallbacks = ["code", "none"];
styles.forEach(function(style) {
types.forEach(function(type) {
assertEquals(style,
(new Intl.DisplayNames(['sr'], {style, type})).resolvedOptions().style);
assertEquals(type,
(new Intl.DisplayNames(['sr'], {style, type})).resolvedOptions().type);
assertEquals(fallbacks[0],
(new Intl.DisplayNames(
['sr'], {style, type})).resolvedOptions().fallback);
fallbacks.forEach(function(fallback) {
assertEquals(style,
(new Intl.DisplayNames(
['sr'], {style, type, fallback})).resolvedOptions().style);
assertEquals(type,
(new Intl.DisplayNames(
['sr'], {style, type, fallback})).resolvedOptions().type);
assertEquals(fallback,
(new Intl.DisplayNames(
['sr'], {style, type, fallback})).resolvedOptions().fallback);
});
});
});
const languageDisplays = ["dialect", "standard"];
styles.forEach(function(style) {
let type = 'language';
languageDisplays.forEach(function(languageDisplay) {
assertEquals(style,
(new Intl.DisplayNames(['sr'], {style, type, languageDisplay}))
.resolvedOptions().style);
assertEquals(type,
(new Intl.DisplayNames(['sr'], {style, type, languageDisplay}))
.resolvedOptions().type);
assertEquals(languageDisplay,
(new Intl.DisplayNames(['sr'], {style, type, languageDisplay}))
.resolvedOptions().languageDisplay);
});
});
......@@ -329,66 +329,66 @@ KNOWN_MAPS = {
("read_only_space", 0x03215): (67, "BasicBlockCountersMarkerMap"),
("read_only_space", 0x03259): (91, "ArrayBoilerplateDescriptionMap"),
("read_only_space", 0x03359): (104, "InterceptorInfoMap"),
("read_only_space", 0x05661): (76, "PromiseFulfillReactionJobTaskMap"),
("read_only_space", 0x05689): (77, "PromiseRejectReactionJobTaskMap"),
("read_only_space", 0x056b1): (78, "CallableTaskMap"),
("read_only_space", 0x056d9): (79, "CallbackTaskMap"),
("read_only_space", 0x05701): (80, "PromiseResolveThenableJobTaskMap"),
("read_only_space", 0x05729): (83, "FunctionTemplateInfoMap"),
("read_only_space", 0x05751): (84, "ObjectTemplateInfoMap"),
("read_only_space", 0x05779): (85, "AccessCheckInfoMap"),
("read_only_space", 0x057a1): (86, "AccessorInfoMap"),
("read_only_space", 0x057c9): (87, "AccessorPairMap"),
("read_only_space", 0x057f1): (88, "AliasedArgumentsEntryMap"),
("read_only_space", 0x05819): (89, "AllocationMementoMap"),
("read_only_space", 0x05841): (92, "AsmWasmDataMap"),
("read_only_space", 0x05869): (93, "AsyncGeneratorRequestMap"),
("read_only_space", 0x05891): (94, "BaselineDataMap"),
("read_only_space", 0x058b9): (95, "BreakPointMap"),
("read_only_space", 0x058e1): (96, "BreakPointInfoMap"),
("read_only_space", 0x05909): (97, "CachedTemplateObjectMap"),
("read_only_space", 0x05931): (99, "ClassPositionsMap"),
("read_only_space", 0x05959): (100, "DebugInfoMap"),
("read_only_space", 0x05981): (103, "FunctionTemplateRareDataMap"),
("read_only_space", 0x059a9): (105, "InterpreterDataMap"),
("read_only_space", 0x059d1): (106, "ModuleRequestMap"),
("read_only_space", 0x059f9): (107, "PromiseCapabilityMap"),
("read_only_space", 0x05a21): (108, "PromiseReactionMap"),
("read_only_space", 0x05a49): (109, "PropertyDescriptorObjectMap"),
("read_only_space", 0x05a71): (110, "PrototypeInfoMap"),
("read_only_space", 0x05a99): (111, "RegExpBoilerplateDescriptionMap"),
("read_only_space", 0x05ac1): (112, "ScriptMap"),
("read_only_space", 0x05ae9): (113, "SourceTextModuleInfoEntryMap"),
("read_only_space", 0x05b11): (114, "StackFrameInfoMap"),
("read_only_space", 0x05b39): (115, "TemplateObjectDescriptionMap"),
("read_only_space", 0x05b61): (116, "Tuple2Map"),
("read_only_space", 0x05b89): (117, "WasmExceptionTagMap"),
("read_only_space", 0x05bb1): (118, "WasmIndirectFunctionTableMap"),
("read_only_space", 0x05bd9): (136, "SloppyArgumentsElementsMap"),
("read_only_space", 0x05c01): (153, "DescriptorArrayMap"),
("read_only_space", 0x05c29): (158, "UncompiledDataWithoutPreparseDataMap"),
("read_only_space", 0x05c51): (157, "UncompiledDataWithPreparseDataMap"),
("read_only_space", 0x05c79): (174, "OnHeapBasicBlockProfilerDataMap"),
("read_only_space", 0x05ca1): (170, "InternalClassMap"),
("read_only_space", 0x05cc9): (181, "SmiPairMap"),
("read_only_space", 0x05cf1): (180, "SmiBoxMap"),
("read_only_space", 0x05d19): (147, "ExportedSubClassBaseMap"),
("read_only_space", 0x05d41): (148, "ExportedSubClassMap"),
("read_only_space", 0x05d69): (68, "AbstractInternalClassSubclass1Map"),
("read_only_space", 0x05d91): (69, "AbstractInternalClassSubclass2Map"),
("read_only_space", 0x05db9): (135, "InternalClassWithSmiElementsMap"),
("read_only_space", 0x05de1): (171, "InternalClassWithStructElementsMap"),
("read_only_space", 0x05e09): (149, "ExportedSubClass2Map"),
("read_only_space", 0x05e31): (182, "SortStateMap"),
("read_only_space", 0x05e59): (90, "AllocationSiteWithWeakNextMap"),
("read_only_space", 0x05e81): (90, "AllocationSiteWithoutWeakNextMap"),
("read_only_space", 0x05ea9): (81, "LoadHandler1Map"),
("read_only_space", 0x05ed1): (81, "LoadHandler2Map"),
("read_only_space", 0x05ef9): (81, "LoadHandler3Map"),
("read_only_space", 0x05f21): (82, "StoreHandler0Map"),
("read_only_space", 0x05f49): (82, "StoreHandler1Map"),
("read_only_space", 0x05f71): (82, "StoreHandler2Map"),
("read_only_space", 0x05f99): (82, "StoreHandler3Map"),
("read_only_space", 0x05691): (76, "PromiseFulfillReactionJobTaskMap"),
("read_only_space", 0x056b9): (77, "PromiseRejectReactionJobTaskMap"),
("read_only_space", 0x056e1): (78, "CallableTaskMap"),
("read_only_space", 0x05709): (79, "CallbackTaskMap"),
("read_only_space", 0x05731): (80, "PromiseResolveThenableJobTaskMap"),
("read_only_space", 0x05759): (83, "FunctionTemplateInfoMap"),
("read_only_space", 0x05781): (84, "ObjectTemplateInfoMap"),
("read_only_space", 0x057a9): (85, "AccessCheckInfoMap"),
("read_only_space", 0x057d1): (86, "AccessorInfoMap"),
("read_only_space", 0x057f9): (87, "AccessorPairMap"),
("read_only_space", 0x05821): (88, "AliasedArgumentsEntryMap"),
("read_only_space", 0x05849): (89, "AllocationMementoMap"),
("read_only_space", 0x05871): (92, "AsmWasmDataMap"),
("read_only_space", 0x05899): (93, "AsyncGeneratorRequestMap"),
("read_only_space", 0x058c1): (94, "BaselineDataMap"),
("read_only_space", 0x058e9): (95, "BreakPointMap"),
("read_only_space", 0x05911): (96, "BreakPointInfoMap"),
("read_only_space", 0x05939): (97, "CachedTemplateObjectMap"),
("read_only_space", 0x05961): (99, "ClassPositionsMap"),
("read_only_space", 0x05989): (100, "DebugInfoMap"),
("read_only_space", 0x059b1): (103, "FunctionTemplateRareDataMap"),
("read_only_space", 0x059d9): (105, "InterpreterDataMap"),
("read_only_space", 0x05a01): (106, "ModuleRequestMap"),
("read_only_space", 0x05a29): (107, "PromiseCapabilityMap"),
("read_only_space", 0x05a51): (108, "PromiseReactionMap"),
("read_only_space", 0x05a79): (109, "PropertyDescriptorObjectMap"),
("read_only_space", 0x05aa1): (110, "PrototypeInfoMap"),
("read_only_space", 0x05ac9): (111, "RegExpBoilerplateDescriptionMap"),
("read_only_space", 0x05af1): (112, "ScriptMap"),
("read_only_space", 0x05b19): (113, "SourceTextModuleInfoEntryMap"),
("read_only_space", 0x05b41): (114, "StackFrameInfoMap"),
("read_only_space", 0x05b69): (115, "TemplateObjectDescriptionMap"),
("read_only_space", 0x05b91): (116, "Tuple2Map"),
("read_only_space", 0x05bb9): (117, "WasmExceptionTagMap"),
("read_only_space", 0x05be1): (118, "WasmIndirectFunctionTableMap"),
("read_only_space", 0x05c09): (136, "SloppyArgumentsElementsMap"),
("read_only_space", 0x05c31): (153, "DescriptorArrayMap"),
("read_only_space", 0x05c59): (158, "UncompiledDataWithoutPreparseDataMap"),
("read_only_space", 0x05c81): (157, "UncompiledDataWithPreparseDataMap"),
("read_only_space", 0x05ca9): (174, "OnHeapBasicBlockProfilerDataMap"),
("read_only_space", 0x05cd1): (170, "InternalClassMap"),
("read_only_space", 0x05cf9): (181, "SmiPairMap"),
("read_only_space", 0x05d21): (180, "SmiBoxMap"),
("read_only_space", 0x05d49): (147, "ExportedSubClassBaseMap"),
("read_only_space", 0x05d71): (148, "ExportedSubClassMap"),
("read_only_space", 0x05d99): (68, "AbstractInternalClassSubclass1Map"),
("read_only_space", 0x05dc1): (69, "AbstractInternalClassSubclass2Map"),
("read_only_space", 0x05de9): (135, "InternalClassWithSmiElementsMap"),
("read_only_space", 0x05e11): (171, "InternalClassWithStructElementsMap"),
("read_only_space", 0x05e39): (149, "ExportedSubClass2Map"),
("read_only_space", 0x05e61): (182, "SortStateMap"),
("read_only_space", 0x05e89): (90, "AllocationSiteWithWeakNextMap"),
("read_only_space", 0x05eb1): (90, "AllocationSiteWithoutWeakNextMap"),
("read_only_space", 0x05ed9): (81, "LoadHandler1Map"),
("read_only_space", 0x05f01): (81, "LoadHandler2Map"),
("read_only_space", 0x05f29): (81, "LoadHandler3Map"),
("read_only_space", 0x05f51): (82, "StoreHandler0Map"),
("read_only_space", 0x05f79): (82, "StoreHandler1Map"),
("read_only_space", 0x05fa1): (82, "StoreHandler2Map"),
("read_only_space", 0x05fc9): (82, "StoreHandler3Map"),
("map_space", 0x02119): (1057, "ExternalMap"),
("map_space", 0x02141): (1098, "JSMessageObjectMap"),
}
......
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