Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Side by Side Diff: src/runtime/runtime-i18n.cc

Issue 2736543002: [intl] Implement Intl.PluralRules
Patch Set: clarify comment Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 5
6 #ifdef V8_I18N_SUPPORT 6 #ifdef V8_I18N_SUPPORT
7 #include "src/runtime/runtime-utils.h" 7 #include "src/runtime/runtime-utils.h"
8 8
9 #include <memory> 9 #include <memory>
10 10
(...skipping 15 matching lines...) Expand all
26 #include "unicode/dcfmtsym.h" 26 #include "unicode/dcfmtsym.h"
27 #include "unicode/decimfmt.h" 27 #include "unicode/decimfmt.h"
28 #include "unicode/dtfmtsym.h" 28 #include "unicode/dtfmtsym.h"
29 #include "unicode/dtptngen.h" 29 #include "unicode/dtptngen.h"
30 #include "unicode/fieldpos.h" 30 #include "unicode/fieldpos.h"
31 #include "unicode/fpositer.h" 31 #include "unicode/fpositer.h"
32 #include "unicode/locid.h" 32 #include "unicode/locid.h"
33 #include "unicode/normalizer2.h" 33 #include "unicode/normalizer2.h"
34 #include "unicode/numfmt.h" 34 #include "unicode/numfmt.h"
35 #include "unicode/numsys.h" 35 #include "unicode/numsys.h"
36 #include "unicode/plurrule.h"
36 #include "unicode/rbbi.h" 37 #include "unicode/rbbi.h"
37 #include "unicode/smpdtfmt.h" 38 #include "unicode/smpdtfmt.h"
38 #include "unicode/timezone.h" 39 #include "unicode/timezone.h"
39 #include "unicode/translit.h" 40 #include "unicode/translit.h"
40 #include "unicode/uchar.h" 41 #include "unicode/uchar.h"
41 #include "unicode/ucol.h" 42 #include "unicode/ucol.h"
42 #include "unicode/ucurr.h" 43 #include "unicode/ucurr.h"
43 #include "unicode/uloc.h" 44 #include "unicode/uloc.h"
44 #include "unicode/unistr.h" 45 #include "unicode/unistr.h"
45 #include "unicode/unum.h" 46 #include "unicode/unum.h"
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 int32_t count = 0; 117 int32_t count = 0;
117 118
118 if (service->IsUtf8EqualTo(CStrVector("collator"))) { 119 if (service->IsUtf8EqualTo(CStrVector("collator"))) {
119 available_locales = icu::Collator::getAvailableLocales(count); 120 available_locales = icu::Collator::getAvailableLocales(count);
120 } else if (service->IsUtf8EqualTo(CStrVector("numberformat"))) { 121 } else if (service->IsUtf8EqualTo(CStrVector("numberformat"))) {
121 available_locales = icu::NumberFormat::getAvailableLocales(count); 122 available_locales = icu::NumberFormat::getAvailableLocales(count);
122 } else if (service->IsUtf8EqualTo(CStrVector("dateformat"))) { 123 } else if (service->IsUtf8EqualTo(CStrVector("dateformat"))) {
123 available_locales = icu::DateFormat::getAvailableLocales(count); 124 available_locales = icu::DateFormat::getAvailableLocales(count);
124 } else if (service->IsUtf8EqualTo(CStrVector("breakiterator"))) { 125 } else if (service->IsUtf8EqualTo(CStrVector("breakiterator"))) {
125 available_locales = icu::BreakIterator::getAvailableLocales(count); 126 available_locales = icu::BreakIterator::getAvailableLocales(count);
127 } else if (service->IsUtf8EqualTo(CStrVector("pluralrules"))) {
128 // TODO(littledan): For PluralRules, filter out locales that
129 // don't support PluralRules.
130 // PluralRules is missing an appropriate getAvailableLocales method,
131 // so we should filter from all locales, but it's not clear how; see
132 // https://ssl.icu-project.org/trac/ticket/12756
133 available_locales = icu::Locale::getAvailableLocales(count);
134 } else {
135 UNREACHABLE();
126 } 136 }
127 137
128 UErrorCode error = U_ZERO_ERROR; 138 UErrorCode error = U_ZERO_ERROR;
129 char result[ULOC_FULLNAME_CAPACITY]; 139 char result[ULOC_FULLNAME_CAPACITY];
130 Handle<JSObject> locales = factory->NewJSObject(isolate->object_function()); 140 Handle<JSObject> locales = factory->NewJSObject(isolate->object_function());
131 141
132 for (int32_t i = 0; i < count; ++i) { 142 for (int32_t i = 0; i < count; ++i) {
133 const char* icu_name = available_locales[i].getName(); 143 const char* icu_name = available_locales[i].getName();
134 144
135 error = U_ZERO_ERROR; 145 error = U_ZERO_ERROR;
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 const UChar* string_val1 = GetUCharBufferFromFlat(flat1, &sap1, length1); 641 const UChar* string_val1 = GetUCharBufferFromFlat(flat1, &sap1, length1);
632 const UChar* string_val2 = GetUCharBufferFromFlat(flat2, &sap2, length2); 642 const UChar* string_val2 = GetUCharBufferFromFlat(flat2, &sap2, length2);
633 result = 643 result =
634 collator->compare(string_val1, length1, string_val2, length2, status); 644 collator->compare(string_val1, length1, string_val2, length2, status);
635 } 645 }
636 if (U_FAILURE(status)) return isolate->ThrowIllegalOperation(); 646 if (U_FAILURE(status)) return isolate->ThrowIllegalOperation();
637 647
638 return *isolate->factory()->NewNumberFromInt(result); 648 return *isolate->factory()->NewNumberFromInt(result);
639 } 649 }
640 650
651 RUNTIME_FUNCTION(Runtime_CreatePluralRules) {
652 HandleScope scope(isolate);
653
654 DCHECK_EQ(3, args.length());
655
656 CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
657 CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
658 CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
659
660 Handle<JSFunction> constructor(
661 isolate->native_context()->intl_plural_rules_function());
662
663 Handle<JSObject> local_object;
664 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, local_object,
665 JSObject::New(constructor, constructor));
666
667 // Set pluralRules as internal field of the resulting JS object.
668 icu::PluralRules* plural_rules;
669 icu::DecimalFormat* decimal_format;
670 bool success = PluralRules::InitializePluralRules(
671 isolate, locale, options, resolved, &plural_rules, &decimal_format);
672
673 if (!success) return isolate->ThrowIllegalOperation();
674
675 local_object->SetInternalField(0, reinterpret_cast<Smi*>(plural_rules));
676 local_object->SetInternalField(1, reinterpret_cast<Smi*>(decimal_format));
677
678 Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
679 GlobalHandles::MakeWeak(wrapper.location(), wrapper.location(),
680 PluralRules::DeletePluralRules,
681 WeakCallbackType::kInternalFields);
682 return *local_object;
683 }
684
685 RUNTIME_FUNCTION(Runtime_PluralRulesSelect) {
686 HandleScope scope(isolate);
687
688 DCHECK_EQ(2, args.length());
689
690 CONVERT_ARG_HANDLE_CHECKED(JSObject, plural_rules_holder, 0);
691 CONVERT_ARG_HANDLE_CHECKED(Object, number, 1);
692
693 icu::PluralRules* plural_rules =
694 PluralRules::UnpackPluralRules(isolate, plural_rules_holder);
695 CHECK_NOT_NULL(plural_rules);
696
697 icu::DecimalFormat* number_format =
698 PluralRules::UnpackNumberFormat(isolate, plural_rules_holder);
699 CHECK_NOT_NULL(number_format);
700
701 // Currently, PluralRules doesn't implement all the options for rounding that
702 // the Intl spec provides; format and parse the number to round to the
703 // appropriate amount, then apply PluralRules.
704 //
705 // TODO(littledan): If a future ICU version supports an extended API to avoid
706 // this step, then switch to that API. Bug thread:
707 // http://bugs.icu-project.org/trac/ticket/12763
jungshik at Google 2017/05/08 19:16:54 Fixed in ICU 59.1. Either wait for me to update Ch
Dan Ehrenberg 2017/07/14 08:31:50 Looks like that API is C-only. I posted a comment
708 icu::UnicodeString rounded_string;
709 number_format->format(number->Number(), rounded_string);
710
711 icu::Formattable formattable;
712 UErrorCode status = U_ZERO_ERROR;
713 number_format->parse(rounded_string, formattable, status);
714 if (!U_SUCCESS(status)) return isolate->ThrowIllegalOperation();
jungshik at Google 2017/05/08 19:16:54 again, check at line 717 would suffice. If you wan
715
716 double rounded = formattable.getDouble(status);
717 if (!U_SUCCESS(status)) return isolate->ThrowIllegalOperation();
718
719 icu::UnicodeString result = plural_rules->select(rounded);
720 return *isolate->factory()
721 ->NewStringFromTwoByte(Vector<const uint16_t>(
722 reinterpret_cast<const uint16_t*>(result.getBuffer()),
723 result.length()))
724 .ToHandleChecked();
725 }
641 726
642 RUNTIME_FUNCTION(Runtime_StringNormalize) { 727 RUNTIME_FUNCTION(Runtime_StringNormalize) {
643 HandleScope scope(isolate); 728 HandleScope scope(isolate);
644 static const struct { 729 static const struct {
645 const char* name; 730 const char* name;
646 UNormalization2Mode mode; 731 UNormalization2Mode mode;
647 } normalizationForms[] = { 732 } normalizationForms[] = {
648 {"nfc", UNORM2_COMPOSE}, 733 {"nfc", UNORM2_COMPOSE},
649 {"nfc", UNORM2_DECOMPOSE}, 734 {"nfc", UNORM2_DECOMPOSE},
650 {"nfkc", UNORM2_COMPOSE}, 735 {"nfkc", UNORM2_COMPOSE},
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after
1199 Handle<FixedArray> date_cache_version = 1284 Handle<FixedArray> date_cache_version =
1200 Handle<FixedArray>::cast(isolate->eternal_handles()->GetSingleton( 1285 Handle<FixedArray>::cast(isolate->eternal_handles()->GetSingleton(
1201 EternalHandles::DATE_CACHE_VERSION)); 1286 EternalHandles::DATE_CACHE_VERSION));
1202 return date_cache_version->get(0); 1287 return date_cache_version->get(0);
1203 } 1288 }
1204 1289
1205 } // namespace internal 1290 } // namespace internal
1206 } // namespace v8 1291 } // namespace v8
1207 1292
1208 #endif // V8_I18N_SUPPORT 1293 #endif // V8_I18N_SUPPORT
OLDNEW
« src/i18n.cc ('K') | « src/runtime/runtime.h ('k') | test/test262/test262.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698