1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef builtin_temporal_Temporal_h
8 #define builtin_temporal_Temporal_h
10 #include "mozilla/Assertions.h"
16 #include "builtin/temporal/Int128.h"
17 #include "builtin/temporal/TemporalRoundingMode.h"
18 #include "builtin/temporal/TemporalUnit.h"
19 #include "js/RootingAPI.h"
20 #include "js/TypeDecls.h"
21 #include "vm/NativeObject.h"
29 namespace js::temporal
{
31 class TemporalObject
: public NativeObject
{
33 static const JSClass class_
;
36 static const ClassSpec classSpec_
;
40 * Rounding increment, which is an integer in the range [1, 1'000'000'000].
42 * Temporal units are rounded to a multiple of the specified increment value.
44 class Increment final
{
48 constexpr explicit Increment(uint32_t value
) : value_(value
) {
49 MOZ_ASSERT(1 <= value
&& value
<= 1'000'000'000);
53 * Minimum allowed rounding increment.
55 static constexpr auto min() { return Increment
{1}; }
58 * Maximum allowed rounding increment.
60 static constexpr auto max() { return Increment
{1'000'000'000}; }
63 * The rounding increment's value.
65 uint32_t value() const { return value_
; }
67 bool operator==(const Increment
& other
) const {
68 return value_
== other
.value_
;
71 bool operator<(const Increment
& other
) const { return value_
< other
.value_
; }
73 // Other operators are implemented in terms of operator== and operator<.
74 bool operator!=(const Increment
& other
) const { return !(*this == other
); }
75 bool operator>(const Increment
& other
) const { return other
< *this; }
76 bool operator<=(const Increment
& other
) const { return !(other
< *this); }
77 bool operator>=(const Increment
& other
) const { return !(*this < other
); }
81 * ToTemporalRoundingIncrement ( normalizedOptions, dividend, inclusive )
83 bool ToTemporalRoundingIncrement(JSContext
* cx
, JS::Handle
<JSObject
*> options
,
84 Increment
* increment
);
87 * ValidateTemporalRoundingIncrement ( increment, dividend, inclusive )
89 bool ValidateTemporalRoundingIncrement(JSContext
* cx
, Increment increment
,
90 int64_t dividend
, bool inclusive
);
93 * ValidateTemporalRoundingIncrement ( increment, dividend, inclusive )
95 inline bool ValidateTemporalRoundingIncrement(JSContext
* cx
,
99 return ValidateTemporalRoundingIncrement(cx
, increment
, dividend
.value(),
104 * MaximumTemporalDurationRoundingIncrement ( unit )
106 constexpr Increment
MaximumTemporalDurationRoundingIncrement(
108 // Step 1. (Not applicable in our implementation.)
109 MOZ_ASSERT(unit
> TemporalUnit::Day
);
112 if (unit
== TemporalUnit::Hour
) {
113 return Increment
{24};
117 if (unit
<= TemporalUnit::Second
) {
118 return Increment
{60};
122 return Increment
{1000};
125 PropertyName
* TemporalUnitToString(JSContext
* cx
, TemporalUnit unit
);
127 enum class TemporalUnitGroup
{
128 // Allow date units: "year", "month", "week", "day".
131 // Allow time units: "hour", "minute", "second", "milli-/micro-/nanoseconds".
134 // Allow date and time units.
137 // Allow "day" and time units.
141 enum class TemporalUnitKey
{
148 * GetTemporalUnit ( normalizedOptions, key, unitGroup, default [ , extraValues
151 bool GetTemporalUnit(JSContext
* cx
, JS::Handle
<JSObject
*> options
,
152 TemporalUnitKey key
, TemporalUnitGroup unitGroup
,
156 * GetTemporalUnit ( normalizedOptions, key, unitGroup, default [ , extraValues
159 bool GetTemporalUnit(JSContext
* cx
, JS::Handle
<JSString
*> value
,
160 TemporalUnitKey key
, TemporalUnitGroup unitGroup
,
164 * ToTemporalRoundingMode ( normalizedOptions, fallback )
166 bool ToTemporalRoundingMode(JSContext
* cx
, JS::Handle
<JSObject
*> options
,
167 TemporalRoundingMode
* mode
);
170 * RoundNumberToIncrement ( x, increment, roundingMode )
172 Int128
RoundNumberToIncrement(int64_t numerator
, int64_t denominator
,
174 TemporalRoundingMode roundingMode
);
177 * RoundNumberToIncrement ( x, increment, roundingMode )
179 Int128
RoundNumberToIncrement(const Int128
& numerator
,
180 const Int128
& denominator
, Increment increment
,
181 TemporalRoundingMode roundingMode
);
184 * RoundNumberToIncrement ( x, increment, roundingMode )
186 Int128
RoundNumberToIncrement(const Int128
& x
, const Int128
& increment
,
187 TemporalRoundingMode roundingMode
);
189 enum class CalendarOption
{ Auto
, Always
, Never
, Critical
};
192 * ToCalendarNameOption ( normalizedOptions )
194 bool ToCalendarNameOption(JSContext
* cx
, JS::Handle
<JSObject
*> options
,
195 CalendarOption
* result
);
198 * Precision when displaying fractional seconds.
200 class Precision final
{
204 constexpr Precision(int8_t value
, Tag
) : value_(value
) {}
207 constexpr explicit Precision(uint8_t value
) : value_(value
) {
208 MOZ_ASSERT(value
< 10);
211 bool operator==(const Precision
& other
) const {
212 return value_
== other
.value_
;
215 bool operator!=(const Precision
& other
) const { return !(*this == other
); }
218 * Return the number of fractional second digits.
220 uint8_t value() const {
221 MOZ_ASSERT(value_
>= 0, "auto and minute precision don't have a value");
222 return uint8_t(value_
);
226 * Limit the precision to trim off any trailing zeros.
228 static constexpr Precision
Auto() { return {-1, Tag
{}}; }
231 * Limit the precision to minutes, i.e. don't display seconds and sub-seconds.
233 static constexpr Precision
Minute() { return {-2, Tag
{}}; }
237 * ToFractionalSecondDigits ( normalizedOptions )
239 bool ToFractionalSecondDigits(JSContext
* cx
, JS::Handle
<JSObject
*> options
,
240 Precision
* precision
);
242 struct SecondsStringPrecision final
{
243 Precision precision
= Precision
{0};
244 TemporalUnit unit
= TemporalUnit::Auto
;
245 Increment increment
= Increment
{1};
249 * ToSecondsStringPrecisionRecord ( smallestUnit, fractionalDigitCount )
251 SecondsStringPrecision
ToSecondsStringPrecision(TemporalUnit smallestUnit
,
252 Precision fractionalDigitCount
);
254 enum class TemporalOverflow
{ Constrain
, Reject
};
257 * ToTemporalOverflow ( normalizedOptions )
259 bool ToTemporalOverflow(JSContext
* cx
, JS::Handle
<JSObject
*> options
,
260 TemporalOverflow
* result
);
262 enum class TemporalDisambiguation
{ Compatible
, Earlier
, Later
, Reject
};
265 * ToTemporalDisambiguation ( options )
267 bool ToTemporalDisambiguation(JSContext
* cx
, JS::Handle
<JSObject
*> options
,
268 TemporalDisambiguation
* disambiguation
);
270 enum class TemporalOffset
{ Prefer
, Use
, Ignore
, Reject
};
273 * ToTemporalOffset ( options, fallback )
275 bool ToTemporalOffset(JSContext
* cx
, JS::Handle
<JSObject
*> options
,
276 TemporalOffset
* offset
);
278 enum class TimeZoneNameOption
{ Auto
, Never
, Critical
};
280 bool ToTimeZoneNameOption(JSContext
* cx
, JS::Handle
<JSObject
*> options
,
281 TimeZoneNameOption
* result
);
283 enum class ShowOffsetOption
{ Auto
, Never
};
286 * ToShowOffsetOption ( normalizedOptions )
288 bool ToShowOffsetOption(JSContext
* cx
, JS::Handle
<JSObject
*> options
,
289 ShowOffsetOption
* result
);
292 * RejectTemporalLikeObject ( object )
294 bool RejectTemporalLikeObject(JSContext
* cx
, JS::Handle
<JSObject
*> object
);
297 * ToPositiveIntegerWithTruncation ( argument )
299 bool ToPositiveIntegerWithTruncation(JSContext
* cx
, JS::Handle
<JS::Value
> value
,
300 const char* name
, double* result
);
303 * ToIntegerWithTruncation ( argument )
305 bool ToIntegerWithTruncation(JSContext
* cx
, JS::Handle
<JS::Value
> value
,
306 const char* name
, double* result
);
311 JSObject
* GetMethod(JSContext
* cx
, JS::Handle
<JSObject
*> object
,
312 JS::Handle
<PropertyName
*> name
);
315 * SnapshotOwnProperties ( source, proto [ , excludedKeys [ , excludedValues ] ]
318 PlainObject
* SnapshotOwnProperties(JSContext
* cx
, JS::Handle
<JSObject
*> source
);
321 * SnapshotOwnProperties ( source, proto [ , excludedKeys [ , excludedValues ] ]
324 PlainObject
* SnapshotOwnPropertiesIgnoreUndefined(JSContext
* cx
,
325 JS::Handle
<JSObject
*> source
);
328 * CopyDataProperties ( target, source, excludedKeys [ , excludedValues ] )
330 bool CopyDataProperties(JSContext
* cx
, JS::Handle
<PlainObject
*> target
,
331 JS::Handle
<JSObject
*> source
);
333 enum class TemporalDifference
{ Since
, Until
};
335 inline const char* ToName(TemporalDifference difference
) {
336 return difference
== TemporalDifference::Since
? "since" : "until";
339 struct DifferenceSettings final
{
340 TemporalUnit smallestUnit
= TemporalUnit::Auto
;
341 TemporalUnit largestUnit
= TemporalUnit::Auto
;
342 TemporalRoundingMode roundingMode
= TemporalRoundingMode::Trunc
;
343 Increment roundingIncrement
= Increment
{1};
347 * GetDifferenceSettings ( operation, options, unitGroup, disallowedUnits,
348 * fallbackSmallestUnit, smallestLargestDefaultUnit )
350 bool GetDifferenceSettings(JSContext
* cx
, TemporalDifference operation
,
351 JS::Handle
<PlainObject
*> options
,
352 TemporalUnitGroup unitGroup
,
353 TemporalUnit smallestAllowedUnit
,
354 TemporalUnit fallbackSmallestUnit
,
355 TemporalUnit smallestLargestDefaultUnit
,
356 DifferenceSettings
* result
);
359 * GetDifferenceSettings ( operation, options, unitGroup, disallowedUnits,
360 * fallbackSmallestUnit, smallestLargestDefaultUnit )
362 inline bool GetDifferenceSettings(JSContext
* cx
, TemporalDifference operation
,
363 JS::Handle
<PlainObject
*> options
,
364 TemporalUnitGroup unitGroup
,
365 TemporalUnit fallbackSmallestUnit
,
366 TemporalUnit smallestLargestDefaultUnit
,
367 DifferenceSettings
* result
) {
368 return GetDifferenceSettings(cx
, operation
, options
, unitGroup
,
369 TemporalUnit::Nanosecond
, fallbackSmallestUnit
,
370 smallestLargestDefaultUnit
, result
);
374 * Sets |result| to `true` when array iteration is still in its initial state.
376 bool IsArrayIterationSane(JSContext
* cx
, bool* result
);
378 } /* namespace js::temporal */
380 #endif /* builtin_temporal_Temporal_h */