1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 04:17:35 +00:00

LibJS: Port prepare_temporal_fields() and calendar_fields() to String

This commit is contained in:
Linus Groh 2023-01-26 14:37:52 +00:00
parent 90a1de564c
commit 227379a1da
7 changed files with 45 additions and 21 deletions

View file

@ -1740,7 +1740,7 @@ ThrowCompletionOr<double> to_positive_integer_with_truncation(VM& vm, Value argu
}
// 13.43 PrepareTemporalFields ( fields, fieldNames, requiredFields ), https://tc39.es/proposal-temporal/#sec-temporal-preparetemporalfields
ThrowCompletionOr<Object*> prepare_temporal_fields(VM& vm, Object const& fields, Vector<DeprecatedString> const& field_names, Variant<PrepareTemporalFieldsPartial, Vector<StringView>> const& required_fields)
ThrowCompletionOr<Object*> prepare_temporal_fields(VM& vm, Object const& fields, Vector<String> const& field_names, Variant<PrepareTemporalFieldsPartial, Vector<StringView>> const& required_fields)
{
auto& realm = *vm.current_realm();
@ -1754,7 +1754,7 @@ ThrowCompletionOr<Object*> prepare_temporal_fields(VM& vm, Object const& fields,
// 3. For each value property of fieldNames, do
for (auto& property : field_names) {
// a. Let value be ? Get(fields, property).
auto value = TRY(fields.get(property));
auto value = TRY(fields.get(property.to_deprecated_string()));
// b. If value is not undefined, then
if (!value.is_undefined()) {
@ -1783,7 +1783,7 @@ ThrowCompletionOr<Object*> prepare_temporal_fields(VM& vm, Object const& fields,
}
// iii. Perform ! CreateDataPropertyOrThrow(result, property, value).
MUST(result->create_data_property_or_throw(property, value));
MUST(result->create_data_property_or_throw(property.to_deprecated_string(), value));
}
// c. Else if requiredFields is a List, then
else if (required_fields.has<Vector<StringView>>()) {
@ -1800,13 +1800,14 @@ ThrowCompletionOr<Object*> prepare_temporal_fields(VM& vm, Object const& fields,
}
// iii. Perform ! CreateDataPropertyOrThrow(result, property, value).
MUST(result->create_data_property_or_throw(property, value));
MUST(result->create_data_property_or_throw(property.to_deprecated_string(), value));
}
}
// 4. If requiredFields is partial and any is false, then
if (required_fields.has<PrepareTemporalFieldsPartial>() && !any) {
// a. Throw a TypeError exception.
// FIXME: Add & use String::join()
return vm.throw_completion<TypeError>(ErrorType::TemporalObjectMustHaveOneOf, DeprecatedString::join(", "sv, field_names));
}

View file

@ -175,7 +175,7 @@ ThrowCompletionOr<TemporalTime> parse_temporal_time_string(VM&, StringView iso_s
ThrowCompletionOr<TemporalTimeZone> parse_temporal_time_zone_string(VM&, StringView iso_string);
ThrowCompletionOr<TemporalYearMonth> parse_temporal_year_month_string(VM&, StringView iso_string);
ThrowCompletionOr<double> to_positive_integer_with_truncation(VM&, Value argument);
ThrowCompletionOr<Object*> prepare_temporal_fields(VM&, Object const& fields, Vector<DeprecatedString> const& field_names, Variant<PrepareTemporalFieldsPartial, Vector<StringView>> const& required_fields);
ThrowCompletionOr<Object*> prepare_temporal_fields(VM&, Object const& fields, Vector<String> const& field_names, Variant<PrepareTemporalFieldsPartial, Vector<StringView>> const& required_fields);
ThrowCompletionOr<DifferenceSettings> get_difference_settings(VM&, DifferenceOperation, Value options_value, UnitGroup unit_group, Vector<StringView> const& disallowed_units, TemporalUnitDefault const& fallback_smallest_unit, StringView smallest_largest_default_unit);
template<size_t Size>

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
* Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2021-2023, Linus Groh <linusg@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -103,7 +103,7 @@ Calendar* get_iso8601_calendar(VM& vm)
}
// 12.2.4 CalendarFields ( calendar, fieldNames ), https://tc39.es/proposal-temporal/#sec-temporal-calendarfields
ThrowCompletionOr<Vector<DeprecatedString>> calendar_fields(VM& vm, Object& calendar, Vector<StringView> const& field_names)
ThrowCompletionOr<Vector<String>> calendar_fields(VM& vm, Object& calendar, Vector<StringView> const& field_names)
{
auto& realm = *vm.current_realm();
@ -112,9 +112,10 @@ ThrowCompletionOr<Vector<DeprecatedString>> calendar_fields(VM& vm, Object& cale
// 2. If fields is undefined, return fieldNames.
if (!fields) {
Vector<DeprecatedString> result;
Vector<String> result;
TRY_OR_THROW_OOM(vm, result.try_ensure_capacity(field_names.size()));
for (auto& value : field_names)
result.append(value);
result.unchecked_append(TRY_OR_THROW_OOM(vm, String::from_utf8(value)));
return result;
}
@ -124,9 +125,10 @@ ThrowCompletionOr<Vector<DeprecatedString>> calendar_fields(VM& vm, Object& cale
// 4. Return ? IterableToListOfType(fieldsArray, « String »).
auto list = TRY(iterable_to_list_of_type(vm, fields_array, { OptionType::String }));
Vector<DeprecatedString> result;
Vector<String> result;
TRY_OR_THROW_OOM(vm, result.try_ensure_capacity(list.size()));
for (auto& value : list)
result.append(TRY(value.as_string().deprecated_string()));
result.unchecked_append(TRY(value.as_string().utf8_string()));
return result;
}
@ -818,7 +820,12 @@ ThrowCompletionOr<ISODateRecord> iso_date_from_fields(VM& vm, Object const& fiel
// 1. Assert: Type(fields) is Object.
// 2. Set fields to ? PrepareTemporalFields(fields, « "day", "month", "monthCode", "year" », « "year", "day" »).
auto* prepared_fields = TRY(prepare_temporal_fields(vm, fields, { "day", "month", "monthCode", "year" }, Vector<StringView> { "year"sv, "day"sv }));
auto* prepared_fields = TRY(prepare_temporal_fields(vm, fields,
{ String::from_utf8_short_string("day"sv),
TRY_OR_THROW_OOM(vm, String::from_utf8("month"sv)),
TRY_OR_THROW_OOM(vm, String::from_utf8("monthCode"sv)),
TRY_OR_THROW_OOM(vm, String::from_utf8("year"sv)) },
Vector<StringView> { "year"sv, "day"sv }));
// 3. Let overflow be ? ToTemporalOverflow(options).
auto overflow = TRY(to_temporal_overflow(vm, &options));
@ -848,7 +855,11 @@ ThrowCompletionOr<ISOYearMonth> iso_year_month_from_fields(VM& vm, Object const&
// 1. Assert: Type(fields) is Object.
// 2. Set fields to ? PrepareTemporalFields(fields, « "month", "monthCode", "year" », « "year" »).
auto* prepared_fields = TRY(prepare_temporal_fields(vm, fields, { "month"sv, "monthCode"sv, "year"sv }, Vector<StringView> { "year"sv }));
auto* prepared_fields = TRY(prepare_temporal_fields(vm, fields,
{ TRY_OR_THROW_OOM(vm, String::from_utf8("month"sv)),
TRY_OR_THROW_OOM(vm, String::from_utf8("monthCode"sv)),
TRY_OR_THROW_OOM(vm, String::from_utf8("year"sv)) },
Vector<StringView> { "year"sv }));
// 3. Let overflow be ? ToTemporalOverflow(options).
auto overflow = TRY(to_temporal_overflow(vm, &options));
@ -875,7 +886,12 @@ ThrowCompletionOr<ISOMonthDay> iso_month_day_from_fields(VM& vm, Object const& f
// 1. Assert: Type(fields) is Object.
// 2. Set fields to ? PrepareTemporalFields(fields, « "day", "month", "monthCode", "year" », « "day" »).
auto* prepared_fields = TRY(prepare_temporal_fields(vm, fields, { "day"sv, "month"sv, "monthCode"sv, "year"sv }, Vector<StringView> { "day"sv }));
auto* prepared_fields = TRY(prepare_temporal_fields(vm, fields,
{ String::from_utf8_short_string("day"sv),
TRY_OR_THROW_OOM(vm, String::from_utf8("month"sv)),
TRY_OR_THROW_OOM(vm, String::from_utf8("monthCode"sv)),
TRY_OR_THROW_OOM(vm, String::from_utf8("year"sv)) },
Vector<StringView> { "day"sv }));
// 3. Let overflow be ? ToTemporalOverflow(options).
auto overflow = TRY(to_temporal_overflow(vm, &options));

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
* Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2021-2023, Linus Groh <linusg@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -42,7 +42,7 @@ Span<StringView const> available_calendars();
ThrowCompletionOr<Calendar*> create_temporal_calendar(VM&, DeprecatedString const& identifier, FunctionObject const* new_target = nullptr);
ThrowCompletionOr<Calendar*> get_builtin_calendar(VM&, DeprecatedString const& identifier);
Calendar* get_iso8601_calendar(VM&);
ThrowCompletionOr<Vector<DeprecatedString>> calendar_fields(VM&, Object& calendar, Vector<StringView> const& field_names);
ThrowCompletionOr<Vector<String>> calendar_fields(VM&, Object& calendar, Vector<StringView> const& field_names);
ThrowCompletionOr<Object*> calendar_merge_fields(VM&, Object& calendar, Object& fields, Object& additional_fields);
ThrowCompletionOr<PlainDate*> calendar_date_add(VM&, Object& calendar, Value date, Duration&, Object* options = nullptr, FunctionObject* date_add = nullptr);
ThrowCompletionOr<Duration*> calendar_date_until(VM&, Object& calendar, Value one, Value two, Object& options, FunctionObject* date_until = nullptr);

View file

@ -343,7 +343,14 @@ ThrowCompletionOr<TemporalTimeLikeRecord> to_temporal_time_record(VM& vm, Object
// 1. If completeness is not present, set completeness to complete.
// 2. Let partial be ? PrepareTemporalFields(temporalTimeLike, « "hour", "microsecond", "millisecond", "minute", "nanosecond", "second" », partial).
auto* partial = TRY(prepare_temporal_fields(vm, temporal_time_like, { "hour"sv, "microsecond"sv, "millisecond"sv, "minute"sv, "nanosecond"sv, "second"sv }, PrepareTemporalFieldsPartial {}));
auto* partial = TRY(prepare_temporal_fields(vm, temporal_time_like,
{ TRY_OR_THROW_OOM(vm, String::from_utf8("hour"sv)),
TRY_OR_THROW_OOM(vm, String::from_utf8("microsecond"sv)),
TRY_OR_THROW_OOM(vm, String::from_utf8("millisecond"sv)),
TRY_OR_THROW_OOM(vm, String::from_utf8("minute"sv)),
TRY_OR_THROW_OOM(vm, String::from_utf8("nanosecond"sv)),
TRY_OR_THROW_OOM(vm, String::from_utf8("second"sv)) },
PrepareTemporalFieldsPartial {}));
TemporalTimeLikeRecord result;
// 3. If completeness is complete, then

View file

@ -150,10 +150,10 @@ ThrowCompletionOr<ZonedDateTime*> to_temporal_zoned_date_time(VM& vm, Value item
auto field_names = TRY(calendar_fields(vm, *calendar, { "day"sv, "hour"sv, "microsecond"sv, "millisecond"sv, "minute"sv, "month"sv, "monthCode"sv, "nanosecond"sv, "second"sv, "year"sv }));
// d. Append "timeZone" to fieldNames.
field_names.append("timeZone");
field_names.append(TRY_OR_THROW_OOM(vm, String::from_utf8("timeZone"sv)));
// e. Append "offset" to fieldNames.
field_names.append("offset");
field_names.append(TRY_OR_THROW_OOM(vm, String::from_utf8("offset"sv)));
// f. Let fields be ? PrepareTemporalFields(item, fieldNames, « "timeZone" »).
auto* fields = TRY(prepare_temporal_fields(vm, item_object, field_names, Vector<StringView> { "timeZone"sv }));

View file

@ -767,7 +767,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::with)
auto field_names = TRY(calendar_fields(vm, calendar, { "day"sv, "hour"sv, "microsecond"sv, "millisecond"sv, "minute"sv, "month"sv, "monthCode"sv, "nanosecond"sv, "second"sv, "year"sv }));
// 7. Append "offset" to fieldNames.
field_names.append("offset"sv);
field_names.append(TRY_OR_THROW_OOM(vm, String::from_utf8("offset"sv)));
// 8. Let partialZonedDateTime be ? PrepareTemporalFields(temporalZonedDateTimeLike, fieldNames, partial).
auto* partial_zoned_date_time = TRY(prepare_temporal_fields(vm, temporal_zoned_date_time_like.as_object(), field_names, PrepareTemporalFieldsPartial {}));
@ -785,7 +785,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::with)
auto& time_zone = zoned_date_time->time_zone();
// 13. Append "timeZone" to fieldNames.
field_names.append("timeZone"sv);
field_names.append(TRY_OR_THROW_OOM(vm, String::from_utf8("timeZone"sv)));
// 14. Let fields be ? PrepareTemporalFields(zonedDateTime, fieldNames, « "timeZone", "offset" »).
auto* fields = TRY(prepare_temporal_fields(vm, *zoned_date_time, field_names, Vector<StringView> { "timeZone"sv, "offset"sv }));