Skip to content

Commit ccbe3d0

Browse files
FrankYFTangCommit Bot
authored andcommitted
[Intl] Upgrade RelativeTimeFormat formatToParts
1. Add Intl::NumberFieldToType to support RelativeTimeFormat by refactoring IcuNumberFieldIdToNumberType 2. Use formatNumericToValue / formatToValue to implement formatToParts Bug: v8:8837 Change-Id: I4d8fab9c337ec02eeb3500b4c0f90547e48444e3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1560661 Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org> Commit-Queue: Frank Tang <ftang@chromium.org> Cr-Commit-Position: refs/heads/master@{#60797}
1 parent af1988f commit ccbe3d0

6 files changed

Lines changed: 205 additions & 173 deletions

File tree

src/builtins/builtins-intl.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -705,7 +705,7 @@ BUILTIN(RelativeTimeFormatPrototypeFormat) {
705705

706706
RETURN_RESULT_OR_FAILURE(
707707
isolate, JSRelativeTimeFormat::Format(isolate, value_obj, unit_obj,
708-
format_holder, "format", false));
708+
format_holder));
709709
}
710710

711711
BUILTIN(RelativeTimeFormatPrototypeFormatToParts) {
@@ -718,9 +718,9 @@ BUILTIN(RelativeTimeFormatPrototypeFormatToParts) {
718718
"Intl.RelativeTimeFormat.prototype.formatToParts");
719719
Handle<Object> value_obj = args.atOrUndefined(isolate, 1);
720720
Handle<Object> unit_obj = args.atOrUndefined(isolate, 2);
721-
RETURN_RESULT_OR_FAILURE(isolate, JSRelativeTimeFormat::Format(
722-
isolate, value_obj, unit_obj,
723-
format_holder, "formatToParts", true));
721+
RETURN_RESULT_OR_FAILURE(
722+
isolate, JSRelativeTimeFormat::FormatToParts(isolate, value_obj, unit_obj,
723+
format_holder));
724724
}
725725

726726
// Locale getters.

src/objects/intl-objects.cc

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1878,5 +1878,61 @@ const std::set<std::string>& Intl::GetAvailableLocalesForDateFormat() {
18781878
return available_locales.Pointer()->Get();
18791879
}
18801880

1881+
Handle<String> Intl::NumberFieldToType(Isolate* isolate,
1882+
Handle<Object> numeric_obj,
1883+
int32_t field_id) {
1884+
DCHECK(numeric_obj->IsNumeric());
1885+
switch (static_cast<UNumberFormatFields>(field_id)) {
1886+
case UNUM_INTEGER_FIELD:
1887+
if (numeric_obj->IsBigInt()) {
1888+
// Neither NaN nor Infinite could be stored into BigInt
1889+
// so just return integer.
1890+
return isolate->factory()->integer_string();
1891+
} else {
1892+
double number = numeric_obj->Number();
1893+
if (std::isfinite(number)) return isolate->factory()->integer_string();
1894+
if (std::isnan(number)) return isolate->factory()->nan_string();
1895+
return isolate->factory()->infinity_string();
1896+
}
1897+
case UNUM_FRACTION_FIELD:
1898+
return isolate->factory()->fraction_string();
1899+
case UNUM_DECIMAL_SEPARATOR_FIELD:
1900+
return isolate->factory()->decimal_string();
1901+
case UNUM_GROUPING_SEPARATOR_FIELD:
1902+
return isolate->factory()->group_string();
1903+
case UNUM_CURRENCY_FIELD:
1904+
return isolate->factory()->currency_string();
1905+
case UNUM_PERCENT_FIELD:
1906+
return isolate->factory()->percentSign_string();
1907+
case UNUM_SIGN_FIELD:
1908+
if (numeric_obj->IsBigInt()) {
1909+
Handle<BigInt> big_int = Handle<BigInt>::cast(numeric_obj);
1910+
return big_int->IsNegative() ? isolate->factory()->minusSign_string()
1911+
: isolate->factory()->plusSign_string();
1912+
} else {
1913+
double number = numeric_obj->Number();
1914+
return number < 0 ? isolate->factory()->minusSign_string()
1915+
: isolate->factory()->plusSign_string();
1916+
}
1917+
case UNUM_EXPONENT_SYMBOL_FIELD:
1918+
case UNUM_EXPONENT_SIGN_FIELD:
1919+
case UNUM_EXPONENT_FIELD:
1920+
// We should never get these because we're not using any scientific
1921+
// formatter.
1922+
UNREACHABLE();
1923+
return Handle<String>();
1924+
1925+
case UNUM_PERMILL_FIELD:
1926+
// We're not creating any permill formatter, and it's not even clear how
1927+
// that would be possible with the ICU API.
1928+
UNREACHABLE();
1929+
return Handle<String>();
1930+
1931+
default:
1932+
UNREACHABLE();
1933+
return Handle<String>();
1934+
}
1935+
}
1936+
18811937
} // namespace internal
18821938
} // namespace v8

