2024-11-23 10:21:21 -05:00
|
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2021-2023, Linus Groh <linusg@serenityos.org>
|
2025-07-20 08:10:37 -04:00
|
|
|
|
* Copyright (c) 2024-2025, Tim Flynn <trflynn89@ladybird.org>
|
2024-11-23 10:21:21 -05:00
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <LibJS/Runtime/Temporal/AbstractOperations.h>
|
|
|
|
|
#include <LibJS/Runtime/Temporal/PlainTime.h>
|
|
|
|
|
#include <LibJS/Runtime/Temporal/PlainTimeConstructor.h>
|
|
|
|
|
|
|
|
|
|
namespace JS::Temporal {
|
|
|
|
|
|
|
|
|
|
GC_DEFINE_ALLOCATOR(PlainTimeConstructor);
|
|
|
|
|
|
|
|
|
|
// 4.1 The Temporal.PlainTime Constructor, https://tc39.es/proposal-temporal/#sec-temporal-plaintime-constructor
|
|
|
|
|
PlainTimeConstructor::PlainTimeConstructor(Realm& realm)
|
|
|
|
|
: NativeFunction(realm.vm().names.PlainTime.as_string(), realm.intrinsics().function_prototype())
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PlainTimeConstructor::initialize(Realm& realm)
|
|
|
|
|
{
|
|
|
|
|
Base::initialize(realm);
|
|
|
|
|
|
|
|
|
|
auto& vm = this->vm();
|
|
|
|
|
|
|
|
|
|
// 4.2.1 Temporal.PlainTime.prototype, https://tc39.es/proposal-temporal/#sec-temporal.plaintime.prototype
|
|
|
|
|
define_direct_property(vm.names.prototype, realm.intrinsics().temporal_plain_time_prototype(), 0);
|
|
|
|
|
|
|
|
|
|
u8 attr = Attribute::Writable | Attribute::Configurable;
|
|
|
|
|
define_native_function(realm, vm.names.from, from, 1, attr);
|
|
|
|
|
define_native_function(realm, vm.names.compare, compare, 2, attr);
|
|
|
|
|
|
|
|
|
|
define_direct_property(vm.names.length, Value(0), Attribute::Configurable);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 4.1.1 Temporal.PlainTime ( [ hour [ , minute [ , second [ , millisecond [ , microsecond [ , nanosecond ] ] ] ] ] ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaintime
|
|
|
|
|
ThrowCompletionOr<Value> PlainTimeConstructor::call()
|
|
|
|
|
{
|
|
|
|
|
auto& vm = this->vm();
|
|
|
|
|
|
2025-07-20 08:10:37 -04:00
|
|
|
|
// 1. If NewTarget is undefined, throw a TypeError exception.
|
2024-11-23 10:21:21 -05:00
|
|
|
|
return vm.throw_completion<TypeError>(ErrorType::ConstructorWithoutNew, "Temporal.PlainTime");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 4.1.1 Temporal.PlainTime ( [ hour [ , minute [ , second [ , millisecond [ , microsecond [ , nanosecond ] ] ] ] ] ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaintime
|
|
|
|
|
ThrowCompletionOr<GC::Ref<Object>> PlainTimeConstructor::construct(FunctionObject& new_target)
|
|
|
|
|
{
|
|
|
|
|
auto& vm = this->vm();
|
|
|
|
|
|
|
|
|
|
auto next_integer_argument = [&, index = 0]() mutable -> ThrowCompletionOr<double> {
|
|
|
|
|
if (auto value = vm.argument(index++); !value.is_undefined())
|
|
|
|
|
return to_integer_with_truncation(vm, value, ErrorType::TemporalInvalidPlainTime);
|
|
|
|
|
return 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 2. If hour is undefined, set hour to 0; else set hour to ? ToIntegerWithTruncation(hour).
|
|
|
|
|
auto hour = TRY(next_integer_argument());
|
|
|
|
|
|
|
|
|
|
// 3. If minute is undefined, set minute to 0; else set minute to ? ToIntegerWithTruncation(minute).
|
|
|
|
|
auto minute = TRY(next_integer_argument());
|
|
|
|
|
|
|
|
|
|
// 4. If second is undefined, set second to 0; else set second to ? ToIntegerWithTruncation(second).
|
|
|
|
|
auto second = TRY(next_integer_argument());
|
|
|
|
|
|
|
|
|
|
// 5. If millisecond is undefined, set millisecond to 0; else set millisecond to ? ToIntegerWithTruncation(millisecond).
|
|
|
|
|
auto millisecond = TRY(next_integer_argument());
|
|
|
|
|
|
|
|
|
|
// 6. If microsecond is undefined, set microsecond to 0; else set microsecond to ? ToIntegerWithTruncation(microsecond).
|
|
|
|
|
auto microsecond = TRY(next_integer_argument());
|
|
|
|
|
|
|
|
|
|
// 7. If nanosecond is undefined, set nanosecond to 0; else set nanosecond to ? ToIntegerWithTruncation(nanosecond).
|
|
|
|
|
auto nanosecond = TRY(next_integer_argument());
|
|
|
|
|
|
|
|
|
|
// 8. If IsValidTime(hour, minute, second, millisecond, microsecond, nanosecond) is false, throw a RangeError exception.
|
|
|
|
|
if (!is_valid_time(hour, minute, second, millisecond, microsecond, nanosecond))
|
|
|
|
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidPlainTime);
|
|
|
|
|
|
|
|
|
|
// 9. Let time be CreateTimeRecord(hour, minute, second, millisecond, microsecond, nanosecond).
|
|
|
|
|
auto time = create_time_record(hour, minute, second, millisecond, microsecond, nanosecond);
|
|
|
|
|
|
|
|
|
|
// 10. Return ? CreateTemporalTime(time, NewTarget).
|
|
|
|
|
return TRY(create_temporal_time(vm, time, new_target));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 4.2.2 Temporal.PlainTime.from ( item [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaintime.from
|
|
|
|
|
JS_DEFINE_NATIVE_FUNCTION(PlainTimeConstructor::from)
|
|
|
|
|
{
|
|
|
|
|
// 4. Return ? ToTemporalTime(item, overflow).
|
|
|
|
|
return TRY(to_temporal_time(vm, vm.argument(0), vm.argument(1)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 4.2.3 Temporal.PlainTime.compare ( one, two ), https://tc39.es/proposal-temporal/#sec-temporal.plaintime.compare
|
|
|
|
|
JS_DEFINE_NATIVE_FUNCTION(PlainTimeConstructor::compare)
|
|
|
|
|
{
|
|
|
|
|
// 1. Set one to ? ToTemporalTime(one).
|
|
|
|
|
auto one = TRY(to_temporal_time(vm, vm.argument(0)));
|
|
|
|
|
|
|
|
|
|
// 2. Set two to ? ToTemporalTime(two).
|
|
|
|
|
auto two = TRY(to_temporal_time(vm, vm.argument(1)));
|
|
|
|
|
|
|
|
|
|
// 3. Return 𝔽(CompareTimeRecord(one.[[Time]], two.[[Time]])).
|
|
|
|
|
return compare_time_record(one->time(), two->time());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|