Ensure Intl classes don't have naming conflicts with unified builds
https://bugs.webkit.org/show_bug.cgi?id=211213

Reviewed by Yusuke Suzuki.

Each Intl class usually has an array named relevantExtensionsKeys and a function named localeData.
This can result in redefinition errors when unified builds put two of them into the same translation unit.
Some are already guarding against this with an internal namespace while others are not.

As a uniform approach, this patch makes each localeData function a static method and
puts each relevantExtensionsKeys array (as well as any constants for its indices) into an internal namespace.

Furthermore, since three different classes are defining an identical UFieldPositionIteratorDeleter,
this patch consolidates them into one definition in IntlObject.

* runtime/IntlCollator.cpp:
(JSC::IntlCollator::sortLocaleData): Renamed from JSC::sortLocaleData.
(JSC::IntlCollator::searchLocaleData): Renamed from JSC::searchLocaleData.
(JSC::IntlCollator::initializeCollator):
* runtime/IntlCollator.h:
* runtime/IntlDateTimeFormat.cpp:
(JSC::IntlDateTimeFormat::localeData): Renamed from JSC::IntlDTFInternal::localeData.
(JSC::toDateTimeOptionsAnyDate): Renamed from JSC::IntlDTFInternal::toDateTimeOptionsAnyDate.
(JSC::IntlDateTimeFormat::initializeDateTimeFormat):
(JSC::UFieldPositionIteratorDeleter::operator() const): Deleted.
* runtime/IntlDateTimeFormat.h:
* runtime/IntlNumberFormat.cpp:
(JSC::IntlNumberFormat::localeData): Renamed from JSC::IntlNFInternal::localeData.
(JSC::IntlNumberFormat::initializeNumberFormat):
(JSC::UFieldPositionIteratorDeleter::operator() const): Deleted.
* runtime/IntlNumberFormat.h:
* runtime/IntlObject.cpp:
(JSC::UFieldPositionIteratorDeleter::operator() const): Added.
* runtime/IntlObject.h:
* runtime/IntlPluralRules.cpp:
(JSC::IntlPluralRules::localeData): Renamed from JSC::localeData.
* runtime/IntlPluralRules.h:
* runtime/IntlRelativeTimeFormat.cpp:
(JSC::IntlRelativeTimeFormat::localeData): Renamed from JSC::localeData.
(JSC::IntlRelativeTimeFormat::initializeRelativeTimeFormat):
(JSC::UFieldPositionIteratorDeleter::operator() const): Deleted.
* runtime/IntlRelativeTimeFormat.h:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@260931 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/runtime/IntlCollator.cpp b/Source/JavaScriptCore/runtime/IntlCollator.cpp
index c14cec1..6d37bf0 100644
--- a/Source/JavaScriptCore/runtime/IntlCollator.cpp
+++ b/Source/JavaScriptCore/runtime/IntlCollator.cpp
@@ -43,10 +43,12 @@
 
 const ClassInfo IntlCollator::s_info = { "Object", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(IntlCollator) };
 
-static const char* const relevantCollatorExtensionKeys[3] = { "co", "kn", "kf" };
-static const size_t indexOfExtensionKeyCo = 0;
-static const size_t indexOfExtensionKeyKn = 1;
-static const size_t indexOfExtensionKeyKf = 2;
+namespace IntlCollatorInternal {
+constexpr const char* const relevantExtensionKeys[3] = { "co", "kn", "kf" };
+constexpr size_t collationIndex = 0;
+constexpr size_t numericIndex = 1;
+constexpr size_t caseFirstIndex = 2;
+}
 
 void IntlCollator::UCollatorDeleter::operator()(UCollator* collator) const
 {
@@ -87,12 +89,12 @@
     visitor.append(thisObject->m_boundCompare);
 }
 
