aboutsummaryrefslogtreecommitdiff
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.cc183
1 files changed, 94 insertions, 89 deletions
diff --git a/deps/v8/src/objects/js-relative-time-format.cc b/deps/v8/src/objects/js-relative-time-format.cc
index b3aa996d64..29896a926e 100644
--- a/deps/v8/src/objects/js-relative-time-format.cc
+++ b/deps/v8/src/objects/js-relative-time-format.cc
@@ -16,10 +16,11 @@
#include "src/isolate.h"
#include "src/objects-inl.h"
#include "src/objects/intl-objects.h"
+#include "src/objects/js-number-format.h"
#include "src/objects/js-relative-time-format-inl.h"
+#include "unicode/datefmt.h"
#include "unicode/numfmt.h"
#include "unicode/reldatefmt.h"
-#include "unicode/uvernum.h" // for U_ICU_VERSION_MAJOR_NUM
namespace v8 {
namespace internal {
@@ -56,81 +57,81 @@ JSRelativeTimeFormat::Numeric JSRelativeTimeFormat::getNumeric(
MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::Initialize(
Isolate* isolate, Handle<JSRelativeTimeFormat> relative_time_format_holder,
- Handle<Object> input_locales, Handle<Object> input_options) {
- Factory* factory = isolate->factory();
+ Handle<Object> locales, Handle<Object> input_options) {
relative_time_format_holder->set_flags(0);
- // 4. If options is undefined, then
+
+ // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
+ Maybe<std::vector<std::string>> maybe_requested_locales =
+ Intl::CanonicalizeLocaleList(isolate, locales);
+ MAYBE_RETURN(maybe_requested_locales, Handle<JSRelativeTimeFormat>());
+ std::vector<std::string> requested_locales =
+ maybe_requested_locales.FromJust();
+
+ // 2. If options is undefined, then
Handle<JSReceiver> options;
if (input_options->IsUndefined(isolate)) {
- // a. Let options be ObjectCreate(null).
+ // 2. a. Let options be ObjectCreate(null).
options = isolate->factory()->NewJSObjectWithNullProto();
- // 5. Else
+ // 3. Else
} else {
- // a. Let options be ? ToObject(options).
+ // 3. a. Let options be ? ToObject(options).
ASSIGN_RETURN_ON_EXCEPTION(isolate, options,
Object::ToObject(isolate, input_options),
JSRelativeTimeFormat);
}
- // 10. Let r be ResolveLocale(%RelativeTimeFormat%.[[AvailableLocales]],
- // requestedLocales, opt,
- // %RelativeTimeFormat%.[[RelevantExtensionKeys]],
- // localeData).
- Handle<JSObject> r;
- ASSIGN_RETURN_ON_EXCEPTION(isolate, r,
- Intl::ResolveLocale(isolate, "relativetimeformat",
- input_locales, options),
- JSRelativeTimeFormat);
- Handle<Object> locale_obj =
- JSObject::GetDataProperty(r, factory->locale_string());
- Handle<String> locale;
- ASSIGN_RETURN_ON_EXCEPTION(isolate, locale,
- Object::ToString(isolate, locale_obj),
- JSRelativeTimeFormat);
-
- // 11. Let locale be r.[[Locale]].
- // 12. Set relativeTimeFormat.[[Locale]] to locale.
- relative_time_format_holder->set_locale(*locale);
-
- // 14. Let s be ? GetOption(options, "style", "string",
+ // 4. Let opt be a new Record.
+ // 5. Let matcher be ? GetOption(options, "localeMatcher", "string", «
+ // "lookup", "best fit" », "best fit").
+ // 6. Set opt.[[localeMatcher]] to matcher.
+ Maybe<Intl::MatcherOption> maybe_locale_matcher =
+ Intl::GetLocaleMatcher(isolate, options, "Intl.RelativeTimeFormat");
+ MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSRelativeTimeFormat>());
+ Intl::MatcherOption matcher = maybe_locale_matcher.FromJust();
+
+ // 7. Let localeData be %RelativeTimeFormat%.[[LocaleData]].
+ // 8. Let r be
+ // ResolveLocale(%RelativeTimeFormat%.[[AvailableLocales]],
+ // requestedLocales, opt,
+ // %RelativeTimeFormat%.[[RelevantExtensionKeys]], localeData).
+ Intl::ResolvedLocale r =
+ Intl::ResolveLocale(isolate, JSRelativeTimeFormat::GetAvailableLocales(),
+ requested_locales, matcher, {"nu"});
+
+ // 9. Let locale be r.[[Locale]].
+ // 10. Set relativeTimeFormat.[[Locale]] to locale.
+ // 11. Let dataLocale be r.[[DataLocale]].
+ Handle<String> locale_str =
+ isolate->factory()->NewStringFromAsciiChecked(r.locale.c_str());
+ relative_time_format_holder->set_locale(*locale_str);
+
+ // 12. Let s be ? GetOption(options, "style", "string",
// «"long", "short", "narrow"», "long").
- std::unique_ptr<char[]> style_str = nullptr;
- std::vector<const char*> style_values = {"long", "short", "narrow"};
- Maybe<bool> maybe_found_style =
- Intl::GetStringOption(isolate, options, "style", style_values,
- "Intl.RelativeTimeFormat", &style_str);
- Style style_enum = Style::LONG;
- MAYBE_RETURN(maybe_found_style, MaybeHandle<JSRelativeTimeFormat>());
- if (maybe_found_style.FromJust()) {
- DCHECK_NOT_NULL(style_str.get());
- style_enum = getStyle(style_str.get());
- }
-
- // 15. Set relativeTimeFormat.[[Style]] to s.
+ Maybe<Style> maybe_style = Intl::GetStringOption<Style>(
+ isolate, options, "style", "Intl.RelativeTimeFormat",
+ {"long", "short", "narrow"}, {Style::LONG, Style::SHORT, Style::NARROW},
+ Style::LONG);
+ MAYBE_RETURN(maybe_style, MaybeHandle<JSRelativeTimeFormat>());
+ Style style_enum = maybe_style.FromJust();
+
+ // 13. Set relativeTimeFormat.[[Style]] to s.
relative_time_format_holder->set_style(style_enum);
- // 16. Let numeric be ? GetOption(options, "numeric", "string",
+ // 14. Let numeric be ? GetOption(options, "numeric", "string",
// «"always", "auto"», "always").
- std::unique_ptr<char[]> numeric_str = nullptr;
- std::vector<const char*> numeric_values = {"always", "auto"};
- Maybe<bool> maybe_found_numeric =
- Intl::GetStringOption(isolate, options, "numeric", numeric_values,
- "Intl.RelativeTimeFormat", &numeric_str);
- Numeric numeric_enum = Numeric::ALWAYS;
- MAYBE_RETURN(maybe_found_numeric, MaybeHandle<JSRelativeTimeFormat>());
- if (maybe_found_numeric.FromJust()) {
- DCHECK_NOT_NULL(numeric_str.get());
- numeric_enum = getNumeric(numeric_str.get());
- }
+ Maybe<Numeric> maybe_numeric = Intl::GetStringOption<Numeric>(
+ isolate, options, "numeric", "Intl.RelativeTimeFormat",
+ {"always", "auto"}, {Numeric::ALWAYS, Numeric::AUTO}, Numeric::ALWAYS);
+ MAYBE_RETURN(maybe_numeric, MaybeHandle<JSRelativeTimeFormat>());
+ Numeric numeric_enum = maybe_numeric.FromJust();
- // 17. Set relativeTimeFormat.[[Numeric]] to numeric.
+ // 15. Set relativeTimeFormat.[[Numeric]] to numeric.
relative_time_format_holder->set_numeric(numeric_enum);
- std::unique_ptr<char[]> locale_name = locale->ToCString();
- icu::Locale icu_locale(locale_name.get());
+ icu::Locale icu_locale = r.icu_locale;
UErrorCode status = U_ZERO_ERROR;
- // 25. Let relativeTimeFormat.[[NumberFormat]] be
+ // 19. Let relativeTimeFormat.[[NumberFormat]] be
// ? Construct(%NumberFormat%, « nfLocale, nfOptions »).
icu::NumberFormat* number_format =
icu::NumberFormat::createInstance(icu_locale, UNUM_DECIMAL, status);
@@ -159,9 +160,10 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::Initialize(
Managed<icu::RelativeDateTimeFormatter>::FromRawPtr(isolate, 0,
icu_formatter);
- // 30. Set relativeTimeFormat.[[InitializedRelativeTimeFormat]] to true.
+ // 21. Set relativeTimeFormat.[[InitializedRelativeTimeFormat]] to true.
relative_time_format_holder->set_icu_formatter(*managed_formatter);
- // 31. Return relativeTimeFormat.
+
+ // 22. Return relativeTimeFormat.
return relative_time_format_holder;
}
@@ -176,6 +178,12 @@ Handle<JSObject> JSRelativeTimeFormat::ResolvedOptions(
format_holder->StyleAsString(), NONE);
JSObject::AddProperty(isolate, result, factory->numeric_string(),
format_holder->NumericAsString(), NONE);
+ std::string locale_str(format_holder->locale()->ToCString().get());
+ icu::Locale icu_locale = Intl::CreateICULocale(locale_str);
+ std::string numbering_system = Intl::GetNumberingSystem(icu_locale);
+ JSObject::AddProperty(
+ isolate, result, factory->numberingSystem_string(),
+ factory->NewStringFromAsciiChecked(numbering_system.c_str()), NONE);
return result;
}
@@ -231,7 +239,8 @@ Handle<String> UnitAsString(Isolate* isolate, URelativeDateTimeUnit unit_enum) {
MaybeHandle<JSArray> GenerateRelativeTimeFormatParts(
Isolate* isolate, const icu::UnicodeString& formatted,
- const icu::UnicodeString& integer_part, URelativeDateTimeUnit unit_enum) {
+ const icu::UnicodeString& integer_part, URelativeDateTimeUnit unit_enum,
+ double number, const icu::NumberFormat& nf) {
Factory* factory = isolate->factory();
Handle<JSArray> array = factory->NewJSArray(0);
int32_t found = formatted.indexOf(integer_part);
@@ -262,18 +271,12 @@ MaybeHandle<JSArray> GenerateRelativeTimeFormatParts(
substring);
}
- // array.push({
- // 'type': 'integer',
- // 'value': formatted.substring(found, found + integer_part.length),
- // 'unit': unit})
- ASSIGN_RETURN_ON_EXCEPTION(isolate, substring,
- Intl::ToString(isolate, formatted, found,
- found + integer_part.length()),
- JSArray);
Handle<String> unit = UnitAsString(isolate, unit_enum);
- Intl::AddElement(isolate, array, index++,
- factory->integer_string(), // field_type_string
- substring, factory->unit_string(), unit);
+
+ Maybe<int> maybe_format_to_parts =
+ JSNumberFormat::FormatToParts(isolate, array, index, nf, number, unit);
+ MAYBE_RETURN(maybe_format_to_parts, Handle<JSArray>());
+ index = maybe_format_to_parts.FromJust();
// array.push({
// 'type': 'literal',
@@ -370,38 +373,33 @@ MaybeHandle<Object> JSRelativeTimeFormat::Format(
UErrorCode status = U_ZERO_ERROR;
icu::UnicodeString formatted;
-#if USE_CHROMIUM_ICU != 1 && U_ICU_VERSION_MAJOR_NUM < 63
- if (unit_enum != UDAT_REL_UNIT_QUARTER) { // ICU did not implement
- // UDAT_REL_UNIT_QUARTER < 63
-#endif // USE_CHROMIUM_ICU != 1 && U_ICU_VERSION_MAJOR_NUM < 63
- if (format_holder->numeric() == JSRelativeTimeFormat::Numeric::ALWAYS) {
- formatter->formatNumeric(number, unit_enum, formatted, status);
- } else {
- DCHECK_EQ(JSRelativeTimeFormat::Numeric::AUTO, format_holder->numeric());
- formatter->format(number, unit_enum, formatted, status);
- }
-#if USE_CHROMIUM_ICU != 1 && U_ICU_VERSION_MAJOR_NUM < 63
+ if (format_holder->numeric() == JSRelativeTimeFormat::Numeric::ALWAYS) {
+ formatter->formatNumeric(number, unit_enum, formatted, status);
+ } else {
+ DCHECK_EQ(JSRelativeTimeFormat::Numeric::AUTO, format_holder->numeric());
+ formatter->format(number, unit_enum, formatted, status);
}
-#endif // USE_CHROMIUM_ICU != 1 && U_ICU_VERSION_MAJOR_NUM < 63
if (U_FAILURE(status)) {
THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kIcuError), Object);
}
if (to_parts) {
- icu::UnicodeString integer;
+ icu::UnicodeString number_str;
icu::FieldPosition pos;
- formatter->getNumberFormat().format(std::abs(number), integer, pos, status);
+ double abs_number = std::abs(number);
+ formatter->getNumberFormat().format(abs_number, number_str, pos, status);
if (U_FAILURE(status)) {
THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kIcuError),
Object);
}
Handle<JSArray> elements;
- ASSIGN_RETURN_ON_EXCEPTION(
- isolate, elements,
- GenerateRelativeTimeFormatParts(isolate, formatted, integer, unit_enum),
- Object);
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, elements,
+ GenerateRelativeTimeFormatParts(
+ isolate, formatted, number_str, unit_enum,
+ abs_number, formatter->getNumberFormat()),
+ Object);
return elements;
}
@@ -410,5 +408,12 @@ MaybeHandle<Object> JSRelativeTimeFormat::Format(
formatted.length()));
}
+std::set<std::string> JSRelativeTimeFormat::GetAvailableLocales() {
+ int32_t num_locales = 0;
+ const icu::Locale* icu_available_locales =
+ icu::DateFormat::getAvailableLocales(num_locales);
+ return Intl::BuildLocaleSet(icu_available_locales, num_locales);
+}
+
} // namespace internal
} // namespace v8