src/objects/intl-objects.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#include "unicode/locid.h"
2121
#include "unicode/uversion.h"
2222

23-
#define V8_MINIMUM_ICU_VERSION 63
23+
#define V8_MINIMUM_ICU_VERSION 64
2424

2525
namespace U_ICU_NAMESPACE {
2626
class BreakIterator;
@@ -186,6 +186,11 @@ class Intl {
186186
Isolate* isolate, const icu::UnicodeString& string, int32_t begin,
187187
int32_t end);
188188

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+
189194
// A helper function to implement formatToParts which add element to array as
190195
// $array[$index] = { type: $field_type_string, value: $value }
191196
static void AddElement(Isolate* isolate, Handle<JSArray> array, int index,

src/objects/js-number-format.cc

Lines changed: 1 addition & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -559,64 +559,6 @@ bool cmp_NumberFormatSpan(const NumberFormatSpan& a,
559559
return a.field_id < b.field_id;
560560
}
561561

562-
// The list comes from third_party/icu/source/i18n/unicode/unum.h.
563-
// They're mapped to NumberFormat part types mentioned throughout
564-
// https://tc39.github.io/ecma402/#sec-partitionnumberpattern .
565-
Handle<String> IcuNumberFieldIdToNumberType(int32_t field_id,
566-
Handle<Object> numeric_obj,
567-
Isolate* isolate) {
568-
DCHECK(numeric_obj->IsNumeric());
569-
switch (static_cast<UNumberFormatFields>(field_id)) {
570-
case UNUM_INTEGER_FIELD:
571-
if (numeric_obj->IsBigInt()) {
572-
// Neither NaN nor Infinite could be stored into BigInt
573-
// so just return integer.
574-
return isolate->factory()->integer_string();
575-
} else {
576-
double number = numeric_obj->Number();
577-
if (std::isfinite(number)) return isolate->factory()->integer_string();
578-
if (std::isnan(number)) return isolate->factory()->nan_string();
579-
return isolate->factory()->infinity_string();
580-
}
581-
case UNUM_FRACTION_FIELD:
582-
return isolate->factory()->fraction_string();
583-
case UNUM_DECIMAL_SEPARATOR_FIELD:
584-
return isolate->factory()->decimal_string();
585-
case UNUM_GROUPING_SEPARATOR_FIELD:
586-
return isolate->factory()->group_string();
587-
case UNUM_CURRENCY_FIELD:
588-
return isolate->factory()->currency_string();
589-
case UNUM_PERCENT_FIELD:
590-
return isolate->factory()->percentSign_string();
591-
case UNUM_SIGN_FIELD:
592-
if (numeric_obj->IsBigInt()) {
593-
Handle<BigInt> big_int = Handle<BigInt>::cast(numeric_obj);
594-
return big_int->IsNegative() ? isolate->factory()->minusSign_string()
595-
: isolate->factory()->plusSign_string();
596-
} else {
597-
double number = numeric_obj->Number();
598-
return number < 0 ? isolate->factory()->minusSign_string()
599-
: isolate->factory()->plusSign_string();
600-
}
601-
case UNUM_EXPONENT_SYMBOL_FIELD:
602-
case UNUM_EXPONENT_SIGN_FIELD:
603-
case UNUM_EXPONENT_FIELD:
604-
// We should never get these because we're not using any scientific
605-
// formatter.
606-
UNREACHABLE();
607-
return Handle<String>();
608-
609-
case UNUM_PERMILL_FIELD:
610-
// We're not creating any permill formatter, and it's not even clear how
611-
// that would be possible with the ICU API.
612-
UNREACHABLE();
613-
return Handle<String>();
614-
615-
default:
616-
UNREACHABLE();
617-
return Handle<String>();
618-
}
619-
}
620562
} // namespace
621563

622564
// Flattens a list of possibly-overlapping "regions" to a list of
@@ -748,7 +690,7 @@ Maybe<int> JSNumberFormat::FormatToParts(Isolate* isolate,
748690
Handle<String> field_type_string =
749691
part.field_id == -1
750692
? isolate->factory()->literal_string()
751-
: IcuNumberFieldIdToNumberType(part.field_id, numeric_obj, isolate);
693+
: Intl::NumberFieldToType(isolate, numeric_obj, part.field_id);
752694
Handle<String> substring;
753695
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
754696
isolate, substring,

0 commit comments

Comments
 (0)