LibJS: Implement the Temporal.Duration constructor

This also includes a stubbed Temporal.Duration.prototype.

Until we have re-implemented Temporal.PlainDate/ZonedDateTime, some of
Temporal.Duration.compare (and its invoked AOs) are left unimplemented.
This commit is contained in:
Timothy Flynn 2024-11-18 11:58:51 -05:00 committed by Tim Flynn
commit 5fe0d3352d
Notes: github-actions[bot] 2024-11-21 00:06:22 +00:00
30 changed files with 2143 additions and 26 deletions

View file

@ -14,9 +14,84 @@
#include <LibJS/Runtime/Completion.h>
#include <LibJS/Runtime/VM.h>
#include <LibJS/Runtime/ValueInlines.h>
#include <math.h>
namespace JS::Temporal {
// https://tc39.es/proposal-temporal/#sec-temporal-units
enum class Unit {
Year,
Month,
Week,
Day,
Hour,
Minute,
Second,
Millisecond,
Microsecond,
Nanosecond,
};
StringView temporal_unit_to_string(Unit);
// https://tc39.es/proposal-temporal/#sec-temporal-units
enum class UnitCategory {
Date,
Time,
};
// https://tc39.es/proposal-temporal/#sec-temporal-units
enum class UnitGroup {
Date,
Time,
DateTime,
};
struct Unset { };
using RoundingIncrement = Variant<Unset, u64>;
struct RelativeTo {
// FIXME: Make these objects represent their actual types when we re-implement them.
GC::Ptr<JS::Object> plain_relative_to; // [[PlainRelativeTo]]
GC::Ptr<JS::Object> zoned_relative_to; // [[ZonedRelativeTo]]
};
ThrowCompletionOr<RelativeTo> get_temporal_relative_to_option(VM&, Object const& options);
bool is_calendar_unit(Unit);
UnitCategory temporal_unit_category(Unit);
ThrowCompletionOr<GC::Ref<Duration>> parse_temporal_duration_string(VM&, StringView iso_string);
// 13.38 ToIntegerWithTruncation ( argument ), https://tc39.es/proposal-temporal/#sec-tointegerwithtruncation
template<typename... Args>
ThrowCompletionOr<double> to_integer_with_truncation(VM& vm, Value argument, ErrorType error_type, Args&&... args)
{
// 1. Let number be ? ToNumber(argument).
auto number = TRY(argument.to_number(vm));
// 2. If number is NaN, +∞𝔽 or -∞𝔽, throw a RangeError exception.
if (number.is_nan() || number.is_infinity())
return vm.throw_completion<RangeError>(error_type, forward<Args>(args)...);
// 3. Return truncate((number)).
return trunc(number.as_double());
}
// 13.38 ToIntegerWithTruncation ( argument ), https://tc39.es/proposal-temporal/#sec-tointegerwithtruncation
// AD-HOC: We often need to use this AO when we have a parsed StringView. This overload allows callers to avoid creating
// a PrimitiveString for the primary definition.
template<typename... Args>
ThrowCompletionOr<double> to_integer_with_truncation(VM& vm, StringView argument, ErrorType error_type, Args&&... args)
{
// 1. Let number be ? ToNumber(argument).
auto number = string_to_number(argument);
// 2. If number is NaN, +∞𝔽 or -∞𝔽, throw a RangeError exception.
if (isnan(number) || isinf(number))
return vm.throw_completion<RangeError>(error_type, forward<Args>(args)...);
// 3. Return truncate((number)).
return trunc(number);
}
// 13.39 ToIntegerIfIntegral ( argument ), https://tc39.es/proposal-temporal/#sec-tointegerifintegral
template<typename... Args>
ThrowCompletionOr<double> to_integer_if_integral(VM& vm, Value argument, ErrorType error_type, Args&&... args)