-static Vector<String> sortLocaleData(const String& locale, size_t keyIndex)
+Vector<String> IntlCollator::sortLocaleData(const String& locale, size_t keyIndex)
 {
     // 9.1 Internal slots of Service Constructors & 10.2.3 Internal slots (ECMA-402 2.0)
     Vector<String> keyLocaleData;
     switch (keyIndex) {
-    case indexOfExtensionKeyCo: {
+    case IntlCollatorInternal::collationIndex: {
         // 10.2.3 "The first element of [[sortLocaleData]][locale].co and [[searchLocaleData]][locale].co must be null for all locale values."
         keyLocaleData.append({ });
 
@@ -121,12 +123,12 @@
         }
         break;
     }
-    case indexOfExtensionKeyKn:
+    case IntlCollatorInternal::numericIndex:
         keyLocaleData.reserveInitialCapacity(2);
         keyLocaleData.uncheckedAppend("false"_s);
         keyLocaleData.uncheckedAppend("true"_s);
         break;
-    case indexOfExtensionKeyKf:
+    case IntlCollatorInternal::caseFirstIndex:
         keyLocaleData.reserveInitialCapacity(3);
         keyLocaleData.uncheckedAppend("false"_s);
         keyLocaleData.uncheckedAppend("lower"_s);
@@ -138,22 +140,22 @@
     return keyLocaleData;
 }
 
-static Vector<String> searchLocaleData(const String&, size_t keyIndex)
+Vector<String> IntlCollator::searchLocaleData(const String&, size_t keyIndex)
 {
     // 9.1 Internal slots of Service Constructors & 10.2.3 Internal slots (ECMA-402 2.0)
     Vector<String> keyLocaleData;
     switch (keyIndex) {
-    case indexOfExtensionKeyCo:
+    case IntlCollatorInternal::collationIndex:
         // 10.2.3 "The first element of [[sortLocaleData]][locale].co and [[searchLocaleData]][locale].co must be null for all locale values."
         keyLocaleData.reserveInitialCapacity(1);
         keyLocaleData.append({ });
         break;
-    case indexOfExtensionKeyKn:
+    case IntlCollatorInternal::numericIndex:
         keyLocaleData.reserveInitialCapacity(2);
         keyLocaleData.uncheckedAppend("false"_s);
         keyLocaleData.uncheckedAppend("true"_s);
         break;
-    case indexOfExtensionKeyKf:
+    case IntlCollatorInternal::caseFirstIndex:
         keyLocaleData.reserveInitialCapacity(3);
         keyLocaleData.uncheckedAppend("false"_s);
         keyLocaleData.uncheckedAppend("lower"_s);
@@ -215,7 +217,7 @@
     }
 
     auto& availableLocales = intlCollatorAvailableLocales();
-    auto result = resolveLocale(globalObject, availableLocales, requestedLocales, opt, relevantCollatorExtensionKeys, WTF_ARRAY_LENGTH(relevantCollatorExtensionKeys), localeData);
+    auto result = resolveLocale(globalObject, availableLocales, requestedLocales, opt, IntlCollatorInternal::relevantExtensionKeys, WTF_ARRAY_LENGTH(IntlCollatorInternal::relevantExtensionKeys), localeData);
 
     m_locale = result.get("locale"_s);
     if (m_locale.isEmpty()) {
diff --git a/Source/JavaScriptCore/runtime/IntlCollator.h b/Source/JavaScriptCore/runtime/IntlCollator.h
index 48a5371..8d34977 100644
--- a/Source/JavaScriptCore/runtime/IntlCollator.h
+++ b/Source/JavaScriptCore/runtime/IntlCollator.h
@@ -67,6 +67,9 @@
     void finishCreation(VM&);
     static void visitChildren(JSCell*, SlotVisitor&);
 
+    static Vector<String> sortLocaleData(const String&, size_t);
+    static Vector<String> searchLocaleData(const String&, size_t);
+
     enum class Usage : uint8_t { Sort, Search };
     enum class Sensitivity : uint8_t { Base, Accent, Case, Variant };
     enum class CaseFirst : uint8_t { Upper, Lower, False };
diff --git a/Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp b/Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp
index 8f0ba83..b39903f 100644
--- a/Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp
+++ b/Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp
@@ -37,7 +37,6 @@
 #include <unicode/ucal.h>
 #include <unicode/udatpg.h>
 #include <unicode/uenum.h>
-#include <unicode/ufieldpositer.h>
 #include <wtf/text/StringBuilder.h>
 #include <wtf/unicode/icu/ICUHelpers.h>
 
@@ -47,22 +46,13 @@
 
 const ClassInfo IntlDateTimeFormat::s_info = { "Object", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(IntlDateTimeFormat) };
 
-namespace IntlDTFInternal {
-static const char* const relevantExtensionKeys[3] = { "ca", "nu", "hc" };
+namespace IntlDateTimeFormatInternal {
+constexpr const char* relevantExtensionKeys[3] = { "ca", "nu", "hc" };
+constexpr size_t calendarIndex = 0;
+constexpr size_t numberingSystemIndex = 1;
+constexpr size_t hourCycleIndex = 2;
 }
 
-static const size_t indexOfExtensionKeyCa = 0;
-static const size_t indexOfExtensionKeyNu = 1;
-static const size_t indexOfExtensionKeyHc = 2;
-
-struct UFieldPositionIteratorDeleter {
-    void operator()(UFieldPositionIterator* iterator) const
-    {
-        if (iterator)
-            ufieldpositer_close(iterator);
-    }
-};
-
 void IntlDateTimeFormat::UDateFormatDeleter::operator()(UDateFormat* dateFormat) const
 {
     if (dateFormat)
@@ -194,12 +184,11 @@
     return canonical;
 }
 
-namespace IntlDTFInternal {
-static Vector<String> localeData(const String& locale, size_t keyIndex)
+Vector<String> IntlDateTimeFormat::localeData(const String& locale, size_t keyIndex)
 {
     Vector<String> keyLocaleData;
     switch (keyIndex) {
-    case indexOfExtensionKeyCa: {
+    case IntlDateTimeFormatInternal::calendarIndex: {
         UErrorCode status = U_ZERO_ERROR;
         UEnumeration* calendars = ucal_getKeywordValuesForLocale("calendar", locale.utf8().data(), false, &status);
         ASSERT(U_SUCCESS(status));
@@ -220,10 +209,10 @@
         uenum_close(calendars);
         break;
     }
-    case indexOfExtensionKeyNu:
+    case IntlDateTimeFormatInternal::numberingSystemIndex:
         keyLocaleData = numberingSystemsForLocale(locale);
         break;
-    case indexOfExtensionKeyHc:
+    case IntlDateTimeFormatInternal::hourCycleIndex:
         // Null default so we know to use 'j' in pattern.
         keyLocaleData.append(String());
         keyLocaleData.append("h11"_s);
@@ -333,7 +322,6 @@
     // 9. Return options.
     return options;
 }
-}
 
 void IntlDateTimeFormat::setFormatsFromPattern(const StringView& pattern)
 {
@@ -449,7 +437,7 @@
     Vector<String> requestedLocales = canonicalizeLocaleList(globalObject, locales);
     RETURN_IF_EXCEPTION(scope, void());
 
-    JSObject* options = IntlDTFInternal::toDateTimeOptionsAnyDate(globalObject, originalOptions);
+    JSObject* options = toDateTimeOptionsAnyDate(globalObject, originalOptions);
     RETURN_IF_EXCEPTION(scope, void());
 
     HashMap<String, String> opt;
@@ -493,7 +481,7 @@
         opt.add("hc"_s, String());
 
     const HashSet<String>& availableLocales = intlDateTimeFormatAvailableLocales();
-    HashMap<String, String> resolved = resolveLocale(globalObject, availableLocales, requestedLocales, opt, IntlDTFInternal::relevantExtensionKeys, WTF_ARRAY_LENGTH(IntlDTFInternal::relevantExtensionKeys), IntlDTFInternal::localeData);
+    HashMap<String, String> resolved = resolveLocale(globalObject, availableLocales, requestedLocales, opt, IntlDateTimeFormatInternal::relevantExtensionKeys, WTF_ARRAY_LENGTH(IntlDateTimeFormatInternal::relevantExtensionKeys), localeData);
 
     m_locale = resolved.get(vm.propertyNames->locale.string());
     if (m_locale.isEmpty()) {
diff --git a/Source/JavaScriptCore/runtime/IntlDateTimeFormat.h b/Source/JavaScriptCore/runtime/IntlDateTimeFormat.h
index e5c94e9..bd94387 100644
--- a/Source/JavaScriptCore/runtime/IntlDateTimeFormat.h
+++ b/Source/JavaScriptCore/runtime/IntlDateTimeFormat.h
@@ -67,6 +67,8 @@
     void finishCreation(VM&);
     static void visitChildren(JSCell*, SlotVisitor&);
 
+    static Vector<String> localeData(const String&, size_t);
+
     enum class Weekday : uint8_t { None, Narrow, Short, Long };
     enum class Era : uint8_t { None, Narrow, Short, Long };
     enum class Year : uint8_t { None, TwoDigit, Numeric };
diff --git a/Source/JavaScriptCore/runtime/IntlNumberFormat.cpp b/Source/JavaScriptCore/runtime/IntlNumberFormat.cpp
index 45f3379..60ce128 100644
--- a/Source/JavaScriptCore/runtime/IntlNumberFormat.cpp
+++ b/Source/JavaScriptCore/runtime/IntlNumberFormat.cpp
@@ -36,22 +36,15 @@
 #include "JSBoundFunction.h"
 #include "JSCInlines.h"
 #include "ObjectConstructor.h"
-#include <unicode/ufieldpositer.h>
 #include <wtf/unicode/icu/ICUHelpers.h>
 
 namespace JSC {
 
 const ClassInfo IntlNumberFormat::s_info = { "Object", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(IntlNumberFormat) };
 
-static const char* const relevantNumberExtensionKeys[1] = { "nu" };
-
-struct UFieldPositionIteratorDeleter {
-    void operator()(UFieldPositionIterator* iterator) const
-    {
-        if (iterator)
-            ufieldpositer_close(iterator);
-    }
-};
+namespace IntlNumberFormatInternal {
+constexpr const char* relevantExtensionKeys[1] = { "nu" };
+}
 
 struct IntlNumberFormatField {
     int32_t type;
@@ -97,14 +90,12 @@
     visitor.append(thisObject->m_boundFormat);
 }
 
-namespace IntlNFInternal {
-static Vector<String> localeData(const String& locale, size_t keyIndex)
+Vector<String> IntlNumberFormat::localeData(const String& locale, size_t keyIndex)
 {
     // 9.1 Internal slots of Service Constructors & 11.2.3 Internal slots (ECMA-402 2.0)
     ASSERT_UNUSED(keyIndex, !keyIndex); // The index of the extension key "nu" in relevantExtensionKeys is 0.
     return numberingSystemsForLocale(locale);
 }
-}
 
 static inline unsigned computeCurrencySortKey(const String& currency)
 {
@@ -198,7 +189,7 @@
     }
 
     auto& availableLocales = intlNumberFormatAvailableLocales();
-    auto result = resolveLocale(globalObject, availableLocales, requestedLocales, opt, relevantNumberExtensionKeys, WTF_ARRAY_LENGTH(relevantNumberExtensionKeys), IntlNFInternal::localeData);
+    auto result = resolveLocale(globalObject, availableLocales, requestedLocales, opt, IntlNumberFormatInternal::relevantExtensionKeys, WTF_ARRAY_LENGTH(IntlNumberFormatInternal::relevantExtensionKeys), localeData);
 
     m_locale = result.get("locale"_s);
     if (m_locale.isEmpty()) {
diff --git a/Source/JavaScriptCore/runtime/IntlNumberFormat.h b/Source/JavaScriptCore/runtime/IntlNumberFormat.h
index f5c62ad..e5aaeb4 100644
--- a/Source/JavaScriptCore/runtime/IntlNumberFormat.h
+++ b/Source/JavaScriptCore/runtime/IntlNumberFormat.h
@@ -71,6 +71,8 @@
     void finishCreation(VM&);
     static void visitChildren(JSCell*, SlotVisitor&);
 
+    static Vector<String> localeData(const String&, size_t);
+
     enum class Style : uint8_t { Decimal, Percent, Currency };
     enum class CurrencyDisplay : uint8_t { Code, Symbol, Name };
 
diff --git a/Source/JavaScriptCore/runtime/IntlObject.cpp b/Source/JavaScriptCore/runtime/IntlObject.cpp
index dab37e7..88f1970 100644
--- a/Source/JavaScriptCore/runtime/IntlObject.cpp
+++ b/Source/JavaScriptCore/runtime/IntlObject.cpp
@@ -47,6 +47,7 @@
 #include "ObjectPrototype.h"
 #include "Options.h"
 #include <unicode/ucol.h>
+#include <unicode/ufieldpositer.h>
 #include <unicode/uloc.h>
 #include <unicode/unumsys.h>
 #include <wtf/Assertions.h>
@@ -114,6 +115,12 @@
 
 const ClassInfo IntlObject::s_info = { "Object", &Base::s_info, &intlObjectTable, nullptr, CREATE_METHOD_TABLE(IntlObject) };
 
+void UFieldPositionIteratorDeleter::operator()(UFieldPositionIterator* iterator) const
+{
+    if (iterator)
+        ufieldpositer_close(iterator);
+}
+
 IntlObject::IntlObject(VM& vm, Structure* structure)
     : Base(vm, structure)
 {
diff --git a/Source/JavaScriptCore/runtime/IntlObject.h b/Source/JavaScriptCore/runtime/IntlObject.h
index 6af6f73..f1122f4 100644
--- a/Source/JavaScriptCore/runtime/IntlObject.h
+++ b/Source/JavaScriptCore/runtime/IntlObject.h
@@ -30,6 +30,8 @@
 #include "JSCJSValueInlines.h"
 #include "JSObject.h"
 
+struct UFieldPositionIterator;
+
 namespace JSC {
 
 class IntlObject final : public JSNonFinalObject {
@@ -75,4 +77,8 @@
 
 bool isUnicodeLocaleIdentifierType(StringView);
 
+struct UFieldPositionIteratorDeleter {
+    void operator()(UFieldPositionIterator*) const;
+};
+
 } // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/IntlPluralRules.cpp b/Source/JavaScriptCore/runtime/IntlPluralRules.cpp
index b2f19188..7994f71 100644
--- a/Source/JavaScriptCore/runtime/IntlPluralRules.cpp
+++ b/Source/JavaScriptCore/runtime/IntlPluralRules.cpp
@@ -88,7 +88,7 @@
     Base::visitChildren(thisObject, visitor);
 }
 
-static Vector<String> localeData(const String&, size_t)
+Vector<String> IntlPluralRules::localeData(const String&, size_t)
 {
     return { };
 }
diff --git a/Source/JavaScriptCore/runtime/IntlPluralRules.h b/Source/JavaScriptCore/runtime/IntlPluralRules.h
index 708d79b..cb66e94 100644
--- a/Source/JavaScriptCore/runtime/IntlPluralRules.h
+++ b/Source/JavaScriptCore/runtime/IntlPluralRules.h
@@ -62,6 +62,8 @@
     void finishCreation(VM&);
     static void visitChildren(JSCell*, SlotVisitor&);
 
+    static Vector<String> localeData(const String&, size_t);
+
     struct UPluralRulesDeleter {
         void operator()(UPluralRules*) const;
     };
diff --git a/Source/JavaScriptCore/runtime/IntlRelativeTimeFormat.cpp b/Source/JavaScriptCore/runtime/IntlRelativeTimeFormat.cpp
index 7140efa..0b40c21 100644
--- a/Source/JavaScriptCore/runtime/IntlRelativeTimeFormat.cpp
+++ b/Source/JavaScriptCore/runtime/IntlRelativeTimeFormat.cpp
@@ -37,15 +37,9 @@
 
 const ClassInfo IntlRelativeTimeFormat::s_info = { "Object", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(IntlRelativeTimeFormat) };
 
+namespace IntlRelativeTimeFormatInternal {
 constexpr const char* relevantExtensionKeys[1] = { "nu" };
-
-struct UFieldPositionIteratorDeleter {
-    void operator()(UFieldPositionIterator* iterator) const
-    {
-        if (iterator)
-            ufieldpositer_close(iterator);
-    }
-};
+}
 
 void IntlRelativeTimeFormat::URelativeDateTimeFormatterDeleter::operator()(URelativeDateTimeFormatter* relativeDateTimeFormatter) const
 {
@@ -90,7 +84,7 @@
     Base::visitChildren(thisObject, visitor);
 }
 
-static Vector<String> localeData(const String& locale, size_t keyIndex)
+Vector<String> IntlRelativeTimeFormat::localeData(const String& locale, size_t keyIndex)
 {
     // The index of the extension key "nu" in relevantExtensionKeys is 0.
     ASSERT_UNUSED(keyIndex, !keyIndex);
@@ -130,7 +124,7 @@
     }
 
     const HashSet<String>& availableLocales = intlRelativeTimeFormatAvailableLocales();
-    HashMap<String, String> resolved = resolveLocale(globalObject, availableLocales, requestedLocales, opt, relevantExtensionKeys, WTF_ARRAY_LENGTH(relevantExtensionKeys), localeData);
+    HashMap<String, String> resolved = resolveLocale(globalObject, availableLocales, requestedLocales, 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);
diff --git a/Source/JavaScriptCore/runtime/IntlRelativeTimeFormat.h b/Source/JavaScriptCore/runtime/IntlRelativeTimeFormat.h
index e721930..e1405cf 100644
--- a/Source/JavaScriptCore/runtime/IntlRelativeTimeFormat.h
+++ b/Source/JavaScriptCore/runtime/IntlRelativeTimeFormat.h
@@ -26,7 +26,6 @@
 #pragma once
 
 #include "JSObject.h"
-#include <unicode/ufieldpositer.h>
 #include <unicode/ureldatefmt.h>
 
 namespace JSC {
@@ -63,6 +62,8 @@
     void finishCreation(VM&);
     static void visitChildren(JSCell*, SlotVisitor&);
 
+    static Vector<String> localeData(const String&, size_t);
+
     String formatInternal(JSGlobalObject*, double, StringView unit);
 
     struct URelativeDateTimeFormatterDeleter {