LCOV - code coverage report
Current view: top level - src/objects - js-segmenter.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 38 46 82.6 %
Date: 2019-03-21 Functions: 5 6 83.3 %

          Line data    Source code
       1             : // Copyright 2018 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             : #include "src/objects/js-segmenter.h"
      10             : 
      11             : #include <map>
      12             : #include <memory>
      13             : #include <string>
      14             : 
      15             : #include "src/heap/factory.h"
      16             : #include "src/isolate.h"
      17             : #include "src/objects-inl.h"
      18             : #include "src/objects/intl-objects.h"
      19             : #include "src/objects/js-segmenter-inl.h"
      20             : #include "src/objects/managed.h"
      21             : #include "unicode/brkiter.h"
      22             : 
      23             : namespace v8 {
      24             : namespace internal {
      25             : 
      26           0 : JSSegmenter::Granularity JSSegmenter::GetGranularity(const char* str) {
      27           0 :   if (strcmp(str, "grapheme") == 0) return JSSegmenter::Granularity::GRAPHEME;
      28           0 :   if (strcmp(str, "word") == 0) return JSSegmenter::Granularity::WORD;
      29           0 :   if (strcmp(str, "sentence") == 0) return JSSegmenter::Granularity::SENTENCE;
      30           0 :   UNREACHABLE();
      31             : }
      32             : 
      33         630 : MaybeHandle<JSSegmenter> JSSegmenter::Initialize(
      34             :     Isolate* isolate, Handle<JSSegmenter> segmenter_holder,
      35             :     Handle<Object> locales, Handle<Object> input_options) {
      36             :   segmenter_holder->set_flags(0);
      37             : 
      38             :   // 3. Let requestedLocales be ? CanonicalizeLocaleList(locales).
      39             :   Maybe<std::vector<std::string>> maybe_requested_locales =
      40         630 :       Intl::CanonicalizeLocaleList(isolate, locales);
      41         630 :   MAYBE_RETURN(maybe_requested_locales, Handle<JSSegmenter>());
      42             :   std::vector<std::string> requested_locales =
      43         621 :       maybe_requested_locales.FromJust();
      44             : 
      45             :   // 11. If options is undefined, then
      46             :   Handle<JSReceiver> options;
      47         621 :   if (input_options->IsUndefined(isolate)) {
      48             :     // 11. a. Let options be ObjectCreate(null).
      49         171 :     options = isolate->factory()->NewJSObjectWithNullProto();
      50             :     // 12. Else
      51             :   } else {
      52             :     // 23. a. Let options be ? ToObject(options).
      53         900 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, options,
      54             :                                Object::ToObject(isolate, input_options),
      55             :                                JSSegmenter);
      56             :   }
      57             : 
      58             :   // 4. Let opt be a new Record.
      59             :   // 5. Let matcher be ? GetOption(options, "localeMatcher", "string",
      60             :   // « "lookup", "best fit" », "best fit").
      61             :   // 6. Set opt.[[localeMatcher]] to matcher.
      62             :   Maybe<Intl::MatcherOption> maybe_locale_matcher =
      63         621 :       Intl::GetLocaleMatcher(isolate, options, "Intl.Segmenter");
      64         621 :   MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSSegmenter>());
      65             :   Intl::MatcherOption matcher = maybe_locale_matcher.FromJust();
      66             : 
      67             :   // 9. Let r be ResolveLocale(%Segmenter%.[[AvailableLocales]],
      68             :   // requestedLocales, opt, %Segmenter%.[[RelevantExtensionKeys]]).
      69             :   Intl::ResolvedLocale r =
      70             :       Intl::ResolveLocale(isolate, JSSegmenter::GetAvailableLocales(),
      71        1836 :                           requested_locales, matcher, {});
      72             : 
      73             :   // 10. Set segmenter.[[Locale]] to the value of r.[[Locale]].
      74             :   Handle<String> locale_str =
      75         612 :       isolate->factory()->NewStringFromAsciiChecked(r.locale.c_str());
      76         612 :   segmenter_holder->set_locale(*locale_str);
      77             : 
      78             :   // 13. Let granularity be ? GetOption(options, "granularity", "string", «
      79             :   // "grapheme", "word", "sentence" », "grapheme").
      80             :   Maybe<Granularity> maybe_granularity = Intl::GetStringOption<Granularity>(
      81             :       isolate, options, "granularity", "Intl.Segmenter",
      82             :       {"grapheme", "word", "sentence"},
      83             :       {Granularity::GRAPHEME, Granularity::WORD, Granularity::SENTENCE},
      84        1836 :       Granularity::GRAPHEME);
      85         612 :   MAYBE_RETURN(maybe_granularity, MaybeHandle<JSSegmenter>());
      86             :   Granularity granularity_enum = maybe_granularity.FromJust();
      87             : 
      88             :   // 14. Set segmenter.[[SegmenterGranularity]] to granularity.
      89         558 :   segmenter_holder->set_granularity(granularity_enum);
      90             : 
      91        1116 :   icu::Locale icu_locale = r.icu_locale;
      92             :   DCHECK(!icu_locale.isBogus());
      93             : 
      94         558 :   UErrorCode status = U_ZERO_ERROR;
      95             :   std::unique_ptr<icu::BreakIterator> icu_break_iterator;
      96             : 
      97         558 :   switch (granularity_enum) {
      98             :     case Granularity::GRAPHEME:
      99         369 :       icu_break_iterator.reset(
     100             :           icu::BreakIterator::createCharacterInstance(icu_locale, status));
     101             :       break;
     102             :     case Granularity::WORD:
     103          99 :       icu_break_iterator.reset(
     104             :           icu::BreakIterator::createWordInstance(icu_locale, status));
     105             :       break;
     106             :     case Granularity::SENTENCE:
     107          90 :       icu_break_iterator.reset(
     108             :           icu::BreakIterator::createSentenceInstance(icu_locale, status));
     109             :       break;
     110             :     case Granularity::COUNT:
     111           0 :       UNREACHABLE();
     112             :   }
     113             : 
     114         558 :   CHECK(U_SUCCESS(status));
     115         558 :   CHECK_NOT_NULL(icu_break_iterator.get());
     116             : 
     117             :   Handle<Managed<icu::BreakIterator>> managed_break_iterator =
     118             :       Managed<icu::BreakIterator>::FromUniquePtr(isolate, 0,
     119        1116 :                                                  std::move(icu_break_iterator));
     120             : 
     121         558 :   segmenter_holder->set_icu_break_iterator(*managed_break_iterator);
     122         558 :   return segmenter_holder;
     123             : }
     124             : 
     125             : // ecma402 #sec-Intl.Segmenter.prototype.resolvedOptions
     126          81 : Handle<JSObject> JSSegmenter::ResolvedOptions(
     127             :     Isolate* isolate, Handle<JSSegmenter> segmenter_holder) {
     128             :   Factory* factory = isolate->factory();
     129             :   // 3. Let options be ! ObjectCreate(%ObjectPrototype%).
     130          81 :   Handle<JSObject> result = factory->NewJSObject(isolate->object_function());
     131             :   // 4. For each row of Table 1, except the header row, do
     132             :   // a. Let p be the Property value of the current row.
     133             :   // b. Let v be the value of pr's internal slot whose name is the Internal Slot
     134             :   //    value of the current row.
     135             :   //
     136             :   // c. If v is not undefined, then
     137             :   //  i. Perform ! CreateDataPropertyOrThrow(options, p, v).
     138             :   //    Table 1: Resolved Options of Segmenter Instances
     139             :   //     Internal Slot                 Property
     140             :   //     [[Locale]]                    "locale"
     141             :   //     [[SegmenterGranularity]]      "granularity"
     142             : 
     143             :   Handle<String> locale(segmenter_holder->locale(), isolate);
     144          81 :   JSObject::AddProperty(isolate, result, factory->locale_string(), locale,
     145          81 :                         NONE);
     146         162 :   JSObject::AddProperty(isolate, result, factory->granularity_string(),
     147          81 :                         segmenter_holder->GranularityAsString(), NONE);
     148             :   // 5. Return options.
     149          81 :   return result;
     150             : }
     151             : 
     152          81 : Handle<String> JSSegmenter::GranularityAsString() const {
     153          81 :   switch (granularity()) {
     154             :     case Granularity::GRAPHEME:
     155             :       return GetReadOnlyRoots().grapheme_string_handle();
     156             :     case Granularity::WORD:
     157             :       return GetReadOnlyRoots().word_string_handle();
     158             :     case Granularity::SENTENCE:
     159             :       return GetReadOnlyRoots().sentence_string_handle();
     160             :     case Granularity::COUNT:
     161           0 :       UNREACHABLE();
     162             :   }
     163           0 : }
     164             : 
     165          41 : const std::set<std::string>& JSSegmenter::GetAvailableLocales() {
     166             :   static base::LazyInstance<Intl::AvailableLocales<icu::BreakIterator>>::type
     167             :       available_locales = LAZY_INSTANCE_INITIALIZER;
     168          41 :   return available_locales.Pointer()->Get();
     169             : }
     170             : 
     171             : }  // namespace internal
     172      120216 : }  // namespace v8

Generated by: LCOV version 1.10