v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
intl-objects.h
Go to the documentation of this file.
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_OBJECTS_INTL_OBJECTS_H_
6#define V8_OBJECTS_INTL_OBJECTS_H_
7
8#include <map>
9#include <memory>
10#include <optional>
11#include <set>
12#include <string>
13
16#include "src/objects/managed.h"
17#include "src/objects/objects.h"
18#include "unicode/locid.h"
19#include "unicode/uversion.h"
20
21#ifndef V8_INTL_SUPPORT
22#error Internationalization is expected to be enabled.
23#endif // V8_INTL_SUPPORT
24
25#define V8_MINIMUM_ICU_VERSION 73
26
27namespace U_ICU_NAMESPACE {
28class BreakIterator;
29class Locale;
30class ListFormatter;
31class RelativeDateTimeFormatter;
32class SimpleDateFormat;
33class DateIntervalFormat;
34class PluralRules;
35class Collator;
36class FormattedValue;
37class StringEnumeration;
38class TimeZone;
39class UnicodeString;
40namespace number {
41class LocalizedNumberFormatter;
42} // namespace number
43} // namespace U_ICU_NAMESPACE
44
45namespace v8::internal {
46
47#define ICU_EXTERNAL_POINTER_TAG_LIST(V) \
48 V(icu::UnicodeString, kIcuUnicodeStringTag) \
49 V(icu::BreakIterator, kIcuBreakIteratorTag) \
50 V(icu::Locale, kIcuLocaleTag) \
51 V(icu::SimpleDateFormat, kIcuSimpleDateFormatTag) \
52 V(icu::DateIntervalFormat, kIcuDateIntervalFormatTag) \
53 V(icu::RelativeDateTimeFormatter, kIcuRelativeDateTimeFormatterTag) \
54 V(icu::ListFormatter, kIcuListFormatterTag) \
55 V(icu::Collator, kIcuCollatorTag) \
56 V(icu::PluralRules, kIcuPluralRulesTag) \
57 V(icu::number::LocalizedNumberFormatter, kIcuLocalizedNumberFormatterTag)
59#undef ICU_EXTERNAL_POINTER_TAG_LIST
60
62 int32_t field_id;
63 int32_t begin_pos;
64 int32_t end_pos;
65
66 NumberFormatSpan() = default;
69};
70
71V8_EXPORT_PRIVATE std::vector<NumberFormatSpan> FlattenRegionsToParts(
72 std::vector<NumberFormatSpan>* regions);
73
74class JSCollator;
75
76class Intl {
77 public:
82
84
86 public:
88 void Add(int32_t field, int32_t start, int32_t limit);
89 FormatRangeSource GetSource(int32_t start, int32_t limit) const;
90
91 private:
92 int32_t start_[2];
93 int32_t limit_[2];
94
95 bool FieldContains(int32_t field, int32_t start, int32_t limit) const;
96 };
97
99 FormatRangeSource source);
100
101 // Build a set of ICU locales from a list of Locales. If there is a locale
102 // with a script tag then the locales also include a locale without the
103 // script; eg, pa_Guru_IN (language=Panjabi, script=Gurmukhi, country-India)
104 // would include pa_IN.
105 static std::set<std::string> BuildLocaleSet(
106 const std::vector<std::string>& locales, const char* path,
107 const char* validate_key);
108
109 static Maybe<std::string> ToLanguageTag(const icu::Locale& locale);
110
111 // Get the name of the numbering system from locale.
112 // ICU doesn't expose numbering system in any way, so we have to assume that
113 // for given locale NumberingSystem constructor produces the same digits as
114 // NumberFormat/Calendar would.
115 static std::string GetNumberingSystem(const icu::Locale& icu_locale);
116
118 Isolate* isolate, const char* method_name,
119 const std::set<std::string>& available_locales,
120 DirectHandle<Object> locales_in, DirectHandle<Object> options_in);
121
122 // https://tc39.github.io/ecma402/#sec-canonicalizelocalelist
123 // {only_return_one_result} is an optimization for callers that only
124 // care about the first result.
126 Isolate* isolate, DirectHandle<Object> locales,
127 bool only_return_one_result = false);
128
129 // ecma-402 #sec-intl.getcanonicallocales
131 Isolate* isolate, DirectHandle<Object> locales);
132
133 // ecma-402 #sec-intl.supportedvaluesof
136
137 // For locale sensitive functions
140 bool is_upper, DirectHandle<Object> locales);
141
143 Isolate* isolate, DirectHandle<String> s);
144
146 Isolate* isolate, DirectHandle<String> s);
147
148 V8_WARN_UNUSED_RESULT static std::optional<int> StringLocaleCompare(
151 const char* method_name);
152
154 kNone,
156 };
157 template <class IsolateT>
159 IsolateT* isolate, DirectHandle<Object> locales,
160 DirectHandle<Object> options);
162 Isolate* isolate, const icu::Collator& collator, DirectHandle<String> s1,
164 CompareStringsOptions compare_strings_options =
166
167 // ecma402/#sup-properties-of-the-number-prototype-object
169 Isolate* isolate, Handle<Object> num, DirectHandle<Object> locales,
170 DirectHandle<Object> options, const char* method_name);
171
172 // [[RoundingPriority]] is one of the String values "auto", "morePrecision",
173 // or "lessPrecision", specifying the rounding priority for the number.
174 enum class RoundingPriority {
175 kAuto,
178 };
179
186
187 // [[RoundingMode]] is one of the String values "ceil", "floor", "expand",
188 // "trunc", "halfCeil", "halfFloor", "halfExpand", "halfTrunc", or "halfEven",
189 // specifying the rounding strategy for the number.
190 enum class RoundingMode {
191 kCeil,
192 kFloor,
193 kExpand,
194 kTrunc,
195 kHalfCeil,
199 kHalfEven,
200 };
201
202 // [[TrailingZeroDisplay]] is one of the String values "auto" or
203 // "stripIfInteger", specifying the strategy for displaying trailing zeros on
204 // whole number.
206 kAuto,
208 };
209
210 // ecma402/#sec-setnfdigitoptions
226 int mnfd_default, int mxfd_default,
227 bool notation_is_compact, const char* service);
228
229 // Helper function to convert a UnicodeString to a Handle<String>
231 Isolate* isolate, const icu::UnicodeString& string);
232
233 // Helper function to convert a substring of UnicodeString to a Handle<String>
235 Isolate* isolate, const icu::UnicodeString& string, int32_t begin,
236 int32_t end);
237
238 // Helper function to convert a FormattedValue to String
240 Isolate* isolate, const icu::FormattedValue& formatted);
241
242 // Helper function to convert number field id to type string.
244 const NumberFormatSpan& part,
245 const icu::UnicodeString& text,
246 bool is_nan);
247
248 // A helper function to implement formatToParts which add element to array as
249 // $array[$index] = { type: $field_type_string, value: $value }
250 static void AddElement(Isolate* isolate, DirectHandle<JSArray> array,
251 int index, DirectHandle<String> field_type_string,
253
254 // A helper function to implement formatToParts which add element to array as
255 // $array[$index] = {
256 // type: $field_type_string, value: $value,
257 // $additional_property_name: $additional_property_value
258 // }
259 static void AddElement(Isolate* isolate, DirectHandle<JSArray> array,
260 int index, DirectHandle<String> field_type_string,
262 DirectHandle<String> additional_property_name,
263 DirectHandle<String> additional_property_value);
264
265 // A helper function to implement formatToParts which add element to array
266 static Maybe<int> AddNumberElements(Isolate* isolate,
267 const icu::FormattedValue& formatted,
269 int start_index,
271
272 // In ECMA 402 v1, Intl constructors supported a mode of operation
273 // where calling them with an existing object as a receiver would
274 // transform the receiver into the relevant Intl instance with all
275 // internal slots. In ECMA 402 v2, this capability was removed, to
276 // avoid adding internal slots on existing objects. In ECMA 402 v3,
277 // the capability was re-added as "normative optional" in a mode
278 // which chains the underlying Intl instance on any object, when the
279 // constructor is called
280 //
281 // See ecma402/#legacy-constructor.
284 DirectHandle<JSFunction> constructor, bool has_initialized_slot);
285
286 // enum for "localeMatcher" option: shared by many Intl objects.
288
289 // Shared function to read the "localeMatcher" option.
291 Isolate* isolate, DirectHandle<JSReceiver> options,
292 const char* method_name);
293
294 // Shared function to read the "numberingSystem" option.
296 Isolate* isolate, DirectHandle<JSReceiver> options,
297 const char* method_name, std::unique_ptr<char[]>* result);
298
299 // Check the calendar is valid or not for that locale.
300 static bool IsValidCalendar(const icu::Locale& locale,
301 const std::string& value);
302
303 // Check the collation is valid or not for that locale.
304 static bool IsValidCollation(const icu::Locale& locale,
305 const std::string& value);
306
307 // Check the numberingSystem is valid.
308 static bool IsValidNumberingSystem(const std::string& value);
309
310 // Check the calendar is well formed.
311 static bool IsWellFormedCalendar(const std::string& value);
312
313 // Check the currency is well formed.
314 static bool IsWellFormedCurrency(const std::string& value);
315
317 std::string locale;
318 icu::Locale icu_locale;
319 std::map<std::string, std::string> extensions;
320 };
321
323 Isolate* isolate, const std::set<std::string>& available_locales,
324 const std::vector<std::string>& requested_locales, MatcherOption options,
325 const std::set<std::string>& relevant_extension_keys);
326
327 // A helper template to implement the GetAvailableLocales
328 // Usage in src/objects/js-XXX.cc
329 // const std::set<std::string>& JSXxx::GetAvailableLocales() {
330 // static base::LazyInstance<Intl::AvailableLocales<icu::YYY>>::type
331 // available_locales = LAZY_INSTANCE_INITIALIZER;
332 // return available_locales.Pointer()->Get();
333 // }
334
336 static const char* key() { return nullptr; }
337 static const char* path() { return nullptr; }
338 };
339
340 template <typename C = SkipResourceCheck>
342 public:
344 UErrorCode status = U_ZERO_ERROR;
345 UEnumeration* uenum =
346 uloc_openAvailableByType(ULOC_AVAILABLE_WITH_LEGACY_ALIASES, &status);
347 DCHECK(U_SUCCESS(status));
348
349 std::vector<std::string> all_locales;
350 const char* loc;
351 while ((loc = uenum_next(uenum, nullptr, &status)) != nullptr) {
352 DCHECK(U_SUCCESS(status));
353 std::string locstr(loc);
354 std::replace(locstr.begin(), locstr.end(), '_', '-');
355 // Handle special case
356 if (locstr == "en-US-POSIX") locstr = "en-US-u-va-posix";
357 all_locales.push_back(locstr);
358 }
359 uenum_close(uenum);
360
361 set_ = Intl::BuildLocaleSet(all_locales, C::path(), C::key());
362 }
363 const std::set<std::string>& Get() const { return set_; }
364
365 private:
366 std::set<std::string> set_;
367 };
368
369 // Utility function to set text to BreakIterator.
371 Isolate* isolate, DirectHandle<String> text,
372 icu::BreakIterator* break_iterator);
373
374 // ecma262 #sec-string.prototype.normalize
376 Isolate* isolate, DirectHandle<String> string,
377 DirectHandle<Object> form_input);
379
380 // Convert a Handle<String> to icu::UnicodeString
381 static icu::UnicodeString ToICUUnicodeString(Isolate* isolate,
383 int offset = 0);
384
385 static const uint8_t* ToLatin1LowerTable();
386
387 static const uint8_t* AsciiCollationWeightsL1();
388 static const uint8_t* AsciiCollationWeightsL3();
390
392 Tagged<String> dst);
393
394 static const std::set<std::string>& GetAvailableLocales();
395
396 static const std::set<std::string>& GetAvailableLocalesForDateFormat();
397
399 Isolate* isolate, const char* unicode_key,
400 icu::StringEnumeration* enumeration,
401 const std::function<bool(const char*)>& removes, bool sort);
402
403 static bool RemoveCollation(const char* collation);
404
405 static std::set<std::string> SanctionedSimpleUnits();
406
408 Isolate* isolate);
409
411 const icu::TimeZone& tz);
413 const std::string& id);
415 Isolate* isolate, DirectHandle<String> id);
416
417 // Function to support Temporal
418 V8_WARN_UNUSED_RESULT static std::string TimeZoneIdFromIndex(int32_t index);
419
420 // Return the index of timezone which later could be used with
421 // TimeZoneIdFromIndex. Returns -1 while the identifier is not a built-in
422 // TimeZone name.
423 static int32_t GetTimeZoneIndex(Isolate* isolate,
425
426 enum class Transition { kNext, kPrevious };
427
428 // Functions to support Temporal
429
430 // Return the epoch of transition in BigInt or null if there are no
431 // transition.
433 Isolate* isolate, int32_t time_zone_index,
434 DirectHandle<BigInt> nanosecond_epoch, Transition transition);
435
436 // Return the Time Zone offset, in the unit of nanosecond by int64_t, during
437 // the time of the nanosecond_epoch.
438 static int64_t GetTimeZoneOffsetNanoseconds(
439 Isolate* isolate, int32_t time_zone_index,
440 DirectHandle<BigInt> nanosecond_epoch);
441
442 // This function may return the result, the std::vector<int64_t> in one of
443 // the following three conditions:
444 // 1. While nanosecond_epoch fall into the daylight saving time change
445 // moment that skipped one (or two or even six, in some Time Zone) hours
446 // later in local time:
447 // [],
448 // 2. In other moment not during daylight saving time change:
449 // [offset_former], and
450 // 3. when nanosecond_epoch fall into they daylight saving time change hour
451 // which the clock time roll back one (or two or six, in some Time Zone) hour:
452 // [offset_former, offset_later]
453 // The unit of the return values in BigInt is nanosecond.
455 Isolate* isolate, int32_t time_zone_index,
456 DirectHandle<BigInt> nanosecond_epoch);
457
459
462
463 // ecma402/#sec-coerceoptionstoobject
466 const char* service);
467};
468
469} // namespace v8::internal
470
471#endif // V8_OBJECTS_INTL_OBJECTS_H_
const std::set< std::string > & Get() const
bool FieldContains(int32_t field, int32_t start, int32_t limit) const
FormatRangeSource GetSource(int32_t start, int32_t limit) const
void Add(int32_t field, int32_t start, int32_t limit)
static void AddElement(Isolate *isolate, DirectHandle< JSArray > array, int index, DirectHandle< String > field_type_string, DirectHandle< String > value)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > NumberToLocaleString(Isolate *isolate, Handle< Object > num, DirectHandle< Object > locales, DirectHandle< Object > options, const char *method_name)
static base::TimezoneCache * CreateTimeZoneCache()
static bool IsValidCalendar(const icu::Locale &locale, const std::string &value)
static bool IsWellFormedCurrency(const std::string &value)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > StringLocaleConvertCase(Isolate *isolate, DirectHandle< String > s, bool is_upper, DirectHandle< Object > locales)
static std::string GetNumberingSystem(const icu::Locale &icu_locale)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Object > LegacyUnwrapReceiver(Isolate *isolate, DirectHandle< JSReceiver > receiver, DirectHandle< JSFunction > constructor, bool has_initialized_slot)
static const std::set< std::string > & GetAvailableLocales()
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT int CompareStrings(Isolate *isolate, const icu::Collator &collator, DirectHandle< String > s1, DirectHandle< String > s2, CompareStringsOptions compare_strings_options=CompareStringsOptions::kNone)
static V8_WARN_UNUSED_RESULT MaybeHandle< String > ToString(Isolate *isolate, const icu::UnicodeString &string)
static V8_WARN_UNUSED_RESULT MaybeHandle< String > ConvertToLower(Isolate *isolate, DirectHandle< String > s)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > Normalize(Isolate *isolate, DirectHandle< String > string, DirectHandle< Object > form_input)
static const int kAsciiCollationWeightsLength
static DirectHandleVector< BigInt > GetTimeZonePossibleOffsetNanoseconds(Isolate *isolate, int32_t time_zone_index, DirectHandle< BigInt > nanosecond_epoch)
static int32_t GetTimeZoneIndex(Isolate *isolate, DirectHandle< String > identifier)
static Tagged< String > ConvertOneByteToLower(Tagged< String > src, Tagged< String > dst)
static Maybe< int > AddNumberElements(Isolate *isolate, const icu::FormattedValue &formatted, DirectHandle< JSArray > result, int start_index, DirectHandle< String > unit)
static bool RemoveCollation(const char *collation)
static Maybe< std::vector< std::string > > CanonicalizeLocaleList(Isolate *isolate, DirectHandle< Object > locales, bool only_return_one_result=false)
static DirectHandle< Object > GetTimeZoneOffsetTransitionNanoseconds(Isolate *isolate, int32_t time_zone_index, DirectHandle< BigInt > nanosecond_epoch, Transition transition)
static bool IsValidCollation(const icu::Locale &locale, const std::string &value)
static const std::set< std::string > & GetAvailableLocalesForDateFormat()
static DirectHandle< String > DefaultTimeZone(Isolate *isolate)
static Maybe< ResolvedLocale > ResolveLocale(Isolate *isolate, const std::set< std::string > &available_locales, const std::vector< std::string > &requested_locales, MatcherOption options, const std::set< std::string > &relevant_extension_keys)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSReceiver > CoerceOptionsToObject(Isolate *isolate, DirectHandle< Object > options, const char *service)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSArray > ToJSArray(Isolate *isolate, const char *unicode_key, icu::StringEnumeration *enumeration, const std::function< bool(const char *)> &removes, bool sort)
static std::set< std::string > SanctionedSimpleUnits()
static V8_WARN_UNUSED_RESULT bool IsValidTimeZoneName(Isolate *isolate, const std::string &id)
static const uint8_t * ToLatin1LowerTable()
static V8_WARN_UNUSED_RESULT std::optional< int > StringLocaleCompare(Isolate *isolate, DirectHandle< String > s1, DirectHandle< String > s2, DirectHandle< Object > locales, DirectHandle< Object > options, const char *method_name)
static icu::UnicodeString ToICUUnicodeString(Isolate *isolate, DirectHandle< String > string, int offset=0)
static V8_EXPORT_PRIVATE CompareStringsOptions CompareStringsOptionsFor(IsolateT *isolate, DirectHandle< Object > locales, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT bool IsValidTimeZoneName(const icu::TimeZone &tz)
static std::set< std::string > BuildLocaleSet(const std::vector< std::string > &locales, const char *path, const char *validate_key)
static V8_WARN_UNUSED_RESULT std::string TimeZoneIdFromIndex(int32_t index)
static V8_WARN_UNUSED_RESULT MaybeHandle< String > CanonicalizeTimeZoneName(Isolate *isolate, DirectHandle< String > identifier)
static int64_t GetTimeZoneOffsetNanoseconds(Isolate *isolate, int32_t time_zone_index, DirectHandle< BigInt > nanosecond_epoch)
static V8_WARN_UNUSED_RESULT Maybe< MatcherOption > GetLocaleMatcher(Isolate *isolate, DirectHandle< JSReceiver > options, const char *method_name)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSArray > AvailableCalendars(Isolate *isolate)
Definition js-locale.cc:544
static bool IsWellFormedCalendar(const std::string &value)
static Maybe< std::string > ToLanguageTag(const icu::Locale &locale)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > FormattedToString(Isolate *isolate, const icu::FormattedValue &formatted)
static V8_WARN_UNUSED_RESULT Maybe< NumberFormatDigitOptions > SetNumberFormatDigitOptions(Isolate *isolate, DirectHandle< JSReceiver > options, int mnfd_default, int mxfd_default, bool notation_is_compact, const char *service)
static const uint8_t * AsciiCollationWeightsL1()
static bool IsValidNumberingSystem(const std::string &value)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSArray > GetCanonicalLocales(Isolate *isolate, DirectHandle< Object > locales)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ConvertToUpper(Isolate *isolate, DirectHandle< String > s)
static DirectHandle< String > SourceString(Isolate *isolate, FormatRangeSource source)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSArray > SupportedValuesOf(Isolate *isolate, DirectHandle< Object > key)
static DirectHandle< Managed< icu::UnicodeString > > SetTextToBreakIterator(Isolate *isolate, DirectHandle< String > text, icu::BreakIterator *break_iterator)
static const uint8_t * AsciiCollationWeightsL3()
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSObject > SupportedLocalesOf(Isolate *isolate, const char *method_name, const std::set< std::string > &available_locales, DirectHandle< Object > locales_in, DirectHandle< Object > options_in)
static DirectHandle< String > NumberFieldToType(Isolate *isolate, const NumberFormatSpan &part, const icu::UnicodeString &text, bool is_nan)
int start
int end
int32_t offset
#define ICU_EXTERNAL_POINTER_TAG_LIST(V)
TNode< Object > receiver
icu::number::FormattedNumber formatted
ZoneVector< RpoNumber > & result
#define ASSIGN_EXTERNAL_POINTER_TAG_FOR_MANAGED(CppType, Tag)
Definition managed.h:49
V8_EXPORT_PRIVATE std::vector< NumberFormatSpan > FlattenRegionsToParts(std::vector< NumberFormatSpan > *regions)
#define DCHECK(condition)
Definition logging.h:482
#define V8_EXPORT_PRIVATE
Definition macros.h:460
std::map< std::string, std::string > extensions
NumberFormatSpan(int32_t field_id, int32_t begin_pos, int32_t end_pos)
Symbol identifier
#define V8_WARN_UNUSED_RESULT
Definition v8config.h:671