/ runtime / IntlObject.h
IntlObject.h
  1  /*
  2   * Copyright (C) 2015 Andy VanWagoner (andy@vanwagoner.family)
  3   * Copyright (C) 2019-2020 Apple Inc. All rights reserved.
  4   * Copyright (C) 2020 Sony Interactive Entertainment Inc.
  5   *
  6   * Redistribution and use in source and binary forms, with or without
  7   * modification, are permitted provided that the following conditions
  8   * are met:
  9   * 1. Redistributions of source code must retain the above copyright
 10   *    notice, this list of conditions and the following disclaimer.
 11   * 2. Redistributions in binary form must reproduce the above copyright
 12   *    notice, this list of conditions and the following disclaimer in the
 13   *    documentation and/or other materials provided with the distribution.
 14   *
 15   * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 16   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 17   * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 18   * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 19   * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 20   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 21   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 22   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 23   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 24   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 25   * THE POSSIBILITY OF SUCH DAMAGE.
 26   */
 27  
 28  #pragma once
 29  
 30  #include "JSCJSValueInlines.h"
 31  #include "JSObject.h"
 32  
 33  struct UFieldPositionIterator;
 34  
 35  namespace JSC {
 36  
 37  extern const uint8_t ducetWeights[128];
 38  
 39  enum class LocaleMatcher : uint8_t {
 40      Lookup,
 41      BestFit,
 42  };
 43  
 44  #define JSC_INTL_RELEVANT_EXTENSION_KEYS(macro) \
 45      macro(ca, Ca) /* calendar */ \
 46      macro(co, Co) /* collation */ \
 47      macro(hc, Hc) /* hour-cycle */ \
 48      macro(kf, Kf) /* case-first */ \
 49      macro(kn, Kn) /* numeric */ \
 50      macro(nu, Nu) /* numbering-system */ \
 51  
 52  enum class RelevantExtensionKey : uint8_t {
 53  #define JSC_DECLARE_INTL_RELEVANT_EXTENSION_KEYS(lowerName, capitalizedName) capitalizedName,
 54  JSC_INTL_RELEVANT_EXTENSION_KEYS(JSC_DECLARE_INTL_RELEVANT_EXTENSION_KEYS)
 55  #undef JSC_DECLARE_INTL_RELEVANT_EXTENSION_KEYS
 56  };
 57  #define JSC_COUNT_INTL_RELEVANT_EXTENSION_KEYS(lowerName, capitalizedName) + 1
 58  static constexpr uint8_t numberOfRelevantExtensionKeys = 0 JSC_INTL_RELEVANT_EXTENSION_KEYS(JSC_COUNT_INTL_RELEVANT_EXTENSION_KEYS);
 59  #undef JSC_COUNT_INTL_RELEVANT_EXTENSION_KEYS
 60  
 61  class IntlObject final : public JSNonFinalObject {
 62  public:
 63      using Base = JSNonFinalObject;
 64      static constexpr unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable;
 65  
 66      template<typename CellType, SubspaceAccess>
 67      static IsoSubspace* subspaceFor(VM& vm)
 68      {
 69          STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(IntlObject, Base);
 70          return &vm.plainObjectSpace;
 71      }
 72  
 73      static IntlObject* create(VM&, JSGlobalObject*, Structure*);
 74      static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
 75  
 76      DECLARE_INFO;
 77  
 78  private:
 79      IntlObject(VM&, Structure*);
 80      void finishCreation(VM&, JSGlobalObject*);
 81  };
 82  
 83  String defaultLocale(JSGlobalObject*);
 84  const HashSet<String>& intlAvailableLocales();
 85  const HashSet<String>& intlCollatorAvailableLocales();
 86  const HashSet<String>& intlSegmenterAvailableLocales();
 87  inline const HashSet<String>& intlDateTimeFormatAvailableLocales() { return intlAvailableLocales(); }
 88  inline const HashSet<String>& intlDisplayNamesAvailableLocales() { return intlAvailableLocales(); }
 89  inline const HashSet<String>& intlNumberFormatAvailableLocales() { return intlAvailableLocales(); }
 90  inline const HashSet<String>& intlPluralRulesAvailableLocales() { return intlAvailableLocales(); }
 91  inline const HashSet<String>& intlRelativeTimeFormatAvailableLocales() { return intlAvailableLocales(); }
 92  inline const HashSet<String>& intlListFormatAvailableLocales() { return intlAvailableLocales(); }
 93  
 94  TriState intlBooleanOption(JSGlobalObject*, JSValue options, PropertyName);
 95  String intlStringOption(JSGlobalObject*, JSValue options, PropertyName, std::initializer_list<const char*> values, const char* notFound, const char* fallback);
 96  unsigned intlNumberOption(JSGlobalObject*, JSValue options, PropertyName, unsigned minimum, unsigned maximum, unsigned fallback);
 97  unsigned intlDefaultNumberOption(JSGlobalObject*, JSValue, PropertyName, unsigned minimum, unsigned maximum, unsigned fallback);
 98  Vector<char, 32> localeIDBufferForLanguageTag(const CString&);
 99  String languageTagForLocaleID(const char*, bool isImmortal = false);
100  Vector<String> canonicalizeLocaleList(JSGlobalObject*, JSValue locales);
101  
102  using ResolveLocaleOptions = std::array<Optional<String>, numberOfRelevantExtensionKeys>;
103  using RelevantExtensions = std::array<String, numberOfRelevantExtensionKeys>;
104  struct ResolvedLocale {
105      String locale;
106      String dataLocale;
107      RelevantExtensions extensions;
108  };
109  
110  ResolvedLocale resolveLocale(JSGlobalObject*, const HashSet<String>& availableLocales, const Vector<String>& requestedLocales, LocaleMatcher, const ResolveLocaleOptions&, std::initializer_list<RelevantExtensionKey> relevantExtensionKeys, Vector<String> (*localeData)(const String&, RelevantExtensionKey));
111  JSValue supportedLocales(JSGlobalObject*, const HashSet<String>& availableLocales, const Vector<String>& requestedLocales, JSValue options);
112  String removeUnicodeLocaleExtension(const String& locale);
113  String bestAvailableLocale(const HashSet<String>& availableLocales, const String& requestedLocale);
114  template<typename Predicate> String bestAvailableLocale(const String& requestedLocale, Predicate);
115  Vector<String> numberingSystemsForLocale(const String& locale);
116  
117  Vector<char, 32> canonicalizeUnicodeExtensionsAfterICULocaleCanonicalization(Vector<char, 32>&&);
118  
119  bool isUnicodeLocaleIdentifierType(StringView);
120  
121  bool isUnicodeLanguageSubtag(StringView);
122  bool isUnicodeScriptSubtag(StringView);
123  bool isUnicodeRegionSubtag(StringView);
124  bool isUnicodeVariantSubtag(StringView);
125  bool isUnicodeLanguageId(StringView);
126  bool isStructurallyValidLanguageTag(StringView);
127  
128  bool isWellFormedCurrencyCode(StringView);
129  
130  struct UFieldPositionIteratorDeleter {
131      void operator()(UFieldPositionIterator*) const;
132  };
133  
134  } // namespace JSC