summaryrefslogtreecommitdiff
path: root/deps/v8/src/objects/js-number-format.h
blob: 2979ab10f43f66d44f17b13dcb8b54726a105cc8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_INTL_SUPPORT
#error Internationalization is expected to be enabled.
#endif  // V8_INTL_SUPPORT

#ifndef V8_OBJECTS_JS_NUMBER_FORMAT_H_
#define V8_OBJECTS_JS_NUMBER_FORMAT_H_

#include <set>
#include <string>

#include "src/execution/isolate.h"
#include "src/heap/factory.h"
#include "src/objects/intl-objects.h"
#include "src/objects/managed.h"
#include "src/objects/objects.h"

// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"

namespace U_ICU_NAMESPACE {
class UnicodeString;
namespace number {
class LocalizedNumberFormatter;
}  //  namespace number
}  //  namespace U_ICU_NAMESPACE

namespace v8 {
namespace internal {

class JSNumberFormat : public JSObject {
 public:
  // ecma402/#sec-initializenumberformat
  V8_WARN_UNUSED_RESULT static MaybeHandle<JSNumberFormat> New(
      Isolate* isolate, Handle<Map> map, Handle<Object> locales,
      Handle<Object> options);

  // ecma402/#sec-unwrapnumberformat
  V8_WARN_UNUSED_RESULT static MaybeHandle<JSNumberFormat> UnwrapNumberFormat(
      Isolate* isolate, Handle<JSReceiver> format_holder);

  // ecma402/#sec-intl.numberformat.prototype.resolvedoptions
  static Handle<JSObject> ResolvedOptions(Isolate* isolate,
                                          Handle<JSNumberFormat> number_format);

  V8_WARN_UNUSED_RESULT static MaybeHandle<JSArray> FormatToParts(
      Isolate* isolate, Handle<JSNumberFormat> number_format,
      Handle<Object> numeric_obj);

  V8_WARN_UNUSED_RESULT static MaybeHandle<String> FormatNumeric(
      Isolate* isolate,
      const icu::number::LocalizedNumberFormatter& number_format,
      Handle<Object> numeric_obj);

  V8_EXPORT_PRIVATE static const std::set<std::string>& GetAvailableLocales();

  // Helper functions shared with JSPluralRules.
  static int32_t MinimumIntegerDigitsFromSkeleton(
      const icu::UnicodeString& skeleton);
  static bool FractionDigitsFromSkeleton(const icu::UnicodeString& skeleton,
                                         int32_t* minimum, int32_t* maximum);
  static bool SignificantDigitsFromSkeleton(const icu::UnicodeString& skeleton,
                                            int32_t* minimum, int32_t* maximum);
  static icu::number::LocalizedNumberFormatter SetDigitOptionsToFormatter(
      const icu::number::LocalizedNumberFormatter& icu_number_formatter,
      const Intl::NumberFormatDigitOptions& digit_options);

  DECL_CAST(JSNumberFormat)
  DECL_PRINTER(JSNumberFormat)
  DECL_VERIFIER(JSNumberFormat)

  // Current ECMA 402 spec mandates to record (Min|Max)imumFractionDigits
  // unconditionally while the unified number proposal eventually will only
  // record either (Min|Max)imumFractionDigits or (Min|Max)imumSignaficantDigits
  // Since LocalizedNumberFormatter can only remember one set, and during
  // 2019-1-17 ECMA402 meeting that the committee decide not to take a PR to
  // address that prior to the unified number proposal, we have to add these two
  // 5 bits int into flags to remember the (Min|Max)imumFractionDigits while
  // (Min|Max)imumSignaficantDigits is present.
  // TODO(ftang) remove the following once we ship int-number-format-unified
  //  * Four inline functions: (set_)?(min|max)imum_fraction_digits
  //  * kFlagsOffset
  //  * #define FLAGS_BIT_FIELDS
  //  * DECL_INT_ACCESSORS(flags)

  inline int minimum_fraction_digits() const;
  inline void set_minimum_fraction_digits(int digits);

  inline int maximum_fraction_digits() const;
  inline void set_maximum_fraction_digits(int digits);

  // [[Style]] is one of the values "decimal", "percent", "currency",
  // or "unit" identifying the style of the number format.
  // Note: "unit" is added in proposal-unified-intl-numberformat
  enum class Style { DECIMAL, PERCENT, CURRENCY, UNIT };

  inline void set_style(Style style);
  inline Style style() const;

  // Layout description.
  DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
                                TORQUE_GENERATED_JSNUMBER_FORMAT_FIELDS)

// Bit positions in |flags|.
#define FLAGS_BIT_FIELDS(V, _)            \
  V(MinimumFractionDigitsBits, int, 5, _) \
  V(MaximumFractionDigitsBits, int, 5, _) \
  V(StyleBits, Style, 2, _)

  DEFINE_BIT_FIELDS(FLAGS_BIT_FIELDS)
#undef FLAGS_BIT_FIELDS

  STATIC_ASSERT(20 <= MinimumFractionDigitsBits::kMax);
  STATIC_ASSERT(20 <= MaximumFractionDigitsBits::kMax);
  STATIC_ASSERT(Style::DECIMAL <= StyleBits::kMax);
  STATIC_ASSERT(Style::PERCENT <= StyleBits::kMax);
  STATIC_ASSERT(Style::CURRENCY <= StyleBits::kMax);
  STATIC_ASSERT(Style::UNIT <= StyleBits::kMax);

  DECL_ACCESSORS(locale, String)
  DECL_ACCESSORS(icu_number_formatter,
                 Managed<icu::number::LocalizedNumberFormatter>)
  DECL_ACCESSORS(bound_format, Object)
  DECL_INT_ACCESSORS(flags)

  OBJECT_CONSTRUCTORS(JSNumberFormat, JSObject);
};

struct NumberFormatSpan {
  int32_t field_id;
  int32_t begin_pos;
  int32_t end_pos;

  NumberFormatSpan() = default;
  NumberFormatSpan(int32_t field_id, int32_t begin_pos, int32_t end_pos)
      : field_id(field_id), begin_pos(begin_pos), end_pos(end_pos) {}
};

V8_EXPORT_PRIVATE std::vector<NumberFormatSpan> FlattenRegionsToParts(
    std::vector<NumberFormatSpan>* regions);

}  // namespace internal
}  // namespace v8

#include "src/objects/object-macros-undef.h"

#endif  // V8_OBJECTS_JS_NUMBER_FORMAT_H_