summaryrefslogtreecommitdiff
path: root/deps/v8/src/objects/js-relative-time-format.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/objects/js-relative-time-format.cc')
-rw-r--r--deps/v8/src/objects/js-relative-time-format.cc126
1 files changed, 80 insertions, 46 deletions
diff --git a/deps/v8/src/objects/js-relative-time-format.cc b/deps/v8/src/objects/js-relative-time-format.cc
index 8768560c39..0cb6b117df 100644
--- a/deps/v8/src/objects/js-relative-time-format.cc
+++ b/deps/v8/src/objects/js-relative-time-format.cc
@@ -25,33 +25,42 @@ namespace v8 {
namespace internal {
namespace {
-UDateRelativeDateTimeFormatterStyle getIcuStyle(
- JSRelativeTimeFormat::Style style) {
+// Style: identifying the relative time format style used.
+//
+// ecma402/#sec-properties-of-intl-relativetimeformat-instances
+
+enum class Style {
+ LONG, // Everything spelled out.
+ SHORT, // Abbreviations used when possible.
+ NARROW // Use the shortest possible form.
+};
+
+UDateRelativeDateTimeFormatterStyle toIcuStyle(Style style) {
switch (style) {
- case JSRelativeTimeFormat::Style::LONG:
+ case Style::LONG:
return UDAT_STYLE_LONG;
- case JSRelativeTimeFormat::Style::SHORT:
+ case Style::SHORT:
return UDAT_STYLE_SHORT;
- case JSRelativeTimeFormat::Style::NARROW:
+ case Style::NARROW:
return UDAT_STYLE_NARROW;
}
UNREACHABLE();
}
-} // namespace
-
-JSRelativeTimeFormat::Style JSRelativeTimeFormat::getStyle(const char* str) {
- if (strcmp(str, "long") == 0) return JSRelativeTimeFormat::Style::LONG;
- if (strcmp(str, "short") == 0) return JSRelativeTimeFormat::Style::SHORT;
- if (strcmp(str, "narrow") == 0) return JSRelativeTimeFormat::Style::NARROW;
- UNREACHABLE();
-}
-JSRelativeTimeFormat::Numeric JSRelativeTimeFormat::getNumeric(
- const char* str) {
- if (strcmp(str, "auto") == 0) return JSRelativeTimeFormat::Numeric::AUTO;
- if (strcmp(str, "always") == 0) return JSRelativeTimeFormat::Numeric::ALWAYS;
+Style fromIcuStyle(UDateRelativeDateTimeFormatterStyle icu_style) {
+ switch (icu_style) {
+ case UDAT_STYLE_LONG:
+ return Style::LONG;
+ case UDAT_STYLE_SHORT:
+ return Style::SHORT;
+ case UDAT_STYLE_NARROW:
+ return Style::NARROW;
+ case UDAT_STYLE_COUNT:
+ UNREACHABLE();
+ }
UNREACHABLE();
}
+} // namespace
MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::New(
Isolate* isolate, Handle<Map> map, Handle<Object> locales,
@@ -103,9 +112,14 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::New(
// ResolveLocale(%RelativeTimeFormat%.[[AvailableLocales]],
// requestedLocales, opt,
// %RelativeTimeFormat%.[[RelevantExtensionKeys]], localeData).
- Intl::ResolvedLocale r =
+ Maybe<Intl::ResolvedLocale> maybe_resolve_locale =
Intl::ResolveLocale(isolate, JSRelativeTimeFormat::GetAvailableLocales(),
requested_locales, matcher, {"nu"});
+ if (maybe_resolve_locale.IsNothing()) {
+ THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kIcuError),
+ JSRelativeTimeFormat);
+ }
+ Intl::ResolvedLocale r = maybe_resolve_locale.FromJust();
UErrorCode status = U_ZERO_ERROR;
@@ -132,10 +146,6 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::New(
icu_locale.setUnicodeKeywordValue("nu", numbering_system_str.get(), status);
CHECK(U_SUCCESS(status));
}
- Handle<String> numbering_system_string =
- isolate->factory()->NewStringFromAsciiChecked(
- Intl::GetNumberingSystem(icu_locale).c_str());
-
// 15. Let dataLocale be r.[[DataLocale]].
// 16. Let s be ? GetOption(options, "style", "string",
@@ -164,25 +174,41 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::New(
icu::NumberFormat* number_format =
icu::NumberFormat::createInstance(icu_locale, UNUM_DECIMAL, status);
if (U_FAILURE(status)) {
- delete number_format;
- FATAL("Failed to create ICU number format, are ICU data files missing?");
+ // Data build filter files excluded data in "rbnf_tree" since ECMA402 does
+ // not support "algorithmic" numbering systems. Therefore we may get the
+ // U_MISSING_RESOURCE_ERROR here. Fallback to locale without the numbering
+ // system and create the object again.
+ if (status == U_MISSING_RESOURCE_ERROR) {
+ delete number_format;
+ status = U_ZERO_ERROR;
+ icu_locale.setUnicodeKeywordValue("nu", nullptr, status);
+ CHECK(U_SUCCESS(status));
+ number_format =
+ icu::NumberFormat::createInstance(icu_locale, UNUM_DECIMAL, status);
+ }
+ if (U_FAILURE(status) || number_format == nullptr) {
+ delete number_format;
+ THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kIcuError),
+ JSRelativeTimeFormat);
+ }
}
- CHECK_NOT_NULL(number_format);
// Change UDISPCTX_CAPITALIZATION_NONE to other values if
// ECMA402 later include option to change capitalization.
// Ref: https://github.com/tc39/proposal-intl-relative-time/issues/11
icu::RelativeDateTimeFormatter* icu_formatter =
new icu::RelativeDateTimeFormatter(icu_locale, number_format,
- getIcuStyle(style_enum),
+ toIcuStyle(style_enum),
UDISPCTX_CAPITALIZATION_NONE, status);
- if (U_FAILURE(status)) {
+ if (U_FAILURE(status) || icu_formatter == nullptr) {
delete icu_formatter;
- FATAL(
- "Failed to create ICU relative date time formatter, are ICU data files "
- "missing?");
+ THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kIcuError),
+ JSRelativeTimeFormat);
}
- CHECK_NOT_NULL(icu_formatter);
+
+ Handle<String> numbering_system_string =
+ isolate->factory()->NewStringFromAsciiChecked(
+ Intl::GetNumberingSystem(icu_locale).c_str());
Handle<Managed<icu::RelativeDateTimeFormatter>> managed_formatter =
Managed<icu::RelativeDateTimeFormatter>::FromRawPtr(isolate, 0,
@@ -191,11 +217,11 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::New(
Handle<JSRelativeTimeFormat> relative_time_format_holder =
Handle<JSRelativeTimeFormat>::cast(
isolate->factory()->NewFastOrSlowJSObjectFromMap(map));
+
DisallowHeapAllocation no_gc;
relative_time_format_holder->set_flags(0);
relative_time_format_holder->set_locale(*locale_str);
relative_time_format_holder->set_numberingSystem(*numbering_system_string);
- relative_time_format_holder->set_style(style_enum);
relative_time_format_holder->set_numeric(numeric_enum);
relative_time_format_holder->set_icu_formatter(*managed_formatter);
@@ -203,16 +229,36 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::New(
return relative_time_format_holder;
}
+namespace {
+
+Handle<String> StyleAsString(Isolate* isolate, Style style) {
+ switch (style) {
+ case Style::LONG:
+ return ReadOnlyRoots(isolate).long_string_handle();
+ case Style::SHORT:
+ return ReadOnlyRoots(isolate).short_string_handle();
+ case Style::NARROW:
+ return ReadOnlyRoots(isolate).narrow_string_handle();
+ }
+ UNREACHABLE();
+}
+
+} // namespace
+
Handle<JSObject> JSRelativeTimeFormat::ResolvedOptions(
Isolate* isolate, Handle<JSRelativeTimeFormat> format_holder) {
Factory* factory = isolate->factory();
+ icu::RelativeDateTimeFormatter* formatter =
+ format_holder->icu_formatter().raw();
+ CHECK_NOT_NULL(formatter);
Handle<JSObject> result = factory->NewJSObject(isolate->object_function());
Handle<String> locale(format_holder->locale(), isolate);
Handle<String> numberingSystem(format_holder->numberingSystem(), isolate);
JSObject::AddProperty(isolate, result, factory->locale_string(), locale,
NONE);
- JSObject::AddProperty(isolate, result, factory->style_string(),
- format_holder->StyleAsString(), NONE);
+ JSObject::AddProperty(
+ isolate, result, factory->style_string(),
+ StyleAsString(isolate, fromIcuStyle(formatter->getFormatStyle())), NONE);
JSObject::AddProperty(isolate, result, factory->numeric_string(),
format_holder->NumericAsString(), NONE);
JSObject::AddProperty(isolate, result, factory->numberingSystem_string(),
@@ -220,18 +266,6 @@ Handle<JSObject> JSRelativeTimeFormat::ResolvedOptions(
return result;
}
-Handle<String> JSRelativeTimeFormat::StyleAsString() const {
- switch (style()) {
- case Style::LONG:
- return GetReadOnlyRoots().long_string_handle();
- case Style::SHORT:
- return GetReadOnlyRoots().short_string_handle();
- case Style::NARROW:
- return GetReadOnlyRoots().narrow_string_handle();
- }
- UNREACHABLE();
-}
-
Handle<String> JSRelativeTimeFormat::NumericAsString() const {
switch (numeric()) {
case Numeric::ALWAYS: