Title: [264500] trunk/Source/_javascript_Core
Revision
264500
Author
[email protected]
Date
2020-07-16 23:07:57 -0700 (Thu, 16 Jul 2020)

Log Message

[JSC] Clean up Intl option parsing code by introducing intlOption<>
https://bugs.webkit.org/show_bug.cgi?id=214437

Reviewed by Ross Kirsling.

This patch introduces intlOption<>(...) function and remove redundant string comparisons.
This makes option handling efficient, and it makes code clean.

* runtime/IntlCollator.cpp:
(JSC::IntlCollator::initializeCollator):
* runtime/IntlDateTimeFormat.cpp:
(JSC::IntlDateTimeFormat::initializeDateTimeFormat):
* runtime/IntlNumberFormat.cpp:
(JSC::IntlNumberFormat::initializeNumberFormat):
* runtime/IntlObject.cpp:
(JSC::resolveLocale):
(JSC::supportedLocales):
* runtime/IntlObject.h:
* runtime/IntlObjectInlines.h:
(JSC::intlOption):
* runtime/IntlPluralRules.cpp:
(JSC::IntlPluralRules::initializePluralRules):
* runtime/IntlRelativeTimeFormat.cpp:
(JSC::IntlRelativeTimeFormat::initializeRelativeTimeFormat):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (264499 => 264500)


--- trunk/Source/_javascript_Core/ChangeLog	2020-07-17 05:18:58 UTC (rev 264499)
+++ trunk/Source/_javascript_Core/ChangeLog	2020-07-17 06:07:57 UTC (rev 264500)
@@ -1,3 +1,30 @@
+2020-07-16  Yusuke Suzuki  <[email protected]>
+
+        [JSC] Clean up Intl option parsing code by introducing intlOption<>
+        https://bugs.webkit.org/show_bug.cgi?id=214437
+
+        Reviewed by Ross Kirsling.
+
+        This patch introduces intlOption<>(...) function and remove redundant string comparisons.
+        This makes option handling efficient, and it makes code clean.
+
+        * runtime/IntlCollator.cpp:
+        (JSC::IntlCollator::initializeCollator):
+        * runtime/IntlDateTimeFormat.cpp:
+        (JSC::IntlDateTimeFormat::initializeDateTimeFormat):
+        * runtime/IntlNumberFormat.cpp:
+        (JSC::IntlNumberFormat::initializeNumberFormat):
+        * runtime/IntlObject.cpp:
+        (JSC::resolveLocale):
+        (JSC::supportedLocales):
+        * runtime/IntlObject.h:
+        * runtime/IntlObjectInlines.h:
+        (JSC::intlOption):
+        * runtime/IntlPluralRules.cpp:
+        (JSC::IntlPluralRules::initializePluralRules):
+        * runtime/IntlRelativeTimeFormat.cpp:
+        (JSC::IntlRelativeTimeFormat::initializeRelativeTimeFormat):
+
 2020-07-16  Fujii Hironori  <[email protected]>
 
         [WTF] Remove the unnecessary inner class DefaultHash<T>::Hash

Modified: trunk/Source/_javascript_Core/runtime/IntlCollator.cpp (264499 => 264500)


--- trunk/Source/_javascript_Core/runtime/IntlCollator.cpp	2020-07-17 05:18:58 UTC (rev 264499)
+++ trunk/Source/_javascript_Core/runtime/IntlCollator.cpp	2020-07-17 06:07:57 UTC (rev 264500)
@@ -28,7 +28,7 @@
 #include "config.h"
 #include "IntlCollator.h"
 
-#include "IntlObject.h"
+#include "IntlObjectInlines.h"
 #include "JSBoundFunction.h"
 #include "JSCInlines.h"
 #include "ObjectConstructor.h"
@@ -178,22 +178,15 @@
         RETURN_IF_EXCEPTION(scope, void());
     }
 
-    String usageString = intlStringOption(globalObject, options, vm.propertyNames->usage, { "sort", "search" }, "usage must be either \"sort\" or \"search\"", "sort");
+    m_usage = intlOption<Usage>(globalObject, options, vm.propertyNames->usage, { { "sort"_s, Usage::Sort }, { "search"_s, Usage::Search } }, "usage must be either \"sort\" or \"search\""_s, Usage::Sort);
     RETURN_IF_EXCEPTION(scope, void());
-    if (usageString == "sort")
-        m_usage = Usage::Sort;
-    else if (usageString == "search")
-        m_usage = Usage::Search;
-    else
-        ASSERT_NOT_REACHED();
 
     auto localeData = (m_usage == Usage::Sort) ? sortLocaleData : searchLocaleData;
 
     HashMap<String, String> opt;
 
-    String matcher = intlStringOption(globalObject, options, vm.propertyNames->localeMatcher, { "lookup", "best fit" }, "localeMatcher must be either \"lookup\" or \"best fit\"", "best fit");
+    LocaleMatcher localeMatcher = intlOption<LocaleMatcher>(globalObject, options, vm.propertyNames->localeMatcher, { { "lookup"_s, LocaleMatcher::Lookup }, { "best fit"_s, LocaleMatcher::BestFit } }, "localeMatcher must be either \"lookup\" or \"best fit\""_s, LocaleMatcher::BestFit);
     RETURN_IF_EXCEPTION(scope, void());
-    opt.add("localeMatcher"_s, matcher);
 
     TriState numeric = intlBooleanOption(globalObject, options, vm.propertyNames->numeric);
     RETURN_IF_EXCEPTION(scope, void());
@@ -206,7 +199,7 @@
         opt.add("kf"_s, caseFirstOption);
 
     auto& availableLocales = intlCollatorAvailableLocales();
-    auto result = resolveLocale(globalObject, availableLocales, requestedLocales, opt, IntlCollatorInternal::relevantExtensionKeys, WTF_ARRAY_LENGTH(IntlCollatorInternal::relevantExtensionKeys), localeData);
+    auto result = resolveLocale(globalObject, availableLocales, requestedLocales, localeMatcher, opt, IntlCollatorInternal::relevantExtensionKeys, WTF_ARRAY_LENGTH(IntlCollatorInternal::relevantExtensionKeys), localeData);
 
     m_locale = result.get("locale"_s);
     if (m_locale.isEmpty()) {
@@ -226,16 +219,8 @@
     else
         m_caseFirst = CaseFirst::False;
 
-    String sensitivityString = intlStringOption(globalObject, options, vm.propertyNames->sensitivity, { "base", "accent", "case", "variant" }, "sensitivity must be either \"base\", \"accent\", \"case\", or \"variant\"", nullptr);
+    m_sensitivity = intlOption<Sensitivity>(globalObject, options, vm.propertyNames->sensitivity, { { "base"_s, Sensitivity::Base }, { "accent"_s, Sensitivity::Accent }, { "case"_s, Sensitivity::Case }, { "variant"_s, Sensitivity::Variant } }, "sensitivity must be either \"base\", \"accent\", \"case\", or \"variant\""_s, Sensitivity::Variant);
     RETURN_IF_EXCEPTION(scope, void());
-    if (sensitivityString == "base")
-        m_sensitivity = Sensitivity::Base;
-    else if (sensitivityString == "accent")
-        m_sensitivity = Sensitivity::Accent;
-    else if (sensitivityString == "case")
-        m_sensitivity = Sensitivity::Case;
-    else
-        m_sensitivity = Sensitivity::Variant;
 
     TriState ignorePunctuation = intlBooleanOption(globalObject, options, vm.propertyNames->ignorePunctuation);
     RETURN_IF_EXCEPTION(scope, void());

Modified: trunk/Source/_javascript_Core/runtime/IntlDateTimeFormat.cpp (264499 => 264500)


--- trunk/Source/_javascript_Core/runtime/IntlDateTimeFormat.cpp	2020-07-17 05:18:58 UTC (rev 264499)
+++ trunk/Source/_javascript_Core/runtime/IntlDateTimeFormat.cpp	2020-07-17 06:07:57 UTC (rev 264500)
@@ -421,9 +421,8 @@
 
     HashMap<String, String> opt;
 
-    String localeMatcher = intlStringOption(globalObject, options, vm.propertyNames->localeMatcher, { "lookup", "best fit" }, "localeMatcher must be either \"lookup\" or \"best fit\"", "best fit");
+    LocaleMatcher localeMatcher = intlOption<LocaleMatcher>(globalObject, options, vm.propertyNames->localeMatcher, { { "lookup"_s, LocaleMatcher::Lookup }, { "best fit"_s, LocaleMatcher::BestFit } }, "localeMatcher must be either \"lookup\" or \"best fit\""_s, LocaleMatcher::BestFit);
     RETURN_IF_EXCEPTION(scope, void());
-    opt.add(vm.propertyNames->localeMatcher.string(), localeMatcher);
 
     String calendar = intlStringOption(globalObject, options, vm.propertyNames->calendar, { }, nullptr, nullptr);
     RETURN_IF_EXCEPTION(scope, void());
@@ -460,7 +459,7 @@
         opt.add("hc"_s, String());
 
     const HashSet<String>& availableLocales = intlDateTimeFormatAvailableLocales();
-    HashMap<String, String> resolved = resolveLocale(globalObject, availableLocales, requestedLocales, opt, IntlDateTimeFormatInternal::relevantExtensionKeys, WTF_ARRAY_LENGTH(IntlDateTimeFormatInternal::relevantExtensionKeys), localeData);
+    HashMap<String, String> resolved = resolveLocale(globalObject, availableLocales, requestedLocales, localeMatcher, opt, IntlDateTimeFormatInternal::relevantExtensionKeys, WTF_ARRAY_LENGTH(IntlDateTimeFormatInternal::relevantExtensionKeys), localeData);
 
     m_locale = resolved.get(vm.propertyNames->locale.string());
     if (m_locale.isEmpty()) {
@@ -496,69 +495,91 @@
     m_timeZone = tz;
 
     StringBuilder skeletonBuilder;
-    auto narrowShortLong = { "narrow", "short", "long" };
-    auto twoDigitNumeric = { "2-digit", "numeric" };
-    auto twoDigitNumericNarrowShortLong = { "2-digit", "numeric", "narrow", "short", "long" };
-    auto shortLong = { "short", "long" };
 
-    String weekday = intlStringOption(globalObject, options, vm.propertyNames->weekday, narrowShortLong, "weekday must be \"narrow\", \"short\", or \"long\"", nullptr);
+    Weekday weekday = intlOption<Weekday>(globalObject, options, vm.propertyNames->weekday, { { "narrow"_s, Weekday::Narrow }, { "short"_s, Weekday::Short }, { "long"_s, Weekday::Long } }, "weekday must be \"narrow\", \"short\", or \"long\""_s, Weekday::None);
     RETURN_IF_EXCEPTION(scope, void());
-    if (!weekday.isNull()) {
-        if (weekday == "narrow")
-            skeletonBuilder.appendLiteral("EEEEE");
-        else if (weekday == "short")
-            skeletonBuilder.appendLiteral("EEE");
-        else if (weekday == "long")
-            skeletonBuilder.appendLiteral("EEEE");
+    switch (weekday) {
+    case Weekday::Narrow:
+        skeletonBuilder.appendLiteral("EEEEE");
+        break;
+    case Weekday::Short:
+        skeletonBuilder.appendLiteral("EEE");
+        break;
+    case Weekday::Long:
+        skeletonBuilder.appendLiteral("EEEE");
+        break;
+    case Weekday::None:
+        break;
     }
 
-    String era = intlStringOption(globalObject, options, vm.propertyNames->era, narrowShortLong, "era must be \"narrow\", \"short\", or \"long\"", nullptr);
+    Era era = intlOption<Era>(globalObject, options, vm.propertyNames->era, { { "narrow"_s, Era::Narrow }, { "short"_s, Era::Short }, { "long"_s, Era::Long } }, "era must be \"narrow\", \"short\", or \"long\""_s, Era::None);
     RETURN_IF_EXCEPTION(scope, void());
-    if (!era.isNull()) {
-        if (era == "narrow")
-            skeletonBuilder.appendLiteral("GGGGG");
-        else if (era == "short")
-            skeletonBuilder.appendLiteral("GGG");
-        else if (era == "long")
-            skeletonBuilder.appendLiteral("GGGG");
+    switch (era) {
+    case Era::Narrow:
+        skeletonBuilder.appendLiteral("GGGGG");
+        break;
+    case Era::Short:
+        skeletonBuilder.appendLiteral("GGG");
+        break;
+    case Era::Long:
+        skeletonBuilder.appendLiteral("GGGG");
+        break;
+    case Era::None:
+        break;
     }
 
-    String year = intlStringOption(globalObject, options, vm.propertyNames->year, twoDigitNumeric, "year must be \"2-digit\" or \"numeric\"", nullptr);
+    Year year = intlOption<Year>(globalObject, options, vm.propertyNames->year, { { "2-digit"_s, Year::TwoDigit }, { "numeric"_s, Year::Numeric } }, "year must be \"2-digit\" or \"numeric\""_s, Year::None);
     RETURN_IF_EXCEPTION(scope, void());
-    if (!year.isNull()) {
-        if (year == "2-digit")
-            skeletonBuilder.appendLiteral("yy");
-        else if (year == "numeric")
-            skeletonBuilder.append('y');
+    switch (year) {
+    case Year::TwoDigit:
+        skeletonBuilder.appendLiteral("yy");
+        break;
+    case Year::Numeric:
+        skeletonBuilder.append('y');
+        break;
+    case Year::None:
+        break;
     }
 
-    String month = intlStringOption(globalObject, options, vm.propertyNames->month, twoDigitNumericNarrowShortLong, "month must be \"2-digit\", \"numeric\", \"narrow\", \"short\", or \"long\"", nullptr);
+    Month month = intlOption<Month>(globalObject, options, vm.propertyNames->month, { { "2-digit"_s, Month::TwoDigit }, { "numeric"_s, Month::Numeric }, { "narrow"_s, Month::Narrow }, { "short"_s, Month::Short }, { "long"_s, Month::Long } }, "month must be \"2-digit\", \"numeric\", \"narrow\", \"short\", or \"long\""_s, Month::None);
     RETURN_IF_EXCEPTION(scope, void());
-    if (!month.isNull()) {
-        if (month == "2-digit")
-            skeletonBuilder.appendLiteral("MM");
-        else if (month == "numeric")
-            skeletonBuilder.append('M');
-        else if (month == "narrow")
-            skeletonBuilder.appendLiteral("MMMMM");
-        else if (month == "short")
-            skeletonBuilder.appendLiteral("MMM");
-        else if (month == "long")
-            skeletonBuilder.appendLiteral("MMMM");
+    switch (month) {
+    case Month::TwoDigit:
+        skeletonBuilder.appendLiteral("MM");
+        break;
+    case Month::Numeric:
+        skeletonBuilder.append('M');
+        break;
+    case Month::Narrow:
+        skeletonBuilder.appendLiteral("MMMMM");
+        break;
+    case Month::Short:
+        skeletonBuilder.appendLiteral("MMM");
+        break;
+    case Month::Long:
+        skeletonBuilder.appendLiteral("MMMM");
+        break;
+    case Month::None:
+        break;
     }
 
-    String day = intlStringOption(globalObject, options, vm.propertyNames->day, twoDigitNumeric, "day must be \"2-digit\" or \"numeric\"", nullptr);
+    Day day = intlOption<Day>(globalObject, options, vm.propertyNames->day, { { "2-digit"_s, Day::TwoDigit }, { "numeric"_s, Day::Numeric } }, "day must be \"2-digit\" or \"numeric\""_s, Day::None);
     RETURN_IF_EXCEPTION(scope, void());
-    if (!day.isNull()) {
-        if (day == "2-digit")
-            skeletonBuilder.appendLiteral("dd");
-        else if (day == "numeric")
-            skeletonBuilder.append('d');
+    switch (day) {
+    case Day::TwoDigit:
+        skeletonBuilder.appendLiteral("dd");
+        break;
+    case Day::Numeric:
+        skeletonBuilder.append('d');
+        break;
+    case Day::None:
+        break;
     }
 
-    String hour = intlStringOption(globalObject, options, vm.propertyNames->hour, twoDigitNumeric, "hour must be \"2-digit\" or \"numeric\"", nullptr);
+    Hour hour = intlOption<Hour>(globalObject, options, vm.propertyNames->hour, { { "2-digit"_s, Hour::TwoDigit }, { "numeric"_s, Hour::Numeric } }, "hour must be \"2-digit\" or \"numeric\""_s, Hour::None);
     RETURN_IF_EXCEPTION(scope, void());
-    if (hour == "2-digit") {
+    switch (hour) {
+    case Hour::TwoDigit:
         if (isHour12Undefined && m_hourCycle.isNull())
             skeletonBuilder.appendLiteral("jj");
         else if (hour12 == TriState::True)
@@ -565,7 +586,8 @@
             skeletonBuilder.appendLiteral("hh");
         else
             skeletonBuilder.appendLiteral("HH");
-    } else if (hour == "numeric") {
+        break;
+    case Hour::Numeric:
         if (isHour12Undefined && m_hourCycle.isNull())
             skeletonBuilder.append('j');
         else if (hour12 == TriState::True)
@@ -572,34 +594,49 @@
             skeletonBuilder.append('h');
         else
             skeletonBuilder.append('H');
-    } else
+        break;
+    case Hour::None:
         m_hourCycle = String();
+        break;
+    }
 
-    String minute = intlStringOption(globalObject, options, vm.propertyNames->minute, twoDigitNumeric, "minute must be \"2-digit\" or \"numeric\"", nullptr);
+    Minute minute = intlOption<Minute>(globalObject, options, vm.propertyNames->minute, { { "2-digit"_s, Minute::TwoDigit }, { "numeric"_s, Minute::Numeric } }, "minute must be \"2-digit\" or \"numeric\""_s, Minute::None);
     RETURN_IF_EXCEPTION(scope, void());
-    if (!minute.isNull()) {
-        if (minute == "2-digit")
-            skeletonBuilder.appendLiteral("mm");
-        else if (minute == "numeric")
-            skeletonBuilder.append('m');
+    switch (minute) {
+    case Minute::TwoDigit:
+        skeletonBuilder.appendLiteral("mm");
+        break;
+    case Minute::Numeric:
+        skeletonBuilder.append('m');
+        break;
+    case Minute::None:
+        break;
     }
 
-    String second = intlStringOption(globalObject, options, vm.propertyNames->second, twoDigitNumeric, "second must be \"2-digit\" or \"numeric\"", nullptr);
+    Second second = intlOption<Second>(globalObject, options, vm.propertyNames->second, { { "2-digit"_s, Second::TwoDigit }, { "numeric"_s, Second::Numeric } }, "second must be \"2-digit\" or \"numeric\""_s, Second::None);
     RETURN_IF_EXCEPTION(scope, void());
-    if (!second.isNull()) {
-        if (second == "2-digit")
-            skeletonBuilder.appendLiteral("ss");
-        else if (second == "numeric")
-            skeletonBuilder.append('s');
+    switch (second) {
+    case Second::TwoDigit:
+        skeletonBuilder.appendLiteral("ss");
+        break;
+    case Second::Numeric:
+        skeletonBuilder.append('s');
+        break;
+    case Second::None:
+        break;
     }
 
-    String timeZoneName = intlStringOption(globalObject, options, vm.propertyNames->timeZoneName, shortLong, "timeZoneName must be \"short\" or \"long\"", nullptr);
+    TimeZoneName timeZoneName = intlOption<TimeZoneName>(globalObject, options, vm.propertyNames->timeZoneName, { { "short"_s, TimeZoneName::Short }, { "long"_s, TimeZoneName::Long } }, "timeZoneName must be \"short\" or \"long\""_s, TimeZoneName::None);
     RETURN_IF_EXCEPTION(scope, void());
-    if (!timeZoneName.isNull()) {
-        if (timeZoneName == "short")
-            skeletonBuilder.append('z');
-        else if (timeZoneName == "long")
-            skeletonBuilder.appendLiteral("zzzz");
+    switch (timeZoneName) {
+    case TimeZoneName::Short:
+        skeletonBuilder.append('z');
+        break;
+    case TimeZoneName::Long:
+        skeletonBuilder.appendLiteral("zzzz");
+        break;
+    case TimeZoneName::None:
+        break;
     }
 
     intlStringOption(globalObject, options, vm.propertyNames->formatMatcher, { "basic", "best fit" }, "formatMatcher must be either \"basic\" or \"best fit\"", "best fit");

Modified: trunk/Source/_javascript_Core/runtime/IntlNumberFormat.cpp (264499 => 264500)


--- trunk/Source/_javascript_Core/runtime/IntlNumberFormat.cpp	2020-07-17 05:18:58 UTC (rev 264499)
+++ trunk/Source/_javascript_Core/runtime/IntlNumberFormat.cpp	2020-07-17 06:07:57 UTC (rev 264500)
@@ -30,7 +30,7 @@
 #include "IntlNumberFormat.h"
 
 #include "Error.h"
-#include "IntlObject.h"
+#include "IntlObjectInlines.h"
 #include "JSBoundFunction.h"
 #include "JSCInlines.h"
 #include "ObjectConstructor.h"
@@ -173,9 +173,8 @@
 
     HashMap<String, String> opt;
 
-    String matcher = intlStringOption(globalObject, options, vm.propertyNames->localeMatcher, { "lookup", "best fit" }, "localeMatcher must be either \"lookup\" or \"best fit\"", "best fit");
+    LocaleMatcher localeMatcher = intlOption<LocaleMatcher>(globalObject, options, vm.propertyNames->localeMatcher, { { "lookup"_s, LocaleMatcher::Lookup }, { "best fit"_s, LocaleMatcher::BestFit } }, "localeMatcher must be either \"lookup\" or \"best fit\""_s, LocaleMatcher::BestFit);
     RETURN_IF_EXCEPTION(scope, void());
-    opt.add("localeMatcher"_s, matcher);
 
     String numberingSystem = intlStringOption(globalObject, options, vm.propertyNames->numberingSystem, { }, nullptr, nullptr);
     RETURN_IF_EXCEPTION(scope, void());
@@ -188,7 +187,7 @@
     }
 
     auto& availableLocales = intlNumberFormatAvailableLocales();
-    auto result = resolveLocale(globalObject, availableLocales, requestedLocales, opt, IntlNumberFormatInternal::relevantExtensionKeys, WTF_ARRAY_LENGTH(IntlNumberFormatInternal::relevantExtensionKeys), localeData);
+    auto result = resolveLocale(globalObject, availableLocales, requestedLocales, localeMatcher, opt, IntlNumberFormatInternal::relevantExtensionKeys, WTF_ARRAY_LENGTH(IntlNumberFormatInternal::relevantExtensionKeys), localeData);
 
     m_locale = result.get("locale"_s);
     if (m_locale.isEmpty()) {
@@ -198,16 +197,8 @@
 
     m_numberingSystem = result.get("nu"_s);
 
-    String styleString = intlStringOption(globalObject, options, vm.propertyNames->style, { "decimal", "percent", "currency" }, "style must be either \"decimal\", \"percent\", or \"currency\"", "decimal");
+    m_style = intlOption<Style>(globalObject, options, vm.propertyNames->style, { { "decimal"_s, Style::Decimal }, { "percent"_s, Style::Percent }, { "currency"_s, Style::Currency } }, "style must be either \"decimal\", \"percent\", or \"currency\""_s, Style::Decimal);
     RETURN_IF_EXCEPTION(scope, void());
-    if (styleString == "decimal")
-        m_style = Style::Decimal;
-    else if (styleString == "percent")
-        m_style = Style::Percent;
-    else if (styleString == "currency")
-        m_style = Style::Currency;
-    else
-        ASSERT_NOT_REACHED();
 
     String currency = intlStringOption(globalObject, options, Identifier::fromString(vm, "currency"), { }, nullptr, nullptr);
     RETURN_IF_EXCEPTION(scope, void());
@@ -230,18 +221,8 @@
         currencyDigits = computeCurrencyDigits(currency);
     }
 
-    String currencyDisplayString = intlStringOption(globalObject, options, Identifier::fromString(vm, "currencyDisplay"), { "code", "symbol", "name" }, "currencyDisplay must be either \"code\", \"symbol\", or \"name\"", "symbol");
+    m_currencyDisplay = intlOption<CurrencyDisplay>(globalObject, options, Identifier::fromString(vm, "currencyDisplay"), { { "code"_s, CurrencyDisplay::Code }, { "symbol"_s, CurrencyDisplay::Symbol }, { "name"_s, CurrencyDisplay::Name } }, "currencyDisplay must be either \"code\", \"symbol\", or \"name\""_s, CurrencyDisplay::Symbol);
     RETURN_IF_EXCEPTION(scope, void());
-    if (m_style == Style::Currency) {
-        if (currencyDisplayString == "code")
-            m_currencyDisplay = CurrencyDisplay::Code;
-        else if (currencyDisplayString == "symbol")
-            m_currencyDisplay = CurrencyDisplay::Symbol;
-        else if (currencyDisplayString == "name")
-            m_currencyDisplay = CurrencyDisplay::Name;
-        else
-            ASSERT_NOT_REACHED();
-    }
 
     unsigned minimumIntegerDigits = intlNumberOption(globalObject, options, Identifier::fromString(vm, "minimumIntegerDigits"), 1, 21, 1);
     RETURN_IF_EXCEPTION(scope, void());

Modified: trunk/Source/_javascript_Core/runtime/IntlObject.cpp (264499 => 264500)


--- trunk/Source/_javascript_Core/runtime/IntlObject.cpp	2020-07-17 05:18:58 UTC (rev 264499)
+++ trunk/Source/_javascript_Core/runtime/IntlObject.cpp	2020-07-17 06:07:57 UTC (rev 264500)
@@ -629,13 +629,12 @@
     subtags.append(extension.substring(valueStart, extensionLength - valueStart));
 }
 
-HashMap<String, String> resolveLocale(JSGlobalObject* globalObject, const HashSet<String>& availableLocales, const Vector<String>& requestedLocales, const HashMap<String, String>& options, const char* const relevantExtensionKeys[], size_t relevantExtensionKeyCount, Vector<String> (*localeData)(const String&, size_t))
+HashMap<String, String> resolveLocale(JSGlobalObject* globalObject, const HashSet<String>& availableLocales, const Vector<String>& requestedLocales, LocaleMatcher localeMatcher, const HashMap<String, String>& options, const char* const relevantExtensionKeys[], size_t relevantExtensionKeyCount, Vector<String> (*localeData)(const String&, size_t))
 {
     // ResolveLocale (availableLocales, requestedLocales, options, relevantExtensionKeys, localeData)
     // https://tc39.github.io/ecma402/#sec-resolvelocale
 
-    const String& matcher = options.get("localeMatcher"_s);
-    MatcherResult matcherResult = (matcher == "lookup")
+    MatcherResult matcherResult = localeMatcher == LocaleMatcher::Lookup
         ? lookupMatcher(globalObject, availableLocales, requestedLocales)
         : bestFitMatcher(globalObject, availableLocales, requestedLocales);
 
@@ -744,13 +743,10 @@
     auto scope = DECLARE_THROW_SCOPE(vm);
     String matcher;
 
-    if (!options.isUndefined()) {
-        matcher = intlStringOption(globalObject, options, vm.propertyNames->localeMatcher, { "lookup", "best fit" }, "localeMatcher must be either \"lookup\" or \"best fit\"", "best fit");
-        RETURN_IF_EXCEPTION(scope, JSValue());
-    } else
-        matcher = "best fit"_s;
+    LocaleMatcher localeMatcher = intlOption<LocaleMatcher>(globalObject, options, vm.propertyNames->localeMatcher, { { "lookup"_s, LocaleMatcher::Lookup }, { "best fit"_s, LocaleMatcher::BestFit } }, "localeMatcher must be either \"lookup\" or \"best fit\""_s, LocaleMatcher::BestFit);
+    RETURN_IF_EXCEPTION(scope, JSValue());
 
-    JSArray* supportedLocales = (matcher == "best fit")
+    JSArray* supportedLocales = localeMatcher == LocaleMatcher::BestFit
         ? bestFitSupportedLocales(globalObject, availableLocales, requestedLocales)
         : lookupSupportedLocales(globalObject, availableLocales, requestedLocales);
     RETURN_IF_EXCEPTION(scope, JSValue());

Modified: trunk/Source/_javascript_Core/runtime/IntlObject.h (264499 => 264500)


--- trunk/Source/_javascript_Core/runtime/IntlObject.h	2020-07-17 05:18:58 UTC (rev 264499)
+++ trunk/Source/_javascript_Core/runtime/IntlObject.h	2020-07-17 06:07:57 UTC (rev 264500)
@@ -34,6 +34,11 @@
 
 namespace JSC {
 
+enum class LocaleMatcher : uint8_t {
+    Lookup,
+    BestFit,
+};
+
 class IntlObject final : public JSNonFinalObject {
 public:
     using Base = JSNonFinalObject;
@@ -71,7 +76,7 @@
 Vector<char, 32> localeIDBufferForLanguageTag(const CString&);
 String languageTagForLocaleID(const char*, bool isImmortal = false);
 Vector<String> canonicalizeLocaleList(JSGlobalObject*, JSValue locales);
-HashMap<String, String> resolveLocale(JSGlobalObject*, const HashSet<String>& availableLocales, const Vector<String>& requestedLocales, const HashMap<String, String>& options, const char* const relevantExtensionKeys[], size_t relevantExtensionKeyCount, Vector<String> (*localeData)(const String&, size_t));
+HashMap<String, String> resolveLocale(JSGlobalObject*, const HashSet<String>& availableLocales, const Vector<String>& requestedLocales, LocaleMatcher, const HashMap<String, String>& options, const char* const relevantExtensionKeys[], size_t relevantExtensionKeyCount, Vector<String> (*localeData)(const String&, size_t));
 JSValue supportedLocales(JSGlobalObject*, const HashSet<String>& availableLocales, const Vector<String>& requestedLocales, JSValue options);
 String removeUnicodeLocaleExtension(const String& locale);
 String bestAvailableLocale(const HashSet<String>& availableLocales, const String& requestedLocale);

Modified: trunk/Source/_javascript_Core/runtime/IntlObjectInlines.h (264499 => 264500)


--- trunk/Source/_javascript_Core/runtime/IntlObjectInlines.h	2020-07-17 05:18:58 UTC (rev 264499)
+++ trunk/Source/_javascript_Core/runtime/IntlObjectInlines.h	2020-07-17 06:07:57 UTC (rev 264500)
@@ -81,4 +81,39 @@
     RELEASE_AND_RETURN(scope, factory(vm));
 }
 
+template<typename ResultType>
+ResultType intlOption(JSGlobalObject* globalObject, JSValue options, PropertyName property, std::initializer_list<std::pair<ASCIILiteral, ResultType>> values, ASCIILiteral notFoundMessage, ResultType fallback)
+{
+    // GetOption (options, property, type="string", values, fallback)
+    // https://tc39.github.io/ecma402/#sec-getoption
+
+    ASSERT(values.size() > 0);
+
+    VM& vm = globalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    if (options.isUndefined())
+        return fallback;
+
+    JSObject* opts = options.toObject(globalObject);
+    RETURN_IF_EXCEPTION(scope, { });
+
+    JSValue value = opts->get(globalObject, property);
+    RETURN_IF_EXCEPTION(scope, { });
+
+    if (!value.isUndefined()) {
+        String stringValue = value.toWTFString(globalObject);
+        RETURN_IF_EXCEPTION(scope, { });
+
+        for (const auto& entry : values) {
+            if (entry.first == stringValue)
+                return entry.second;
+        }
+        throwException(globalObject, scope, createRangeError(globalObject, notFoundMessage));
+        return { };
+    }
+
+    return fallback;
+}
+
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/IntlPluralRules.cpp (264499 => 264500)


--- trunk/Source/_javascript_Core/runtime/IntlPluralRules.cpp	2020-07-17 05:18:58 UTC (rev 264499)
+++ trunk/Source/_javascript_Core/runtime/IntlPluralRules.cpp	2020-07-17 06:07:57 UTC (rev 264500)
@@ -27,7 +27,7 @@
 #include "config.h"
 #include "IntlPluralRules.h"
 
-#include "IntlObject.h"
+#include "IntlObjectInlines.h"
 #include "JSCInlines.h"
 #include "ObjectConstructor.h"
 
@@ -109,12 +109,11 @@
     }
 
     HashMap<String, String> localeOpt;
-    String localeMatcher = intlStringOption(globalObject, options, vm.propertyNames->localeMatcher, { "lookup", "best fit" }, "localeMatcher must be either \"lookup\" or \"best fit\"", "best fit");
+    LocaleMatcher localeMatcher = intlOption<LocaleMatcher>(globalObject, options, vm.propertyNames->localeMatcher, { { "lookup"_s, LocaleMatcher::Lookup }, { "best fit"_s, LocaleMatcher::BestFit } }, "localeMatcher must be either \"lookup\" or \"best fit\""_s, LocaleMatcher::BestFit);
     RETURN_IF_EXCEPTION(scope, void());
-    localeOpt.add(vm.propertyNames->localeMatcher.string(), localeMatcher);
 
     const HashSet<String>& availableLocales = intlPluralRulesAvailableLocales();
-    HashMap<String, String> resolved = resolveLocale(globalObject, availableLocales, requestedLocales, localeOpt, nullptr, 0, localeData);
+    HashMap<String, String> resolved = resolveLocale(globalObject, availableLocales, requestedLocales, localeMatcher, localeOpt, nullptr, 0, localeData);
     m_locale = resolved.get(vm.propertyNames->locale.string());
     if (m_locale.isEmpty()) {
         throwTypeError(globalObject, scope, "failed to initialize PluralRules due to invalid locale"_s);
@@ -121,9 +120,8 @@
         return;
     }
 
-    String typeString = intlStringOption(globalObject, options, vm.propertyNames->type, { "cardinal", "ordinal" }, "type must be \"cardinal\" or \"ordinal\"", "cardinal");
+    m_type = intlOption<Type>(globalObject, options, vm.propertyNames->type, { { "cardinal"_s, Type::Cardinal }, { "ordinal"_s, Type::Ordinal } }, "type must be \"cardinal\" or \"ordinal\""_s, Type::Cardinal);
     RETURN_IF_EXCEPTION(scope, void());
-    m_type = typeString == "ordinal" ? Type::Ordinal : Type::Cardinal;
 
     unsigned minimumIntegerDigits = intlNumberOption(globalObject, options, Identifier::fromString(vm, "minimumIntegerDigits"), 1, 21, 1);
     RETURN_IF_EXCEPTION(scope, void());

Modified: trunk/Source/_javascript_Core/runtime/IntlRelativeTimeFormat.cpp (264499 => 264500)


--- trunk/Source/_javascript_Core/runtime/IntlRelativeTimeFormat.cpp	2020-07-17 05:18:58 UTC (rev 264499)
+++ trunk/Source/_javascript_Core/runtime/IntlRelativeTimeFormat.cpp	2020-07-17 06:07:57 UTC (rev 264500)
@@ -27,7 +27,7 @@
 #include "IntlRelativeTimeFormat.h"
 
 #include "IntlNumberFormat.h"
-#include "IntlObject.h"
+#include "IntlObjectInlines.h"
 #include "JSCInlines.h"
 #include "ObjectConstructor.h"
 #include <wtf/unicode/icu/ICUHelpers.h>
@@ -108,9 +108,8 @@
     }
 
     HashMap<String, String> opt;
-    String localeMatcher = intlStringOption(globalObject, options, vm.propertyNames->localeMatcher, { "lookup", "best fit" }, "localeMatcher must be either \"lookup\" or \"best fit\"", "best fit");
+    LocaleMatcher localeMatcher = intlOption<LocaleMatcher>(globalObject, options, vm.propertyNames->localeMatcher, { { "lookup"_s, LocaleMatcher::Lookup }, { "best fit"_s, LocaleMatcher::BestFit } }, "localeMatcher must be either \"lookup\" or \"best fit\""_s, LocaleMatcher::BestFit);
     RETURN_IF_EXCEPTION(scope, void());
-    opt.add(vm.propertyNames->localeMatcher.string(), localeMatcher);
 
     String numberingSystem = intlStringOption(globalObject, options, vm.propertyNames->numberingSystem, { }, nullptr, nullptr);
     RETURN_IF_EXCEPTION(scope, void());
@@ -123,7 +122,7 @@
     }
 
     const HashSet<String>& availableLocales = intlRelativeTimeFormatAvailableLocales();
-    HashMap<String, String> resolved = resolveLocale(globalObject, availableLocales, requestedLocales, opt, IntlRelativeTimeFormatInternal::relevantExtensionKeys, WTF_ARRAY_LENGTH(IntlRelativeTimeFormatInternal::relevantExtensionKeys), localeData);
+    HashMap<String, String> resolved = resolveLocale(globalObject, availableLocales, requestedLocales, localeMatcher, opt, IntlRelativeTimeFormatInternal::relevantExtensionKeys, WTF_ARRAY_LENGTH(IntlRelativeTimeFormatInternal::relevantExtensionKeys), localeData);
     m_locale = resolved.get(vm.propertyNames->locale.string());
     if (m_locale.isEmpty()) {
         throwTypeError(globalObject, scope, "failed to initialize RelativeTimeFormat due to invalid locale"_s);
@@ -133,24 +132,23 @@
     m_numberingSystem = resolved.get("nu"_s);
     CString dataLocaleWithExtensions = makeString(resolved.get("dataLocale"_s), "-u-nu-", m_numberingSystem).utf8();
 
-    String style = intlStringOption(globalObject, options, vm.propertyNames->style, { "long", "short", "narrow" }, "style must be either \"long\", \"short\", or \"narrow\"", "long");
+    m_style = intlOption<Style>(globalObject, options, vm.propertyNames->style, { { "long"_s, Style::Long }, { "short"_s, Style::Short }, { "narrow"_s, Style::Narrow } }, "style must be either \"long\", \"short\", or \"narrow\""_s, Style::Long);
     RETURN_IF_EXCEPTION(scope, void());
-    UDateRelativeDateTimeFormatterStyle icuStyle;
-    if (style == "long") {
+    UDateRelativeDateTimeFormatterStyle icuStyle = UDAT_STYLE_LONG;
+    switch (m_style) {
+    case Style::Long:
         icuStyle = UDAT_STYLE_LONG;
-        m_style = Style::Long;
-    } else if (style == "short") {
+        break;
+    case Style::Short:
         icuStyle = UDAT_STYLE_SHORT;
-        m_style = Style::Short;
-    } else {
-        ASSERT(style == "narrow");
+        break;
+    case Style::Narrow:
         icuStyle = UDAT_STYLE_NARROW;
-        m_style = Style::Narrow;
+        break;
     }
 
-    String numeric = intlStringOption(globalObject, options, vm.propertyNames->numeric, { "always", "auto" }, "numeric must be either \"always\" or \"auto\"", "always");
+    m_numeric = intlOption<bool>(globalObject, options, vm.propertyNames->numeric, { { "always"_s, true }, { "auto"_s, false } }, "numeric must be either \"always\" or \"auto\""_s, true);
     RETURN_IF_EXCEPTION(scope, void());
-    m_numeric = (numeric == "always");
 
     UErrorCode status = U_ZERO_ERROR;
     m_numberFormat = std::unique_ptr<UNumberFormat, UNumberFormatDeleter>(unum_open(UNUM_DECIMAL, nullptr, 0, dataLocaleWithExtensions.data(), nullptr, &status));
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to