diff options
Diffstat (limited to 'deps/v8/src/objects/js-relative-time-format.cc')
-rw-r--r-- | deps/v8/src/objects/js-relative-time-format.cc | 183 |
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 |