ladybird/Libraries/LibJS/Runtime/Temporal/PlainTimeConstructor.cpp
Timothy Flynn 66365fef57 LibJS: Implement the Temporal.PlainTime constructor
And the simple Temporal.PlainTime.prototype getters, so that the
constructed Temporal.PlainTime may actually be validated.
2024-11-23 19:35:36 -05:00

108 lines
4.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (c) 2021-2023, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2024, Tim Flynn <trflynn89@ladybird.org>
*
* 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();
// 1. If NewTarget is undefined, then
// a. Throw a TypeError exception.
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());
}
}