LCOV - code coverage report
Current view: top level - src/objects - intl-objects.h (source / functions) Hit Total Coverage
Test: app.info Lines: 14 16 87.5 %
Date: 2019-04-17 Functions: 22 32 68.8 %

          Line data    Source code
       1             : // Copyright 2013 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_INTL_SUPPORT
       6             : #error Internationalization is expected to be enabled.
       7             : #endif  // V8_INTL_SUPPORT
       8             : 
       9             : #ifndef V8_OBJECTS_INTL_OBJECTS_H_
      10             : #define V8_OBJECTS_INTL_OBJECTS_H_
      11             : 
      12             : #include <map>
      13             : #include <set>
      14             : #include <string>
      15             : 
      16             : #include "src/base/timezone-cache.h"
      17             : #include "src/contexts.h"
      18             : #include "src/objects.h"
      19             : #include "src/objects/managed.h"
      20             : #include "unicode/locid.h"
      21             : #include "unicode/uversion.h"
      22             : 
      23             : #define V8_MINIMUM_ICU_VERSION 64
      24             : 
      25             : namespace U_ICU_NAMESPACE {
      26             : class BreakIterator;
      27             : class Collator;
      28             : class DecimalFormat;
      29             : class SimpleDateFormat;
      30             : class UnicodeString;
      31             : }
      32             : 
      33             : namespace v8 {
      34             : namespace internal {
      35             : 
      36             : template <typename T>
      37             : class Handle;
      38             : class JSCollator;
      39             : 
      40             : class Intl {
      41             :  public:
      42             :   enum class BoundFunctionContextSlot {
      43             :     kBoundFunction = Context::MIN_CONTEXT_SLOTS,
      44             :     kLength
      45             :   };
      46             : 
      47             :   // Build a set of ICU locales from a list of Locales. If there is a locale
      48             :   // with a script tag then the locales also include a locale without the
      49             :   // script; eg, pa_Guru_IN (language=Panjabi, script=Gurmukhi, country-India)
      50             :   // would include pa_IN.
      51             :   static std::set<std::string> BuildLocaleSet(
      52             :       const icu::Locale* icu_available_locales, int32_t count);
      53             : 
      54             :   static Maybe<std::string> ToLanguageTag(const icu::Locale& locale);
      55             : 
      56             :   // Get the name of the numbering system from locale.
      57             :   // ICU doesn't expose numbering system in any way, so we have to assume that
      58             :   // for given locale NumberingSystem constructor produces the same digits as
      59             :   // NumberFormat/Calendar would.
      60             :   static std::string GetNumberingSystem(const icu::Locale& icu_locale);
      61             : 
      62             :   static V8_WARN_UNUSED_RESULT MaybeHandle<JSObject> SupportedLocalesOf(
      63             :       Isolate* isolate, const char* method,
      64             :       const std::set<std::string>& available_locales, Handle<Object> locales_in,
      65             :       Handle<Object> options_in);
      66             : 
      67             :   // ECMA402 9.2.10. GetOption( options, property, type, values, fallback)
      68             :   // ecma402/#sec-getoption
      69             :   //
      70             :   // This is specialized for the case when type is string.
      71             :   //
      72             :   // Instead of passing undefined for the values argument as the spec
      73             :   // defines, pass in an empty vector.
      74             :   //
      75             :   // Returns true if options object has the property and stores the
      76             :   // result in value. Returns false if the value is not found. The
      77             :   // caller is required to use fallback value appropriately in this
      78             :   // case.
      79             :   //
      80             :   // service is a string denoting the type of Intl object; used when
      81             :   // printing the error message.
      82             :   V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool> GetStringOption(
      83             :       Isolate* isolate, Handle<JSReceiver> options, const char* property,
      84             :       std::vector<const char*> values, const char* service,
      85             :       std::unique_ptr<char[]>* result);
      86             : 
      87             :   // A helper template to get string from option into a enum.
      88             :   // The enum in the enum_values is the corresponding value to the strings
      89             :   // in the str_values. If the option does not contains name,
      90             :   // default_value will be return.
      91             :   template <typename T>
      92       50268 :   V8_WARN_UNUSED_RESULT static Maybe<T> GetStringOption(
      93             :       Isolate* isolate, Handle<JSReceiver> options, const char* name,
      94             :       const char* method, const std::vector<const char*>& str_values,
      95             :       const std::vector<T>& enum_values, T default_value) {
      96             :     DCHECK_EQ(str_values.size(), enum_values.size());
      97       50268 :     std::unique_ptr<char[]> cstr;
      98      100536 :     Maybe<bool> found = Intl::GetStringOption(isolate, options, name,
      99       50268 :                                               str_values, method, &cstr);
     100       50268 :     MAYBE_RETURN(found, Nothing<T>());
     101       49890 :     if (found.FromJust()) {
     102             :       DCHECK_NOT_NULL(cstr.get());
     103       10521 :       for (size_t i = 0; i < str_values.size(); i++) {
     104       14202 :         if (strcmp(cstr.get(), str_values[i]) == 0) {
     105             :           return Just(enum_values[i]);
     106             :         }
     107             :       }
     108           0 :       UNREACHABLE();
     109             :     }
     110             :     return Just(default_value);
     111             :   }
     112             : 
     113             :   // ECMA402 9.2.10. GetOption( options, property, type, values, fallback)
     114             :   // ecma402/#sec-getoption
     115             :   //
     116             :   // This is specialized for the case when type is boolean.
     117             :   //
     118             :   // Returns true if options object has the property and stores the
     119             :   // result in value. Returns false if the value is not found. The
     120             :   // caller is required to use fallback value appropriately in this
     121             :   // case.
     122             :   //
     123             :   // service is a string denoting the type of Intl object; used when
     124             :   // printing the error message.
     125             :   V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool> GetBoolOption(
     126             :       Isolate* isolate, Handle<JSReceiver> options, const char* property,
     127             :       const char* service, bool* result);
     128             : 
     129             :   // Canonicalize the locale.
     130             :   // https://tc39.github.io/ecma402/#sec-canonicalizelanguagetag,
     131             :   // including type check and structural validity check.
     132             :   static Maybe<std::string> CanonicalizeLanguageTag(Isolate* isolate,
     133             :                                                     Handle<Object> locale_in);
     134             : 
     135             :   static Maybe<std::string> CanonicalizeLanguageTag(Isolate* isolate,
     136             :                                                     const std::string& locale);
     137             : 
     138             :   // https://tc39.github.io/ecma402/#sec-canonicalizelocalelist
     139             :   // {only_return_one_result} is an optimization for callers that only
     140             :   // care about the first result.
     141             :   static Maybe<std::vector<std::string>> CanonicalizeLocaleList(
     142             :       Isolate* isolate, Handle<Object> locales,
     143             :       bool only_return_one_result = false);
     144             : 
     145             :   // ecma-402 #sec-intl.getcanonicallocales
     146             :   V8_WARN_UNUSED_RESULT static MaybeHandle<JSArray> GetCanonicalLocales(
     147             :       Isolate* isolate, Handle<Object> locales);
     148             : 
     149             :   // For locale sensitive functions
     150             :   V8_WARN_UNUSED_RESULT static MaybeHandle<String> StringLocaleConvertCase(
     151             :       Isolate* isolate, Handle<String> s, bool is_upper,
     152             :       Handle<Object> locales);
     153             : 
     154             :   V8_WARN_UNUSED_RESULT static MaybeHandle<String> ConvertToUpper(
     155             :       Isolate* isolate, Handle<String> s);
     156             : 
     157             :   V8_WARN_UNUSED_RESULT static MaybeHandle<String> ConvertToLower(
     158             :       Isolate* isolate, Handle<String> s);
     159             : 
     160             :   V8_WARN_UNUSED_RESULT static MaybeHandle<Object> StringLocaleCompare(
     161             :       Isolate* isolate, Handle<String> s1, Handle<String> s2,
     162             :       Handle<Object> locales, Handle<Object> options);
     163             : 
     164             :   V8_WARN_UNUSED_RESULT static Handle<Object> CompareStrings(
     165             :       Isolate* isolate, const icu::Collator& collator, Handle<String> s1,
     166             :       Handle<String> s2);
     167             : 
     168             :   // ecma402/#sup-properties-of-the-number-prototype-object
     169             :   V8_WARN_UNUSED_RESULT static MaybeHandle<String> NumberToLocaleString(
     170             :       Isolate* isolate, Handle<Object> num, Handle<Object> locales,
     171             :       Handle<Object> options);
     172             : 
     173             :   // ecma402/#sec-setnfdigitoptions
     174             :   V8_WARN_UNUSED_RESULT static Maybe<bool> SetNumberFormatDigitOptions(
     175             :       Isolate* isolate, icu::DecimalFormat* number_format,
     176             :       Handle<JSReceiver> options, int mnfd_default, int mxfd_default);
     177             : 
     178             :   static icu::Locale CreateICULocale(const std::string& bcp47_locale);
     179             : 
     180             :   // Helper funciton to convert a UnicodeString to a Handle<String>
     181             :   V8_WARN_UNUSED_RESULT static MaybeHandle<String> ToString(
     182             :       Isolate* isolate, const icu::UnicodeString& string);
     183             : 
     184             :   // Helper function to convert a substring of UnicodeString to a Handle<String>
     185             :   V8_WARN_UNUSED_RESULT static MaybeHandle<String> ToString(
     186             :       Isolate* isolate, const icu::UnicodeString& string, int32_t begin,
     187             :       int32_t end);
     188             : 
     189             :   // Helper function to convert number field id to type string.
     190             :   static Handle<String> NumberFieldToType(Isolate* isolate,
     191             :                                           Handle<Object> numeric_obj,
     192             :                                           int32_t field_id);
     193             : 
     194             :   // A helper function to implement formatToParts which add element to array as
     195             :   // $array[$index] = { type: $field_type_string, value: $value }
     196             :   static void AddElement(Isolate* isolate, Handle<JSArray> array, int index,
     197             :                          Handle<String> field_type_string,
     198             :                          Handle<String> value);
     199             : 
     200             :   // A helper function to implement formatToParts which add element to array as
     201             :   // $array[$index] = {
     202             :   //   type: $field_type_string, value: $value,
     203             :   //   $additional_property_name: $additional_property_value
     204             :   // }
     205             :   static void AddElement(Isolate* isolate, Handle<JSArray> array, int index,
     206             :                          Handle<String> field_type_string, Handle<String> value,
     207             :                          Handle<String> additional_property_name,
     208             :                          Handle<String> additional_property_value);
     209             : 
     210             :   // In ECMA 402 v1, Intl constructors supported a mode of operation
     211             :   // where calling them with an existing object as a receiver would
     212             :   // transform the receiver into the relevant Intl instance with all
     213             :   // internal slots. In ECMA 402 v2, this capability was removed, to
     214             :   // avoid adding internal slots on existing objects. In ECMA 402 v3,
     215             :   // the capability was re-added as "normative optional" in a mode
     216             :   // which chains the underlying Intl instance on any object, when the
     217             :   // constructor is called
     218             :   //
     219             :   // See ecma402/#legacy-constructor.
     220             :   V8_WARN_UNUSED_RESULT static MaybeHandle<Object> LegacyUnwrapReceiver(
     221             :       Isolate* isolate, Handle<JSReceiver> receiver,
     222             :       Handle<JSFunction> constructor, bool has_initialized_slot);
     223             : 
     224             :   // enum for "caseFirst" option: shared by Intl.Locale and Intl.Collator.
     225             :   enum class CaseFirst { kUpper, kLower, kFalse, kUndefined };
     226             : 
     227             :   // Shared function to read the "caseFirst" option.
     228             :   V8_WARN_UNUSED_RESULT static Maybe<CaseFirst> GetCaseFirst(
     229             :       Isolate* isolate, Handle<JSReceiver> options, const char* method);
     230             : 
     231             :   // enum for "hourCycle" option: shared by Intl.Locale and Intl.DateTimeFormat.
     232             :   enum class HourCycle { kH11, kH12, kH23, kH24, kUndefined };
     233             : 
     234             :   static HourCycle ToHourCycle(const std::string& str);
     235             : 
     236             :   // Shared function to read the "hourCycle" option.
     237             :   V8_WARN_UNUSED_RESULT static Maybe<HourCycle> GetHourCycle(
     238             :       Isolate* isolate, Handle<JSReceiver> options, const char* method);
     239             : 
     240             :   // enum for "localeMatcher" option: shared by many Intl objects.
     241             :   enum class MatcherOption { kBestFit, kLookup };
     242             : 
     243             :   // Shared function to read the "localeMatcher" option.
     244             :   V8_WARN_UNUSED_RESULT static Maybe<MatcherOption> GetLocaleMatcher(
     245             :       Isolate* isolate, Handle<JSReceiver> options, const char* method);
     246             : 
     247       44652 :   struct ResolvedLocale {
     248             :     std::string locale;
     249             :     icu::Locale icu_locale;
     250             :     std::map<std::string, std::string> extensions;
     251             :   };
     252             : 
     253             :   static ResolvedLocale ResolveLocale(
     254             :       Isolate* isolate, const std::set<std::string>& available_locales,
     255             :       const std::vector<std::string>& requested_locales, MatcherOption options,
     256             :       const std::set<std::string>& relevant_extension_keys);
     257             : 
     258             :   // A helper template to implement the GetAvailableLocales
     259             :   // Usage in src/objects/js-XXX.cc
     260             :   //
     261             :   // const std::set<std::string>& JSXxx::GetAvailableLocales() {
     262             :   //   static base::LazyInstance<Intl::AvailableLocales<icu::YYY>>::type
     263             :   //       available_locales = LAZY_INSTANCE_INITIALIZER;
     264             :   //   return available_locales.Pointer()->Get();
     265             :   // }
     266             :   template <typename T>
     267             :   class AvailableLocales {
     268             :    public:
     269        1039 :     AvailableLocales() {
     270        1039 :       int32_t num_locales = 0;
     271             :       const icu::Locale* icu_available_locales =
     272        1039 :           T::getAvailableLocales(num_locales);
     273        2078 :       set = Intl::BuildLocaleSet(icu_available_locales, num_locales);
     274        1039 :     }
     275           0 :     virtual ~AvailableLocales() {}
     276             :     const std::set<std::string>& Get() const { return set; }
     277             : 
     278             :    private:
     279             :     std::set<std::string> set;
     280             :   };
     281             : 
     282             :   // Utility function to set text to BreakIterator.
     283             :   static Managed<icu::UnicodeString> SetTextToBreakIterator(
     284             :       Isolate* isolate, Handle<String> text,
     285             :       icu::BreakIterator* break_iterator);
     286             : 
     287             :   // ecma262 #sec-string.prototype.normalize
     288             :   V8_WARN_UNUSED_RESULT static MaybeHandle<String> Normalize(
     289             :       Isolate* isolate, Handle<String> string, Handle<Object> form_input);
     290             :   static base::TimezoneCache* CreateTimeZoneCache();
     291             : 
     292             :   // Convert a Handle<String> to icu::UnicodeString
     293             :   static icu::UnicodeString ToICUUnicodeString(Isolate* isolate,
     294             :                                                Handle<String> string);
     295             : 
     296             :   static const uint8_t* ToLatin1LowerTable();
     297             : 
     298             :   static String ConvertOneByteToLower(String src, String dst);
     299             : 
     300             :   static const std::set<std::string>& GetAvailableLocalesForLocale();
     301             : 
     302             :   static const std::set<std::string>& GetAvailableLocalesForDateFormat();
     303             : };
     304             : 
     305             : }  // namespace internal
     306             : }  // namespace v8
     307             : 
     308             : #endif  // V8_OBJECTS_INTL_OBJECTS_H_

Generated by: LCOV version 1.10