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

[Intl] Clean up Intl::GetStringOption

Add a templates: Intl::GetStringOptionTo<> to simplify the reading
of string from options.
Add GetCaseFirst and GetHourCycle into Intl for later reuse
by different Intl objects
Move some enum shared by Intl object into Intl::

Bug: v8:5751
Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng
Change-Id: If9ed1889a594f7c0ee6669b4679dda9169e4a771
Reviewed-on: https://chromium-review.googlesource.com/c/1297772Reviewed-by: 's avatarAdam Klein <adamk@chromium.org>
Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Commit-Queue: Frank Tang <ftang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57201}
parent 7ac25c0e
......@@ -1954,21 +1954,33 @@ base::TimezoneCache* Intl::CreateTimeZoneCache() {
: base::OS::CreateTimezoneCache();
}
Maybe<Intl::CaseFirst> Intl::GetCaseFirst(Isolate* isolate,
Handle<JSReceiver> options,
const char* method) {
return Intl::GetStringOption<Intl::CaseFirst>(
isolate, options, "caseFirst", method, {"upper", "lower", "false"},
{Intl::CaseFirst::kUpper, Intl::CaseFirst::kLower,
Intl::CaseFirst::kFalse},
Intl::CaseFirst::kUndefined);
}
Maybe<Intl::HourCycle> Intl::GetHourCycle(Isolate* isolate,
Handle<JSReceiver> options,
const char* method) {
return Intl::GetStringOption<Intl::HourCycle>(
isolate, options, "hourCycle", method, {"h11", "h12", "h23", "h24"},
{Intl::HourCycle::kH11, Intl::HourCycle::kH12, Intl::HourCycle::kH23,
Intl::HourCycle::kH24},
Intl::HourCycle::kUndefined);
}
Maybe<Intl::MatcherOption> Intl::GetLocaleMatcher(Isolate* isolate,
Handle<JSReceiver> options,
const char* method) {
const std::vector<const char*> values = {"lookup", "best fit"};
std::unique_ptr<char[]> matcher_str = nullptr;
Maybe<bool> found_matcher = Intl::GetStringOption(
isolate, options, "localeMatcher", values, method, &matcher_str);
MAYBE_RETURN(found_matcher, Nothing<Intl::MatcherOption>());
if (found_matcher.FromJust()) {
DCHECK_NOT_NULL(matcher_str.get());
if (strcmp(matcher_str.get(), "lookup") == 0) {
return Just(Intl::MatcherOption::kLookup);
}
}
return Just(Intl::MatcherOption::kBestFit);
return Intl::GetStringOption<Intl::MatcherOption>(
isolate, options, "localeMatcher", method, {"best fit", "lookup"},
{Intl::MatcherOption::kLookup, Intl::MatcherOption::kBestFit},
Intl::MatcherOption::kLookup);
}
} // namespace internal
......
......@@ -81,6 +81,32 @@ class Intl {
std::vector<const char*> values, const char* service,
std::unique_ptr<char[]>* result);
// A helper template to get string from option into a enum.
// The enum in the enum_values is the corresponding value to the strings
// in the str_values. If the option does not contains name,
// default_value will be return.
template <typename T>
V8_WARN_UNUSED_RESULT static Maybe<T> GetStringOption(
Isolate* isolate, Handle<JSReceiver> options, const char* name,
const char* method, const std::vector<const char*>& str_values,
const std::vector<T>& enum_values, T default_value) {
DCHECK_EQ(str_values.size(), enum_values.size());
std::unique_ptr<char[]> cstr;
Maybe<bool> found = Intl::GetStringOption(isolate, options, name,
str_values, method, &cstr);
MAYBE_RETURN(found, Nothing<T>());
if (found.FromJust()) {
DCHECK_NOT_NULL(cstr.get());
for (size_t i = 0; i < str_values.size(); i++) {
if (strcmp(cstr.get(), str_values[i]) == 0) {
return Just(enum_values[i]);
}
}
UNREACHABLE();
}
return Just(default_value);
}
// ECMA402 9.2.10. GetOption( options, property, type, values, fallback)
// ecma402/#sec-getoption
//
......@@ -189,7 +215,26 @@ class Intl {
Isolate* isolate, Handle<String> service, Handle<Object> locales,
Handle<Object> options, Handle<Object> internal_options);
enum MatcherOption { kBestFit, kLookup };
// enum for "caseFirst" option: shared by Intl.Locale and Intl.Collator.
enum class CaseFirst { kUpper, kLower, kFalse, kUndefined };
// Shared function to read the "caseFirst" option.
V8_WARN_UNUSED_RESULT static Maybe<CaseFirst> GetCaseFirst(
Isolate* isolate, Handle<JSReceiver> options, const char* method);
// enum for "hourCycle" option: shared by Intl.Locale and Intl.DateTimeFormat.
enum class HourCycle { kH11, kH12, kH23, kH24, kUndefined };
// Shared function to read the "hourCycle" option.
V8_WARN_UNUSED_RESULT static Maybe<HourCycle> GetHourCycle(
Isolate* isolate, Handle<JSReceiver> options, const char* method);
// enum for "localeMatcher" option: shared by many Intl objects.
enum class MatcherOption { kBestFit, kLookup };
// Shared function to read the "localeMatcher" option.
V8_WARN_UNUSED_RESULT static Maybe<MatcherOption> GetLocaleMatcher(
Isolate* isolate, Handle<JSReceiver> options, const char* method);
struct ResolvedLocale {
std::string locale;
......@@ -202,10 +247,6 @@ class Intl {
const std::vector<std::string>& requested_locales, MatcherOption options,
const std::set<std::string>& relevant_extension_keys);
// Shared function to read the "localeMatcher" option.
V8_WARN_UNUSED_RESULT static Maybe<MatcherOption> GetLocaleMatcher(
Isolate* isolate, Handle<JSReceiver> options, const char* method);
// Utility function to set text to BreakIterator.
static Managed<icu::UnicodeString>* SetTextToBreakIterator(
Isolate* isolate, Handle<String> text,
......
......@@ -15,14 +15,6 @@
namespace v8 {
namespace internal {
JSV8BreakIterator::Type JSV8BreakIterator::getType(const char* str) {
if (strcmp(str, "character") == 0) return Type::CHARACTER;
if (strcmp(str, "word") == 0) return Type::WORD;
if (strcmp(str, "sentence") == 0) return Type::SENTENCE;
if (strcmp(str, "line") == 0) return Type::LINE;
UNREACHABLE();
}
MaybeHandle<JSV8BreakIterator> JSV8BreakIterator::Initialize(
Isolate* isolate, Handle<JSV8BreakIterator> break_iterator_holder,
Handle<Object> locales, Handle<Object> options_obj) {
......@@ -56,17 +48,12 @@ MaybeHandle<JSV8BreakIterator> JSV8BreakIterator::Initialize(
requested_locales, matcher, {});
// Extract type from options
std::unique_ptr<char[]> type_str = nullptr;
std::vector<const char*> type_values = {"character", "word", "sentence",
"line"};
Maybe<bool> maybe_found_type = Intl::GetStringOption(
isolate, options, "type", type_values, "Intl.v8BreakIterator", &type_str);
Type type_enum = Type::WORD;
MAYBE_RETURN(maybe_found_type, MaybeHandle<JSV8BreakIterator>());
if (maybe_found_type.FromJust()) {
DCHECK_NOT_NULL(type_str.get());
type_enum = getType(type_str.get());
}
Maybe<Type> maybe_type = Intl::GetStringOption<Type>(
isolate, options, "type", "Intl.v8BreakIterator",
{"word", "character", "sentence", "line"},
{Type::WORD, Type::CHARACTER, Type::SENTENCE, Type::LINE}, Type::WORD);
MAYBE_RETURN(maybe_type, MaybeHandle<JSV8BreakIterator>());
Type type_enum = maybe_type.FromJust();
icu::Locale icu_locale = r.icu_locale;
DCHECK(!icu_locale.isBogus());
......
......@@ -88,8 +88,6 @@ class JSV8BreakIterator : public JSObject {
#undef BREAK_ITERATOR_FIELDS
private:
static Type getType(const char* str);
DISALLOW_IMPLICIT_CONSTRUCTORS(JSV8BreakIterator)
};
......
......@@ -27,6 +27,14 @@ enum class Usage {
SEARCH,
};
enum class Sensitivity {
kBase,
kAccent,
kCase,
kVariant,
kUndefined,
};
// TODO(gsathya): Consider internalizing the value strings.
void CreateDataPropertyForOptions(Isolate* isolate, Handle<JSObject> options,
Handle<String> key, const char* value) {
......@@ -208,17 +216,31 @@ Handle<JSObject> JSCollator::ResolvedOptions(Isolate* isolate,
namespace {
void SetCaseFirstOption(icu::Collator* icu_collator, const char* value) {
Intl::CaseFirst ToCaseFirst(const char* str) {
if (strcmp(str, "upper") == 0) return Intl::CaseFirst::kUpper;
if (strcmp(str, "lower") == 0) return Intl::CaseFirst::kLower;
if (strcmp(str, "false") == 0) return Intl::CaseFirst::kFalse;
return Intl::CaseFirst::kUndefined;
}
UColAttributeValue ToUColAttributeValue(Intl::CaseFirst case_first) {
switch (case_first) {
case Intl::CaseFirst::kUpper:
return UCOL_UPPER_FIRST;
case Intl::CaseFirst::kLower:
return UCOL_LOWER_FIRST;
case Intl::CaseFirst::kFalse:
case Intl::CaseFirst::kUndefined:
return UCOL_OFF;
}
}
void SetCaseFirstOption(icu::Collator* icu_collator,
Intl::CaseFirst case_first) {
CHECK_NOT_NULL(icu_collator);
CHECK_NOT_NULL(value);
UErrorCode status = U_ZERO_ERROR;
if (strcmp(value, "upper") == 0) {
icu_collator->setAttribute(UCOL_CASE_FIRST, UCOL_UPPER_FIRST, status);
} else if (strcmp(value, "lower") == 0) {
icu_collator->setAttribute(UCOL_CASE_FIRST, UCOL_LOWER_FIRST, status);
} else {
icu_collator->setAttribute(UCOL_CASE_FIRST, UCOL_OFF, status);
}
icu_collator->setAttribute(UCOL_CASE_FIRST, ToUColAttributeValue(case_first),
status);
CHECK(U_SUCCESS(status));
}
......@@ -253,19 +275,11 @@ MaybeHandle<JSCollator> JSCollator::Initialize(Isolate* isolate,
// 4. Let usage be ? GetOption(options, "usage", "string", « "sort",
// "search" », "sort").
std::vector<const char*> values = {"sort", "search"};
std::unique_ptr<char[]> usage_str = nullptr;
Usage usage = Usage::SORT;
Maybe<bool> found_usage = Intl::GetStringOption(
isolate, options, "usage", values, "Intl.Collator", &usage_str);
MAYBE_RETURN(found_usage, MaybeHandle<JSCollator>());
if (found_usage.FromJust()) {
DCHECK_NOT_NULL(usage_str.get());
if (strcmp(usage_str.get(), "search") == 0) {
usage = Usage::SEARCH;
}
}
Maybe<Usage> maybe_usage = Intl::GetStringOption<Usage>(
isolate, options, "usage", "Intl.Collator", {"sort", "search"},
{Usage::SORT, Usage::SEARCH}, Usage::SORT);
MAYBE_RETURN(maybe_usage, MaybeHandle<JSCollator>());
Usage usage = maybe_usage.FromJust();
// 9. Let matcher be ? GetOption(options, "localeMatcher", "string",
// « "lookup", "best fit" », "best fit").
......@@ -292,12 +306,10 @@ MaybeHandle<JSCollator> JSCollator::Initialize(Isolate* isolate,
// 14. Let caseFirst be ? GetOption(options, "caseFirst", "string",
// « "upper", "lower", "false" », undefined).
// 15. Set opt.[[kf]] to caseFirst.
values = {"upper", "lower", "false"};
std::unique_ptr<char[]> case_first_str = nullptr;
Maybe<bool> found_case_first = Intl::GetStringOption(
isolate, options, "caseFirst", values, "Intl.Collator", &case_first_str);
MAYBE_RETURN(found_case_first, MaybeHandle<JSCollator>());
Maybe<Intl::CaseFirst> maybe_case_first =
Intl::GetCaseFirst(isolate, options, "Intl.Collator");
MAYBE_RETURN(maybe_case_first, MaybeHandle<JSCollator>());
Intl::CaseFirst case_first = maybe_case_first.FromJust();
// The relevant unicode extensions accepted by Collator as specified here:
// https://tc39.github.io/ecma402/#sec-intl-collator-internal-slots
......@@ -420,14 +432,13 @@ MaybeHandle<JSCollator> JSCollator::Initialize(Isolate* isolate,
// If the caseFirst value is passed in through the options object,
// then we use it. Otherwise, we check if the caseFirst value is
// passed in through the unicode extensions.
if (found_case_first.FromJust()) {
const char* case_first_cstr = case_first_str.get();
SetCaseFirstOption(icu_collator.get(), case_first_cstr);
if (case_first != Intl::CaseFirst::kUndefined) {
SetCaseFirstOption(icu_collator.get(), case_first);
} else {
auto kf_extension_it = extensions.find("kf");
if (kf_extension_it != extensions.end()) {
const std::string& value = kf_extension_it->second;
SetCaseFirstOption(icu_collator.get(), value.c_str());
SetCaseFirstOption(icu_collator.get(), ToCaseFirst(value.c_str()));
}
}
......@@ -440,40 +451,42 @@ MaybeHandle<JSCollator> JSCollator::Initialize(Isolate* isolate,
// 24. Let sensitivity be ? GetOption(options, "sensitivity",
// "string", « "base", "accent", "case", "variant" », undefined).
values = {"base", "accent", "case", "variant"};
std::unique_ptr<char[]> sensitivity_str = nullptr;
Maybe<bool> found_sensitivity =
Intl::GetStringOption(isolate, options, "sensitivity", values,
"Intl.Collator", &sensitivity_str);
MAYBE_RETURN(found_sensitivity, MaybeHandle<JSCollator>());
Maybe<Sensitivity> maybe_sensitivity = Intl::GetStringOption<Sensitivity>(
isolate, options, "sensitivity", "Intl.Collator",
{"base", "accent", "case", "variant"},
{Sensitivity::kBase, Sensitivity::kAccent, Sensitivity::kCase,
Sensitivity::kVariant},
Sensitivity::kUndefined);
MAYBE_RETURN(maybe_sensitivity, MaybeHandle<JSCollator>());
Sensitivity sensitivity = maybe_sensitivity.FromJust();
// 25. If sensitivity is undefined, then
if (!found_sensitivity.FromJust()) {
if (sensitivity == Sensitivity::kUndefined) {
// 25. a. If usage is "sort", then
if (usage == Usage::SORT) {
// 25. a. i. Let sensitivity be "variant".
// 26. Set collator.[[Sensitivity]] to sensitivity.
icu_collator->setStrength(icu::Collator::TERTIARY);
sensitivity = Sensitivity::kVariant;
}
} else {
DCHECK(found_sensitivity.FromJust());
const char* sensitivity_cstr = sensitivity_str.get();
DCHECK_NOT_NULL(sensitivity_cstr);
// 26. Set collator.[[Sensitivity]] to sensitivity.
if (strcmp(sensitivity_cstr, "base") == 0) {
}
// 26. Set collator.[[Sensitivity]] to sensitivity.
switch (sensitivity) {
case Sensitivity::kBase:
icu_collator->setStrength(icu::Collator::PRIMARY);
} else if (strcmp(sensitivity_cstr, "accent") == 0) {
break;
case Sensitivity::kAccent:
icu_collator->setStrength(icu::Collator::SECONDARY);
} else if (strcmp(sensitivity_cstr, "case") == 0) {
break;
case Sensitivity::kCase:
icu_collator->setStrength(icu::Collator::PRIMARY);
status = U_ZERO_ERROR;
icu_collator->setAttribute(UCOL_CASE_LEVEL, UCOL_ON, status);
CHECK(U_SUCCESS(status));
} else {
DCHECK_EQ(0, strcmp(sensitivity_cstr, "variant"));
break;
case Sensitivity::kVariant:
icu_collator->setStrength(icu::Collator::TERTIARY);
}
break;
case Sensitivity::kUndefined:
break;
}
// 27.Let ignorePunctuation be ? GetOption(options,
......
......@@ -785,16 +785,17 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize(
// 7. Let hourCycle be ? GetOption(options, "hourCycle", "string", « "h11",
// "h12", "h23", "h24" », undefined).
const std::vector<const char*> hour_cycle_values{"h11", "h12", "h23", "h24"};
std::unique_ptr<char[]> hour_cycle = nullptr;
Maybe<bool> maybe_hour_cycle =
Intl::GetStringOption(isolate, options, "hourCycle", hour_cycle_values,
"Intl.DateTimeFormat", &hour_cycle);
MAYBE_RETURN(maybe_hour_cycle, Handle<JSDateTimeFormat>());
Maybe<Intl::HourCycle> maybe_hour_cycle =
Intl::GetHourCycle(isolate, options, "Intl.DateTimeFormat");
MAYBE_RETURN(maybe_hour_cycle, MaybeHandle<JSDateTimeFormat>());
// TODO(ftang): uncomment the following line and handle hour_cycle.
// Intl::HourCycle hour_cycle = maybe_hour_cycle.FromJust();
// 8. If hour12 is not undefined, then
if (maybe_get_hour12.FromJust()) {
// a. Let hourCycle be null.
hour_cycle = nullptr;
// TODO(ftang): uncomment the following line and handle hour_cycle.
// hour_cycle = Intl::HourCycle::kUndefined;
}
// 9. Set opt.[[hc]] to hourCycle.
// TODO(ftang): change behavior based on hour_cycle.
......@@ -838,20 +839,20 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize(
}
}
enum FormatMatcherOption { kBestFit, kBasic };
// We implement only best fit algorithm, but still need to check
// if the formatMatcher values are in range.
// 25. Let matcher be ? GetOption(options, "formatMatcher", "string",
// « "basic", "best fit" », "best fit").
Handle<JSReceiver> options_obj;
ASSIGN_RETURN_ON_EXCEPTION(isolate, options_obj,
Object::ToObject(isolate, options),
JSDateTimeFormat);
std::unique_ptr<char[]> matcher_str = nullptr;
std::vector<const char*> matcher_values = {"basic", "best fit"};
Maybe<bool> maybe_found_matcher = Intl::GetStringOption(
isolate, options_obj, "formatMatcher", matcher_values,
"Intl.DateTimeFormat", &matcher_str);
MAYBE_RETURN(maybe_found_matcher, Handle<JSDateTimeFormat>());
Maybe<FormatMatcherOption> maybe_format_matcher =
Intl::GetStringOption<FormatMatcherOption>(
isolate, options, "formatMatcher", "Intl.DateTimeFormat",
{"best fit", "basic"},
{FormatMatcherOption::kBestFit, FormatMatcherOption::kBasic},
FormatMatcherOption::kBestFit);
MAYBE_RETURN(maybe_format_matcher, MaybeHandle<JSDateTimeFormat>());
// TODO(ftang): uncomment the following line and handle format_matcher.
// FormatMatcherOption format_matcher = maybe_format_matcher.FromJust();
std::unique_ptr<icu::SimpleDateFormat> date_format(
CreateICUDateFormat(isolate, icu_locale, skeleton));
......
......@@ -150,32 +150,24 @@ MaybeHandle<JSListFormat> JSListFormat::Initialize(
// 7. Let t be GetOption(options, "type", "string", «"conjunction",
// "disjunction", "unit"», "conjunction").
std::unique_ptr<char[]> type_str = nullptr;
std::vector<const char*> type_values = {"conjunction", "disjunction", "unit"};
Maybe<bool> maybe_found_type = Intl::GetStringOption(
isolate, options, "type", type_values, "Intl.ListFormat", &type_str);
Type type_enum = Type::CONJUNCTION;
MAYBE_RETURN(maybe_found_type, MaybeHandle<JSListFormat>());
if (maybe_found_type.FromJust()) {
DCHECK_NOT_NULL(type_str.get());
type_enum = get_type(type_str.get());
}
Maybe<Type> maybe_type = Intl::GetStringOption<Type>(
isolate, options, "type", "Intl.ListFormat",
{"conjunction", "disjunction", "unit"},
{Type::CONJUNCTION, Type::DISJUNCTION, Type::UNIT}, Type::CONJUNCTION);
MAYBE_RETURN(maybe_type, MaybeHandle<JSListFormat>());
Type type_enum = maybe_type.FromJust();
// 8. Set listFormat.[[Type]] to t.
list_format->set_type(type_enum);
// 9. 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.ListFormat", &style_str);
Style style_enum = Style::LONG;
MAYBE_RETURN(maybe_found_style, MaybeHandle<JSListFormat>());
if (maybe_found_style.FromJust()) {
DCHECK_NOT_NULL(style_str.get());
style_enum = get_style(style_str.get());
}
Maybe<Style> maybe_style = Intl::GetStringOption<Style>(
isolate, options, "style", "Intl.ListFormat", {"long", "short", "narrow"},
{Style::LONG, Style::SHORT, Style::NARROW}, Style::LONG);
MAYBE_RETURN(maybe_style, MaybeHandle<JSListFormat>());
Style style_enum = maybe_style.FromJust();
// 10. Set listFormat.[[Style]] to s.
list_format->set_style(style_enum);
......
......@@ -27,6 +27,20 @@ namespace internal {
namespace {
UNumberFormatStyle ToNumberFormatStyle(
JSNumberFormat::CurrencyDisplay currency_display) {
switch (currency_display) {
case JSNumberFormat::CurrencyDisplay::SYMBOL:
return UNUM_CURRENCY;
case JSNumberFormat::CurrencyDisplay::CODE:
return UNUM_CURRENCY_ISO;
case JSNumberFormat::CurrencyDisplay::NAME:
return UNUM_CURRENCY_PLURAL;
case JSNumberFormat::CurrencyDisplay::COUNT:
UNREACHABLE();
}
}
// ecma-402/#sec-currencydigits
// The currency is expected to an all upper case string value.
int CurrencyDigits(const icu::UnicodeString& currency) {
......@@ -277,21 +291,11 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize(
// 12. Let style be ? GetOption(options, "style", "string", « "decimal",
// "percent", "currency" », "decimal").
const char* service = "Intl.NumberFormat";
std::unique_ptr<char[]> style_cstr;
const std::vector<const char*> style_values = {"decimal", "percent",
"currency"};
Maybe<bool> found_style = Intl::GetStringOption(
isolate, options, "style", style_values, service, &style_cstr);
MAYBE_RETURN(found_style, MaybeHandle<JSNumberFormat>());
Style style = Style::DECIMAL;
if (found_style.FromJust()) {
DCHECK_NOT_NULL(style_cstr.get());
if (strcmp(style_cstr.get(), "percent") == 0) {
style = Style::PERCENT;
} else if (strcmp(style_cstr.get(), "currency") == 0) {
style = Style::CURRENCY;
}
}
Maybe<Style> maybe_style = Intl::GetStringOption<Style>(
isolate, options, "style", service, {"decimal", "percent", "currency"},
{Style::DECIMAL, Style::PERCENT, Style::CURRENCY}, Style::DECIMAL);
MAYBE_RETURN(maybe_style, MaybeHandle<JSNumberFormat>());
Style style = maybe_style.FromJust();
// 13. Set numberFormat.[[Style]] to style.
number_format->set_style(style);
......@@ -340,26 +344,16 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::Initialize(
// 18. Let currencyDisplay be ? GetOption(options, "currencyDisplay",
// "string", « "code", "symbol", "name" », "symbol").
std::unique_ptr<char[]> currency_display_cstr;
const std::vector<const char*> currency_display_values = {"code", "name",
"symbol"};
Maybe<bool> found_currency_display = Intl::GetStringOption(
isolate, options, "currencyDisplay", currency_display_values, service,
&currency_display_cstr);
MAYBE_RETURN(found_currency_display, MaybeHandle<JSNumberFormat>());
CurrencyDisplay currency_display = CurrencyDisplay::SYMBOL;
UNumberFormatStyle format_style = UNUM_CURRENCY;
if (found_currency_display.FromJust()) {
DCHECK_NOT_NULL(currency_display_cstr.get());
if (strcmp(currency_display_cstr.get(), "code") == 0) {
currency_display = CurrencyDisplay::CODE;
format_style = UNUM_CURRENCY_ISO;
} else if (strcmp(currency_display_cstr.get(), "name") == 0) {
currency_display = CurrencyDisplay::NAME;
format_style = UNUM_CURRENCY_PLURAL;
}
}
Maybe<CurrencyDisplay> maybe_currencyDisplay =
Intl::GetStringOption<CurrencyDisplay>(
isolate, options, "currencyDisplay", service,
{"code", "symbol", "name"},
{CurrencyDisplay::CODE, CurrencyDisplay::SYMBOL,
CurrencyDisplay::NAME},
CurrencyDisplay::SYMBOL);
MAYBE_RETURN(maybe_currencyDisplay, MaybeHandle<JSNumberFormat>());
CurrencyDisplay currency_display = maybe_currencyDisplay.FromJust();
UNumberFormatStyle format_style = ToNumberFormatStyle(currency_display);
UErrorCode status = U_ZERO_ERROR;
std::unique_ptr<icu::NumberFormat> icu_number_format;
......
......@@ -130,20 +130,11 @@ MaybeHandle<JSPluralRules> JSPluralRules::Initialize(
// 7. Let t be ? GetOption(options, "type", "string", « "cardinal",
// "ordinal" », "cardinal").
std::vector<const char*> values = {"cardinal", "ordinal"};
std::unique_ptr<char[]> type_str = nullptr;
JSPluralRules::Type type = JSPluralRules::Type::CARDINAL;
Maybe<bool> found = Intl::GetStringOption(isolate, options, "type", values,
"Intl.PluralRules", &type_str);
MAYBE_RETURN(found, MaybeHandle<JSPluralRules>());
if (found.FromJust()) {
DCHECK_NOT_NULL(type_str.get());
if (strcmp("ordinal", type_str.get()) == 0) {
type = JSPluralRules::Type::ORDINAL;
} else {
DCHECK_EQ(0, strcmp("cardinal", type_str.get()));
}
}
Maybe<Type> maybe_type = Intl::GetStringOption<Type>(
isolate, options, "type", "Intl.PluralRules", {"cardinal", "ordinal"},
{Type::CARDINAL, Type::ORDINAL}, Type::CARDINAL);
MAYBE_RETURN(maybe_type, MaybeHandle<JSPluralRules>());
Type type = maybe_type.FromJust();
// 8. Set pluralRules.[[Type]] to t.
plural_rules->set_type(type);
......
......@@ -108,34 +108,23 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::Initialize(
// 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());
}
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);
// 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();
// 15. Set relativeTimeFormat.[[Numeric]] to numeric.
relative_time_format_holder->set_numeric(numeric_enum);
......
......@@ -82,18 +82,15 @@ MaybeHandle<JSSegmenter> JSSegmenter::Initialize(
// 7. Let lineBreakStyle be ? GetOption(options, "lineBreakStyle", "string", «
// "strict", "normal", "loose" », "normal").
std::unique_ptr<char[]> line_break_style_str = nullptr;
const std::vector<const char*> line_break_style_values = {"strict", "normal",
"loose"};
Maybe<bool> maybe_found_line_break_style = Intl::GetStringOption(
isolate, options, "lineBreakStyle", line_break_style_values,
"Intl.Segmenter", &line_break_style_str);
LineBreakStyle line_break_style_enum = LineBreakStyle::NORMAL;
MAYBE_RETURN(maybe_found_line_break_style, MaybeHandle<JSSegmenter>());
if (maybe_found_line_break_style.FromJust()) {
DCHECK_NOT_NULL(line_break_style_str.get());
line_break_style_enum = GetLineBreakStyle(line_break_style_str.get());
}
Maybe<LineBreakStyle> maybe_line_break_style =
Intl::GetStringOption<LineBreakStyle>(
isolate, options, "lineBreakStyle", "Intl.Segmenter",
{"strict", "normal", "loose"},
{LineBreakStyle::STRICT, LineBreakStyle::NORMAL,
LineBreakStyle::LOOSE},
LineBreakStyle::NORMAL);
MAYBE_RETURN(maybe_line_break_style, MaybeHandle<JSSegmenter>());
LineBreakStyle line_break_style_enum = maybe_line_break_style.FromJust();
// 10. Set segmenter.[[Locale]] to the value of r.[[Locale]].
Handle<String> locale_str =
......@@ -102,19 +99,14 @@ MaybeHandle<JSSegmenter> JSSegmenter::Initialize(
// 13. Let granularity be ? GetOption(options, "granularity", "string", «
// "grapheme", "word", "sentence", "line" », "grapheme").
std::unique_ptr<char[]> granularity_str = nullptr;
const std::vector<const char*> granularity_values = {"grapheme", "word",
"sentence", "line"};
Maybe<bool> maybe_found_granularity =
Intl::GetStringOption(isolate, options, "granularity", granularity_values,
"Intl.Segmenter", &granularity_str);
Granularity granularity_enum = Granularity::GRAPHEME;
MAYBE_RETURN(maybe_found_granularity, MaybeHandle<JSSegmenter>());
if (maybe_found_granularity.FromJust()) {
DCHECK_NOT_NULL(granularity_str.get());
granularity_enum = GetGranularity(granularity_str.get());
}
Maybe<Granularity> maybe_granularity = Intl::GetStringOption<Granularity>(
isolate, options, "granularity", "Intl.Segmenter",
{"grapheme", "word", "sentence", "line"},
{Granularity::GRAPHEME, Granularity::WORD, Granularity::SENTENCE,
Granularity::LINE},
Granularity::GRAPHEME);
MAYBE_RETURN(maybe_granularity, MaybeHandle<JSSegmenter>());
Granularity granularity_enum = maybe_granularity.FromJust();
// 14. Set segmenter.[[SegmenterGranularity]] to granularity.
segmenter_holder->set_granularity(granularity_enum);
......
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