From aa61307392ba50d3cfa6dce1d1656d7e7ac80b46 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Mon, 3 Mar 2025 08:47:10 -0500 Subject: [PATCH] LibJS: Re-arrange and rename a few Intl properties This is an editorial change in the ECMA-402 spec. See: https://github.com/tc39/ecma402/commit/a46e37d https://github.com/tc39/ecma402/commit/e102741 https://github.com/tc39/ecma402/commit/67a8417 https://github.com/tc39/ecma402/commit/ecb086c --- .../LibJS/Runtime/Intl/CollatorPrototype.cpp | 54 ++--- .../LibJS/Runtime/Intl/CollatorPrototype.h | 4 +- .../Runtime/Intl/DateTimeFormatPrototype.cpp | 228 +++++++++--------- .../Runtime/Intl/DateTimeFormatPrototype.h | 6 +- .../Runtime/Intl/DisplayNamesPrototype.cpp | 64 ++--- .../Runtime/Intl/DisplayNamesPrototype.h | 4 +- .../Runtime/Intl/ListFormatPrototype.cpp | 54 ++--- .../LibJS/Runtime/Intl/ListFormatPrototype.h | 4 +- .../LibJS/Runtime/Intl/LocalePrototype.cpp | 158 ++++++------ .../LibJS/Runtime/Intl/LocalePrototype.h | 6 +- .../Runtime/Intl/NumberFormatPrototype.cpp | 196 +++++++-------- .../Runtime/Intl/NumberFormatPrototype.h | 6 +- .../Runtime/Intl/PluralRulesPrototype.cpp | 90 +++---- .../LibJS/Runtime/Intl/PluralRulesPrototype.h | 2 +- .../Intl/RelativeTimeFormatPrototype.cpp | 56 ++--- .../Intl/RelativeTimeFormatPrototype.h | 4 +- .../LibJS/Runtime/Intl/SegmentIterator.cpp | 4 +- .../Runtime/Intl/SegmentIteratorPrototype.cpp | 6 +- .../Runtime/Intl/SegmenterConstructor.cpp | 2 +- .../LibJS/Runtime/Intl/SegmenterPrototype.cpp | 4 +- .../LibJS/Runtime/Intl/SegmenterPrototype.h | 2 +- Libraries/LibJS/Runtime/Intl/Segments.cpp | 2 +- .../LibJS/Runtime/Intl/SegmentsPrototype.cpp | 6 +- 23 files changed, 481 insertions(+), 481 deletions(-) diff --git a/Libraries/LibJS/Runtime/Intl/CollatorPrototype.cpp b/Libraries/LibJS/Runtime/Intl/CollatorPrototype.cpp index 169eff868ad..f1a194252fd 100644 --- a/Libraries/LibJS/Runtime/Intl/CollatorPrototype.cpp +++ b/Libraries/LibJS/Runtime/Intl/CollatorPrototype.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Tim Flynn + * Copyright (c) 2022-2025, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -25,38 +25,15 @@ void CollatorPrototype::initialize(Realm& realm) auto& vm = this->vm(); - // 10.3.2 Intl.Collator.prototype [ @@toStringTag ], https://tc39.es/ecma402/#sec-intl.collator.prototype-@@tostringtag + // 10.3.4 Intl.Collator.prototype [ %Symbol.toStringTag% ], https://tc39.es/ecma402/#sec-intl.collator.prototype-%symbol.tostringtag% define_direct_property(vm.well_known_symbol_to_string_tag(), PrimitiveString::create(vm, "Intl.Collator"_string), Attribute::Configurable); u8 attr = Attribute::Writable | Attribute::Configurable; - define_native_accessor(realm, vm.names.compare, compare_getter, {}, attr); define_native_function(realm, vm.names.resolvedOptions, resolved_options, 0, attr); + define_native_accessor(realm, vm.names.compare, compare_getter, {}, attr); } -// 10.3.3 get Intl.Collator.prototype.compare, https://tc39.es/ecma402/#sec-intl.collator.prototype.compare -JS_DEFINE_NATIVE_FUNCTION(CollatorPrototype::compare_getter) -{ - auto& realm = *vm.current_realm(); - - // 1. Let collator be the this value. - // 2. Perform ? RequireInternalSlot(collator, [[InitializedCollator]]). - auto collator = TRY(typed_this_object(vm)); - - // 3. If collator.[[BoundCompare]] is undefined, then - if (!collator->bound_compare()) { - // a. Let F be a new built-in function object as defined in 10.3.3.1. - // b. Set F.[[Collator]] to collator. - auto function = CollatorCompareFunction::create(realm, collator); - - // c. Set collator.[[BoundCompare]] to F. - collator->set_bound_compare(function); - } - - // 4. Return collator.[[BoundCompare]]. - return collator->bound_compare(); -} - -// 10.3.4 Intl.Collator.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.collator.prototype.resolvedoptions +// 10.3.2 Intl.Collator.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.collator.prototype.resolvedoptions JS_DEFINE_NATIVE_FUNCTION(CollatorPrototype::resolved_options) { auto& realm = *vm.current_realm(); @@ -89,4 +66,27 @@ JS_DEFINE_NATIVE_FUNCTION(CollatorPrototype::resolved_options) return options; } +// 10.3.3 get Intl.Collator.prototype.compare, https://tc39.es/ecma402/#sec-intl.collator.prototype.compare +JS_DEFINE_NATIVE_FUNCTION(CollatorPrototype::compare_getter) +{ + auto& realm = *vm.current_realm(); + + // 1. Let collator be the this value. + // 2. Perform ? RequireInternalSlot(collator, [[InitializedCollator]]). + auto collator = TRY(typed_this_object(vm)); + + // 3. If collator.[[BoundCompare]] is undefined, then + if (!collator->bound_compare()) { + // a. Let F be a new built-in function object as defined in 10.3.3.1. + // b. Set F.[[Collator]] to collator. + auto function = CollatorCompareFunction::create(realm, collator); + + // c. Set collator.[[BoundCompare]] to F. + collator->set_bound_compare(function); + } + + // 4. Return collator.[[BoundCompare]]. + return collator->bound_compare(); +} + } diff --git a/Libraries/LibJS/Runtime/Intl/CollatorPrototype.h b/Libraries/LibJS/Runtime/Intl/CollatorPrototype.h index 9b941a768fe..0caf3b03d0b 100644 --- a/Libraries/LibJS/Runtime/Intl/CollatorPrototype.h +++ b/Libraries/LibJS/Runtime/Intl/CollatorPrototype.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Tim Flynn + * Copyright (c) 2022-2025, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -22,8 +22,8 @@ public: private: explicit CollatorPrototype(Realm&); - JS_DECLARE_NATIVE_FUNCTION(compare_getter); JS_DECLARE_NATIVE_FUNCTION(resolved_options); + JS_DECLARE_NATIVE_FUNCTION(compare_getter); }; } diff --git a/Libraries/LibJS/Runtime/Intl/DateTimeFormatPrototype.cpp b/Libraries/LibJS/Runtime/Intl/DateTimeFormatPrototype.cpp index e8e4acc5552..3cfdc7327dc 100644 --- a/Libraries/LibJS/Runtime/Intl/DateTimeFormatPrototype.cpp +++ b/Libraries/LibJS/Runtime/Intl/DateTimeFormatPrototype.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024, Tim Flynn + * Copyright (c) 2021-2025, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -28,128 +28,19 @@ void DateTimeFormatPrototype::initialize(Realm& realm) auto& vm = this->vm(); - // 11.3.2 Intl.DateTimeFormat.prototype [ @@toStringTag ], https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype-@@tostringtag + // 11.3.7 Intl.DateTimeFormat.prototype [ %Symbol.toStringTag% ], https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype-%symbol.tostringtag% define_direct_property(vm.well_known_symbol_to_string_tag(), PrimitiveString::create(vm, "Intl.DateTimeFormat"_string), Attribute::Configurable); define_native_accessor(realm, vm.names.format, format, nullptr, Attribute::Configurable); u8 attr = Attribute::Writable | Attribute::Configurable; - define_native_function(realm, vm.names.formatToParts, format_to_parts, 1, attr); + define_native_function(realm, vm.names.resolvedOptions, resolved_options, 0, attr); define_native_function(realm, vm.names.formatRange, format_range, 2, attr); define_native_function(realm, vm.names.formatRangeToParts, format_range_to_parts, 2, attr); - define_native_function(realm, vm.names.resolvedOptions, resolved_options, 0, attr); + define_native_function(realm, vm.names.formatToParts, format_to_parts, 1, attr); } -// 11.3.3 get Intl.DateTimeFormat.prototype.format, https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype.format -JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format) -{ - auto& realm = *vm.current_realm(); - - // 1. Let dtf be the this value. - // 2. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then - // a. Set dtf to ? UnwrapDateTimeFormat(dtf). - // 3. Perform ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]]). - auto date_time_format = TRY(typed_this_object(vm)); - - // 4. If dtf.[[BoundFormat]] is undefined, then - if (!date_time_format->bound_format()) { - // a. Let F be a new built-in function object as defined in DateTime Format Functions (11.1.6). - // b. Set F.[[DateTimeFormat]] to dtf. - auto bound_format = DateTimeFormatFunction::create(realm, date_time_format); - - // c. Set dtf.[[BoundFormat]] to F. - date_time_format->set_bound_format(bound_format); - } - - // 5. Return dtf.[[BoundFormat]]. - return date_time_format->bound_format(); -} - -// 11.3.4 Intl.DateTimeFormat.prototype.formatToParts ( date ), https://tc39.es/ecma402/#sec-Intl.DateTimeFormat.prototype.formatToParts -// 15.10.1 Intl.DateTimeFormat.prototype.formatToParts ( date ), https://tc39.es/proposal-temporal/#sec-Intl.DateTimeFormat.prototype.formatToParts -JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format_to_parts) -{ - auto& realm = *vm.current_realm(); - - auto date_value = vm.argument(0); - - // 1. Let dtf be the this value. - // 2. Perform ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]]). - auto date_time_format = TRY(typed_this_object(vm)); - - FormattableDateTime date { 0 }; - - // 3. If date is undefined, then - if (date_value.is_undefined()) { - // a. Let x be ! Call(%Date.now%, undefined). - date = MUST(call(vm, *realm.intrinsics().date_constructor_now_function(), js_undefined())).as_double(); - } - // 4. Else, - else { - // a. Let x be ? ToDateTimeFormattable(date). - date = TRY(to_date_time_formattable(vm, date_value)); - } - - // 5. Return ? FormatDateTimeToParts(dtf, x). - return TRY(format_date_time_to_parts(vm, date_time_format, date)); -} - -// 11.3.5 Intl.DateTimeFormat.prototype.formatRange ( startDate, endDate ), https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype.formatRange -// 15.10.2 Intl.DateTimeFormat.prototype.formatRange ( startDate, endDate ), https://tc39.es/proposal-temporal/#sec-intl.datetimeformat.prototype.formatRange -JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format_range) -{ - auto start_date_value = vm.argument(0); - auto end_date_value = vm.argument(1); - - // 1. Let dtf be this value. - // 2. Perform ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]]). - auto date_time_format = TRY(typed_this_object(vm)); - - // 3. If startDate is undefined or endDate is undefined, throw a TypeError exception. - if (start_date_value.is_undefined()) - return vm.throw_completion(ErrorType::IsUndefined, "startDate"sv); - if (end_date_value.is_undefined()) - return vm.throw_completion(ErrorType::IsUndefined, "endDate"sv); - - // 4. Let x be ? ToDateTimeFormattable(startDate). - auto start_date = TRY(to_date_time_formattable(vm, start_date_value)); - - // 5. Let y be ? ToDateTimeFormattable(endDate). - auto end_date = TRY(to_date_time_formattable(vm, end_date_value)); - - // 6. Return ? FormatDateTimeRange(dtf, x, y). - auto formatted = TRY(format_date_time_range(vm, date_time_format, start_date, end_date)); - return PrimitiveString::create(vm, move(formatted)); -} - -// 11.3.6 Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate, endDate ), https://tc39.es/ecma402/#sec-Intl.DateTimeFormat.prototype.formatRangeToParts -// 15.10.3 Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate, endDate ), https://tc39.es/proposal-temporal/#sec-Intl.DateTimeFormat.prototype.formatRangeToParts -JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format_range_to_parts) -{ - auto start_date_value = vm.argument(0); - auto end_date_value = vm.argument(1); - - // 1. Let dtf be this value. - // 2. Perform ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]]). - auto date_time_format = TRY(typed_this_object(vm)); - - // 3. If startDate is undefined or endDate is undefined, throw a TypeError exception. - if (start_date_value.is_undefined()) - return vm.throw_completion(ErrorType::IsUndefined, "startDate"sv); - if (end_date_value.is_undefined()) - return vm.throw_completion(ErrorType::IsUndefined, "endDate"sv); - - // 4. Let x be ? ToDateTimeFormattable(startDate). - auto start_date = TRY(to_date_time_formattable(vm, start_date_value)); - - // 5. Let y be ? ToDateTimeFormattable(endDate). - auto end_date = TRY(to_date_time_formattable(vm, end_date_value)); - - // 6. Return ? FormatDateTimeRangeToParts(dtf, x, y). - return TRY(format_date_time_range_to_parts(vm, date_time_format, start_date, end_date)); -} - -// 11.3.7 Intl.DateTimeFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype.resolvedoptions +// 11.3.2 Intl.DateTimeFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype.resolvedoptions JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::resolved_options) { auto& realm = *vm.current_realm(); @@ -229,4 +120,113 @@ JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::resolved_options) return options; } +// 11.3.3 get Intl.DateTimeFormat.prototype.format, https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype.format +JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format) +{ + auto& realm = *vm.current_realm(); + + // 1. Let dtf be the this value. + // 2. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then + // a. Set dtf to ? UnwrapDateTimeFormat(dtf). + // 3. Perform ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]]). + auto date_time_format = TRY(typed_this_object(vm)); + + // 4. If dtf.[[BoundFormat]] is undefined, then + if (!date_time_format->bound_format()) { + // a. Let F be a new built-in function object as defined in DateTime Format Functions (11.1.6). + // b. Set F.[[DateTimeFormat]] to dtf. + auto bound_format = DateTimeFormatFunction::create(realm, date_time_format); + + // c. Set dtf.[[BoundFormat]] to F. + date_time_format->set_bound_format(bound_format); + } + + // 5. Return dtf.[[BoundFormat]]. + return date_time_format->bound_format(); +} + +// 11.3.4 Intl.DateTimeFormat.prototype.formatRange ( startDate, endDate ), https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype.formatRange +// 15.10.2 Intl.DateTimeFormat.prototype.formatRange ( startDate, endDate ), https://tc39.es/proposal-temporal/#sec-intl.datetimeformat.prototype.formatRange +JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format_range) +{ + auto start_date_value = vm.argument(0); + auto end_date_value = vm.argument(1); + + // 1. Let dtf be this value. + // 2. Perform ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]]). + auto date_time_format = TRY(typed_this_object(vm)); + + // 3. If startDate is undefined or endDate is undefined, throw a TypeError exception. + if (start_date_value.is_undefined()) + return vm.throw_completion(ErrorType::IsUndefined, "startDate"sv); + if (end_date_value.is_undefined()) + return vm.throw_completion(ErrorType::IsUndefined, "endDate"sv); + + // 4. Let x be ? ToDateTimeFormattable(startDate). + auto start_date = TRY(to_date_time_formattable(vm, start_date_value)); + + // 5. Let y be ? ToDateTimeFormattable(endDate). + auto end_date = TRY(to_date_time_formattable(vm, end_date_value)); + + // 6. Return ? FormatDateTimeRange(dtf, x, y). + auto formatted = TRY(format_date_time_range(vm, date_time_format, start_date, end_date)); + return PrimitiveString::create(vm, move(formatted)); +} + +// 11.3.5 Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate, endDate ), https://tc39.es/ecma402/#sec-Intl.DateTimeFormat.prototype.formatRangeToParts +// 15.10.3 Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate, endDate ), https://tc39.es/proposal-temporal/#sec-Intl.DateTimeFormat.prototype.formatRangeToParts +JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format_range_to_parts) +{ + auto start_date_value = vm.argument(0); + auto end_date_value = vm.argument(1); + + // 1. Let dtf be this value. + // 2. Perform ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]]). + auto date_time_format = TRY(typed_this_object(vm)); + + // 3. If startDate is undefined or endDate is undefined, throw a TypeError exception. + if (start_date_value.is_undefined()) + return vm.throw_completion(ErrorType::IsUndefined, "startDate"sv); + if (end_date_value.is_undefined()) + return vm.throw_completion(ErrorType::IsUndefined, "endDate"sv); + + // 4. Let x be ? ToDateTimeFormattable(startDate). + auto start_date = TRY(to_date_time_formattable(vm, start_date_value)); + + // 5. Let y be ? ToDateTimeFormattable(endDate). + auto end_date = TRY(to_date_time_formattable(vm, end_date_value)); + + // 6. Return ? FormatDateTimeRangeToParts(dtf, x, y). + return TRY(format_date_time_range_to_parts(vm, date_time_format, start_date, end_date)); +} + +// 11.3.6 Intl.DateTimeFormat.prototype.formatToParts ( date ), https://tc39.es/ecma402/#sec-Intl.DateTimeFormat.prototype.formatToParts +// 15.10.1 Intl.DateTimeFormat.prototype.formatToParts ( date ), https://tc39.es/proposal-temporal/#sec-Intl.DateTimeFormat.prototype.formatToParts +JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format_to_parts) +{ + auto& realm = *vm.current_realm(); + + auto date_value = vm.argument(0); + + // 1. Let dtf be the this value. + // 2. Perform ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]]). + auto date_time_format = TRY(typed_this_object(vm)); + + FormattableDateTime date { 0 }; + + // 3. If date is undefined, then + if (date_value.is_undefined()) { + // a. Let x be ! Call(%Date.now%, undefined). + date = MUST(call(vm, *realm.intrinsics().date_constructor_now_function(), js_undefined())).as_double(); + } + // 4. Else, + else { + // a. Let x be ? ToDateTimeFormattable(date). + date = TRY(to_date_time_formattable(vm, date_value)); + } + + // 5. Return ? FormatDateTimeToParts(dtf, x). + return TRY(format_date_time_to_parts(vm, date_time_format, date)); +} + } diff --git a/Libraries/LibJS/Runtime/Intl/DateTimeFormatPrototype.h b/Libraries/LibJS/Runtime/Intl/DateTimeFormatPrototype.h index 9dd070c9b47..bd302f79d9b 100644 --- a/Libraries/LibJS/Runtime/Intl/DateTimeFormatPrototype.h +++ b/Libraries/LibJS/Runtime/Intl/DateTimeFormatPrototype.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Tim Flynn + * Copyright (c) 2021-2025, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -22,11 +22,11 @@ public: private: explicit DateTimeFormatPrototype(Realm&); + JS_DECLARE_NATIVE_FUNCTION(resolved_options); JS_DECLARE_NATIVE_FUNCTION(format); - JS_DECLARE_NATIVE_FUNCTION(format_to_parts); JS_DECLARE_NATIVE_FUNCTION(format_range); JS_DECLARE_NATIVE_FUNCTION(format_range_to_parts); - JS_DECLARE_NATIVE_FUNCTION(resolved_options); + JS_DECLARE_NATIVE_FUNCTION(format_to_parts); }; } diff --git a/Libraries/LibJS/Runtime/Intl/DisplayNamesPrototype.cpp b/Libraries/LibJS/Runtime/Intl/DisplayNamesPrototype.cpp index 0e933589a81..dcbb701ca87 100644 --- a/Libraries/LibJS/Runtime/Intl/DisplayNamesPrototype.cpp +++ b/Libraries/LibJS/Runtime/Intl/DisplayNamesPrototype.cpp @@ -27,12 +27,42 @@ void DisplayNamesPrototype::initialize(Realm& realm) auto& vm = this->vm(); - // 12.3.2 Intl.DisplayNames.prototype[ @@toStringTag ], https://tc39.es/ecma402/#sec-Intl.DisplayNames.prototype-@@tostringtag + // 12.3.4 Intl.DisplayNames.prototype [ %Symbol.toStringTag% ], https://tc39.es/ecma402/#sec-intl.displaynames.prototype-%symbol.tostringtag% define_direct_property(vm.well_known_symbol_to_string_tag(), PrimitiveString::create(vm, "Intl.DisplayNames"_string), Attribute::Configurable); u8 attr = Attribute::Writable | Attribute::Configurable; - define_native_function(realm, vm.names.of, of, 1, attr); define_native_function(realm, vm.names.resolvedOptions, resolved_options, 0, attr); + define_native_function(realm, vm.names.of, of, 1, attr); +} + +// 12.3.2 Intl.DisplayNames.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-Intl.DisplayNames.prototype.resolvedOptions +JS_DEFINE_NATIVE_FUNCTION(DisplayNamesPrototype::resolved_options) +{ + auto& realm = *vm.current_realm(); + + // 1. Let displayNames be this value. + // 2. Perform ? RequireInternalSlot(displayNames, [[InitializedDisplayNames]]). + auto display_names = TRY(typed_this_object(vm)); + + // 3. Let options be OrdinaryObjectCreate(%Object.prototype%). + auto options = Object::create(realm, realm.intrinsics().object_prototype()); + + // 4. For each row of Table 18, except the header row, in table order, do + // a. Let p be the Property value of the current row. + // b. Let v be the value of displayNames's internal slot whose name is the Internal Slot value of the current row. + // c. Assert: v is not undefined. + // d. Perform ! CreateDataPropertyOrThrow(options, p, v). + MUST(options->create_data_property_or_throw(vm.names.locale, PrimitiveString::create(vm, display_names->locale()))); + MUST(options->create_data_property_or_throw(vm.names.style, PrimitiveString::create(vm, display_names->style_string()))); + MUST(options->create_data_property_or_throw(vm.names.type, PrimitiveString::create(vm, display_names->type_string()))); + MUST(options->create_data_property_or_throw(vm.names.fallback, PrimitiveString::create(vm, display_names->fallback_string()))); + + // NOTE: Step 4c indicates languageDisplay must not be undefined, but it is only set when the type option is language. + if (display_names->has_language_display()) + MUST(options->create_data_property_or_throw(vm.names.languageDisplay, PrimitiveString::create(vm, display_names->language_display_string()))); + + // 5. Return options. + return options; } // 12.3.3 Intl.DisplayNames.prototype.of ( code ), https://tc39.es/ecma402/#sec-Intl.DisplayNames.prototype.of @@ -89,34 +119,4 @@ JS_DEFINE_NATIVE_FUNCTION(DisplayNamesPrototype::of) return js_undefined(); } -// 12.3.4 Intl.DisplayNames.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-Intl.DisplayNames.prototype.resolvedOptions -JS_DEFINE_NATIVE_FUNCTION(DisplayNamesPrototype::resolved_options) -{ - auto& realm = *vm.current_realm(); - - // 1. Let displayNames be this value. - // 2. Perform ? RequireInternalSlot(displayNames, [[InitializedDisplayNames]]). - auto display_names = TRY(typed_this_object(vm)); - - // 3. Let options be OrdinaryObjectCreate(%Object.prototype%). - auto options = Object::create(realm, realm.intrinsics().object_prototype()); - - // 4. For each row of Table 18, except the header row, in table order, do - // a. Let p be the Property value of the current row. - // b. Let v be the value of displayNames's internal slot whose name is the Internal Slot value of the current row. - // c. Assert: v is not undefined. - // d. Perform ! CreateDataPropertyOrThrow(options, p, v). - MUST(options->create_data_property_or_throw(vm.names.locale, PrimitiveString::create(vm, display_names->locale()))); - MUST(options->create_data_property_or_throw(vm.names.style, PrimitiveString::create(vm, display_names->style_string()))); - MUST(options->create_data_property_or_throw(vm.names.type, PrimitiveString::create(vm, display_names->type_string()))); - MUST(options->create_data_property_or_throw(vm.names.fallback, PrimitiveString::create(vm, display_names->fallback_string()))); - - // NOTE: Step 4c indicates languageDisplay must not be undefined, but it is only set when the type option is language. - if (display_names->has_language_display()) - MUST(options->create_data_property_or_throw(vm.names.languageDisplay, PrimitiveString::create(vm, display_names->language_display_string()))); - - // 5. Return options. - return options; -} - } diff --git a/Libraries/LibJS/Runtime/Intl/DisplayNamesPrototype.h b/Libraries/LibJS/Runtime/Intl/DisplayNamesPrototype.h index 8d1705b9a70..54a63e7956b 100644 --- a/Libraries/LibJS/Runtime/Intl/DisplayNamesPrototype.h +++ b/Libraries/LibJS/Runtime/Intl/DisplayNamesPrototype.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Tim Flynn + * Copyright (c) 2021-2025, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -22,8 +22,8 @@ public: private: explicit DisplayNamesPrototype(Realm&); - JS_DECLARE_NATIVE_FUNCTION(of); JS_DECLARE_NATIVE_FUNCTION(resolved_options); + JS_DECLARE_NATIVE_FUNCTION(of); }; } diff --git a/Libraries/LibJS/Runtime/Intl/ListFormatPrototype.cpp b/Libraries/LibJS/Runtime/Intl/ListFormatPrototype.cpp index 5d3f6760058..9f5c8360043 100644 --- a/Libraries/LibJS/Runtime/Intl/ListFormatPrototype.cpp +++ b/Libraries/LibJS/Runtime/Intl/ListFormatPrototype.cpp @@ -26,13 +26,38 @@ void ListFormatPrototype::initialize(Realm& realm) auto& vm = this->vm(); - // 14.3.2 Intl.ListFormat.prototype [ @@toStringTag ], https://tc39.es/ecma402/#sec-Intl.ListFormat.prototype-toStringTag + // 14.3.5 Intl.ListFormat.prototype [ %Symbol.toStringTag% ], https://tc39.es/ecma402/#sec-Intl.ListFormat.prototype-toStringTag define_direct_property(vm.well_known_symbol_to_string_tag(), PrimitiveString::create(vm, "Intl.ListFormat"_string), Attribute::Configurable); u8 attr = Attribute::Writable | Attribute::Configurable; + define_native_function(realm, vm.names.resolvedOptions, resolved_options, 0, attr); define_native_function(realm, vm.names.format, format, 1, attr); define_native_function(realm, vm.names.formatToParts, format_to_parts, 1, attr); - define_native_function(realm, vm.names.resolvedOptions, resolved_options, 0, attr); +} + +// 14.3.2 Intl.ListFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-Intl.ListFormat.prototype.resolvedoptions +JS_DEFINE_NATIVE_FUNCTION(ListFormatPrototype::resolved_options) +{ + auto& realm = *vm.current_realm(); + + // 1. Let lf be the this value. + // 2. Perform ? RequireInternalSlot(lf, [[InitializedListFormat]]). + auto list_format = TRY(typed_this_object(vm)); + + // 3. Let options be OrdinaryObjectCreate(%Object.prototype%). + auto options = Object::create(realm, realm.intrinsics().object_prototype()); + + // 4. For each row of Table 24, except the header row, in table order, do + // a. Let p be the Property value of the current row. + // b. Let v be the value of lf's internal slot whose name is the Internal Slot value of the current row. + // c. Assert: v is not undefined. + // d. Perform ! CreateDataPropertyOrThrow(options, p, v). + MUST(options->create_data_property_or_throw(vm.names.locale, PrimitiveString::create(vm, list_format->locale()))); + MUST(options->create_data_property_or_throw(vm.names.type, PrimitiveString::create(vm, list_format->type_string()))); + MUST(options->create_data_property_or_throw(vm.names.style, PrimitiveString::create(vm, list_format->style_string()))); + + // 5. Return options. + return options; } // 14.3.3 Intl.ListFormat.prototype.format ( list ), https://tc39.es/ecma402/#sec-Intl.ListFormat.prototype.format @@ -68,29 +93,4 @@ JS_DEFINE_NATIVE_FUNCTION(ListFormatPrototype::format_to_parts) return format_list_to_parts(vm, list_format, string_list); } -// 14.3.5 Intl.ListFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-Intl.ListFormat.prototype.resolvedoptions -JS_DEFINE_NATIVE_FUNCTION(ListFormatPrototype::resolved_options) -{ - auto& realm = *vm.current_realm(); - - // 1. Let lf be the this value. - // 2. Perform ? RequireInternalSlot(lf, [[InitializedListFormat]]). - auto list_format = TRY(typed_this_object(vm)); - - // 3. Let options be OrdinaryObjectCreate(%Object.prototype%). - auto options = Object::create(realm, realm.intrinsics().object_prototype()); - - // 4. For each row of Table 24, except the header row, in table order, do - // a. Let p be the Property value of the current row. - // b. Let v be the value of lf's internal slot whose name is the Internal Slot value of the current row. - // c. Assert: v is not undefined. - // d. Perform ! CreateDataPropertyOrThrow(options, p, v). - MUST(options->create_data_property_or_throw(vm.names.locale, PrimitiveString::create(vm, list_format->locale()))); - MUST(options->create_data_property_or_throw(vm.names.type, PrimitiveString::create(vm, list_format->type_string()))); - MUST(options->create_data_property_or_throw(vm.names.style, PrimitiveString::create(vm, list_format->style_string()))); - - // 5. Return options. - return options; -} - } diff --git a/Libraries/LibJS/Runtime/Intl/ListFormatPrototype.h b/Libraries/LibJS/Runtime/Intl/ListFormatPrototype.h index 311bcfaf17f..97fd29e3f82 100644 --- a/Libraries/LibJS/Runtime/Intl/ListFormatPrototype.h +++ b/Libraries/LibJS/Runtime/Intl/ListFormatPrototype.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Tim Flynn + * Copyright (c) 2021-2025, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -22,9 +22,9 @@ public: private: explicit ListFormatPrototype(Realm&); + JS_DECLARE_NATIVE_FUNCTION(resolved_options); JS_DECLARE_NATIVE_FUNCTION(format); JS_DECLARE_NATIVE_FUNCTION(format_to_parts); - JS_DECLARE_NATIVE_FUNCTION(resolved_options); }; } diff --git a/Libraries/LibJS/Runtime/Intl/LocalePrototype.cpp b/Libraries/LibJS/Runtime/Intl/LocalePrototype.cpp index c743f5fd1d0..701f510d33a 100644 --- a/Libraries/LibJS/Runtime/Intl/LocalePrototype.cpp +++ b/Libraries/LibJS/Runtime/Intl/LocalePrototype.cpp @@ -39,7 +39,7 @@ void LocalePrototype::initialize(Realm& realm) define_native_function(realm, vm.names.getTextInfo, get_text_info, 0, attr); define_native_function(realm, vm.names.getWeekInfo, get_week_info, 0, attr); - // 15.3.2 Intl.Locale.prototype[ @@toStringTag ], https://tc39.es/ecma402/#sec-Intl.Locale.prototype-@@tostringtag + // 15.3.15 Intl.Locale.prototype [ %Symbol.toStringTag% ], https://tc39.es/ecma402/#sec-intl.locale.prototype-%symbol.tostringtag% define_direct_property(vm.well_known_symbol_to_string_tag(), PrimitiveString::create(vm, "Intl.Locale"_string), Attribute::Configurable); define_native_accessor(realm, vm.names.baseName, base_name, {}, Attribute::Configurable); @@ -48,57 +48,14 @@ void LocalePrototype::initialize(Realm& realm) define_native_accessor(realm, vm.names.collation, collation, {}, Attribute::Configurable); define_native_accessor(realm, vm.names.firstDayOfWeek, first_day_of_week, {}, Attribute::Configurable); define_native_accessor(realm, vm.names.hourCycle, hour_cycle, {}, Attribute::Configurable); + define_native_accessor(realm, vm.names.language, language, {}, Attribute::Configurable); define_native_accessor(realm, vm.names.numberingSystem, numbering_system, {}, Attribute::Configurable); define_native_accessor(realm, vm.names.numeric, numeric, {}, Attribute::Configurable); - define_native_accessor(realm, vm.names.language, language, {}, Attribute::Configurable); - define_native_accessor(realm, vm.names.script, script, {}, Attribute::Configurable); define_native_accessor(realm, vm.names.region, region, {}, Attribute::Configurable); + define_native_accessor(realm, vm.names.script, script, {}, Attribute::Configurable); } -// 15.3.3 Intl.Locale.prototype.maximize ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.maximize -JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::maximize) -{ - auto& realm = *vm.current_realm(); - - // 1. Let loc be the this value. - // 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]). - auto locale_object = TRY(typed_this_object(vm)); - - // 3. Let maximal be the result of the Add Likely Subtags algorithm applied to loc.[[Locale]]. If an error is signaled, set maximal to loc.[[Locale]]. - auto maximal = Unicode::add_likely_subtags(locale_object->locale()).value_or(locale_object->locale()); - - // 4. Return ! Construct(%Locale%, maximal). - return Locale::create(realm, locale_object, move(maximal)); -} - -// 15.3.4 Intl.Locale.prototype.minimize ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.minimize -JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::minimize) -{ - auto& realm = *vm.current_realm(); - - // 1. Let loc be the this value. - // 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]). - auto locale_object = TRY(typed_this_object(vm)); - - // 3. Let minimal be the result of the Remove Likely Subtags algorithm applied to loc.[[Locale]]. If an error is signaled, set minimal to loc.[[Locale]]. - auto minimal = Unicode::remove_likely_subtags(locale_object->locale()).value_or(locale_object->locale()); - - // 4. Return ! Construct(%Locale%, minimal). - return Locale::create(realm, locale_object, move(minimal)); -} - -// 15.3.5 Intl.Locale.prototype.toString ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.toString -JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::to_string) -{ - // 1. Let loc be the this value. - // 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]). - auto locale_object = TRY(typed_this_object(vm)); - - // 3. Return loc.[[Locale]]. - return PrimitiveString::create(vm, locale_object->locale()); -} - -// 15.3.6 get Intl.Locale.prototype.baseName, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.baseName +// 15.3.2 get Intl.Locale.prototype.baseName, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.baseName JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::base_name) { // 1. Let loc be the this value. @@ -121,12 +78,12 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::base_name) __JS_ENUMERATE(hour_cycle) \ __JS_ENUMERATE(numbering_system) -// 15.3.7 get Intl.Locale.prototype.calendar, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.calendar -// 15.3.8 get Intl.Locale.prototype.caseFirst, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.caseFirst -// 15.3.9 get Intl.Locale.prototype.collation, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.collation +// 15.3.3 get Intl.Locale.prototype.calendar, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.calendar +// 15.3.4 get Intl.Locale.prototype.caseFirst, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.caseFirst +// 15.3.5 get Intl.Locale.prototype.collation, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.collation // 1.4.10 get Intl.Locale.prototype.firstDayOfWeek, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.firstDayOfWeek -// 15.3.10 get Intl.Locale.prototype.hourCycle, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.hourCycle -// 15.3.12 get Intl.Locale.prototype.numberingSystem, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.numberingSystem +// 15.3.6 get Intl.Locale.prototype.hourCycle, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.hourCycle +// 15.3.10 get Intl.Locale.prototype.numberingSystem, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.numberingSystem #define __JS_ENUMERATE(keyword) \ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::keyword) \ { \ @@ -138,18 +95,7 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::base_name) JS_ENUMERATE_LOCALE_KEYWORD_PROPERTIES #undef __JS_ENUMERATE -// 15.3.11 get Intl.Locale.prototype.numeric, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.numeric -JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::numeric) -{ - // 1. Let loc be the this value. - // 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]). - auto locale_object = TRY(typed_this_object(vm)); - - // 3. Return loc.[[Numeric]]. - return Value(locale_object->numeric()); -} - -// 15.3.13 get Intl.Locale.prototype.language, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.language +// 15.3.7 get Intl.Locale.prototype.language, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.language JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::language) { // 1. Let loc be the this value. @@ -166,7 +112,71 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::language) return PrimitiveString::create(vm, locale->language_id.language.release_value()); } -// 15.3.14 get Intl.Locale.prototype.script, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.script +// 15.3.8 Intl.Locale.prototype.maximize ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.maximize +JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::maximize) +{ + auto& realm = *vm.current_realm(); + + // 1. Let loc be the this value. + // 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]). + auto locale_object = TRY(typed_this_object(vm)); + + // 3. Let maximal be the result of the Add Likely Subtags algorithm applied to loc.[[Locale]]. If an error is signaled, set maximal to loc.[[Locale]]. + auto maximal = Unicode::add_likely_subtags(locale_object->locale()).value_or(locale_object->locale()); + + // 4. Return ! Construct(%Locale%, maximal). + return Locale::create(realm, locale_object, move(maximal)); +} + +// 15.3.9 Intl.Locale.prototype.minimize ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.minimize +JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::minimize) +{ + auto& realm = *vm.current_realm(); + + // 1. Let loc be the this value. + // 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]). + auto locale_object = TRY(typed_this_object(vm)); + + // 3. Let minimal be the result of the Remove Likely Subtags algorithm applied to loc.[[Locale]]. If an error is signaled, set minimal to loc.[[Locale]]. + auto minimal = Unicode::remove_likely_subtags(locale_object->locale()).value_or(locale_object->locale()); + + // 4. Return ! Construct(%Locale%, minimal). + return Locale::create(realm, locale_object, move(minimal)); +} + +// 15.3.11 get Intl.Locale.prototype.numeric, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.numeric +JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::numeric) +{ + // 1. Let loc be the this value. + // 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]). + auto locale_object = TRY(typed_this_object(vm)); + + // 3. Return loc.[[Numeric]]. + return Value(locale_object->numeric()); +} + +// 15.3.12 get Intl.Locale.prototype.region, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.region +JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::region) +{ + // 1. Let loc be the this value. + // 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]). + auto locale_object = TRY(typed_this_object(vm)); + + // 3. Let locale be loc.[[Locale]]. + auto locale = Unicode::parse_unicode_locale_id(locale_object->locale()); + + // 4. Assert: locale matches the unicode_locale_id production. + VERIFY(locale.has_value()); + + // 5. If the unicode_language_id production of locale does not contain the ["-" unicode_region_subtag] sequence, return undefined. + if (!locale->language_id.region.has_value()) + return js_undefined(); + + // 6. Return the substring of locale corresponding to the unicode_region_subtag production of the unicode_language_id. + return PrimitiveString::create(vm, locale->language_id.region.release_value()); +} + +// 15.3.13 get Intl.Locale.prototype.script, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.script JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::script) { // 1. Let loc be the this value. @@ -187,25 +197,15 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::script) return PrimitiveString::create(vm, locale->language_id.script.release_value()); } -// 15.3.15 get Intl.Locale.prototype.region, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.region -JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::region) +// 15.3.14 Intl.Locale.prototype.toString ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.toString +JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::to_string) { // 1. Let loc be the this value. // 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]). auto locale_object = TRY(typed_this_object(vm)); - // 3. Let locale be loc.[[Locale]]. - auto locale = Unicode::parse_unicode_locale_id(locale_object->locale()); - - // 4. Assert: locale matches the unicode_locale_id production. - VERIFY(locale.has_value()); - - // 5. If the unicode_language_id production of locale does not contain the ["-" unicode_region_subtag] sequence, return undefined. - if (!locale->language_id.region.has_value()) - return js_undefined(); - - // 6. Return the substring of locale corresponding to the unicode_region_subtag production of the unicode_language_id. - return PrimitiveString::create(vm, locale->language_id.region.release_value()); + // 3. Return loc.[[Locale]]. + return PrimitiveString::create(vm, locale_object->locale()); } #define JS_ENUMERATE_LOCALE_INFO_PROPERTIES \ diff --git a/Libraries/LibJS/Runtime/Intl/LocalePrototype.h b/Libraries/LibJS/Runtime/Intl/LocalePrototype.h index 790e28b62b4..4b21c663dc8 100644 --- a/Libraries/LibJS/Runtime/Intl/LocalePrototype.h +++ b/Libraries/LibJS/Runtime/Intl/LocalePrototype.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, Tim Flynn + * Copyright (c) 2021-2025, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -32,11 +32,11 @@ private: JS_DECLARE_NATIVE_FUNCTION(collation); JS_DECLARE_NATIVE_FUNCTION(first_day_of_week); JS_DECLARE_NATIVE_FUNCTION(hour_cycle); + JS_DECLARE_NATIVE_FUNCTION(language); JS_DECLARE_NATIVE_FUNCTION(numbering_system); JS_DECLARE_NATIVE_FUNCTION(numeric); - JS_DECLARE_NATIVE_FUNCTION(language); - JS_DECLARE_NATIVE_FUNCTION(script); JS_DECLARE_NATIVE_FUNCTION(region); + JS_DECLARE_NATIVE_FUNCTION(script); JS_DECLARE_NATIVE_FUNCTION(get_calendars); JS_DECLARE_NATIVE_FUNCTION(get_collations); JS_DECLARE_NATIVE_FUNCTION(get_hour_cycles); diff --git a/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.cpp b/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.cpp index 29f10418ed7..2d870783831 100644 --- a/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.cpp +++ b/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.cpp @@ -27,113 +27,19 @@ void NumberFormatPrototype::initialize(Realm& realm) auto& vm = this->vm(); - // 16.3.2 Intl.NumberFormat.prototype [ @@toStringTag ], https://tc39.es/ecma402/#sec-intl.numberformat.prototype-@@tostringtag + // 16.3.7 Intl.NumberFormat.prototype [ %Symbol.toStringTag% ], https://tc39.es/ecma402/#sec-intl.numberformat.prototype-%symbol.tostringtag% define_direct_property(vm.well_known_symbol_to_string_tag(), PrimitiveString::create(vm, "Intl.NumberFormat"_string), Attribute::Configurable); define_native_accessor(realm, vm.names.format, format, nullptr, Attribute::Configurable); u8 attr = Attribute::Writable | Attribute::Configurable; - define_native_function(realm, vm.names.formatToParts, format_to_parts, 1, attr); + define_native_function(realm, vm.names.resolvedOptions, resolved_options, 0, attr); define_native_function(realm, vm.names.formatRange, format_range, 2, attr); define_native_function(realm, vm.names.formatRangeToParts, format_range_to_parts, 2, attr); - define_native_function(realm, vm.names.resolvedOptions, resolved_options, 0, attr); + define_native_function(realm, vm.names.formatToParts, format_to_parts, 1, attr); } -// 16.3.3 get Intl.NumberFormat.prototype.format, https://tc39.es/ecma402/#sec-intl.numberformat.prototype.format -JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format) -{ - auto& realm = *vm.current_realm(); - - // 1. Let nf be the this value. - // 2. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then - // a. Set nf to ? UnwrapNumberFormat(nf). - // 3. Perform ? RequireInternalSlot(nf, [[InitializedNumberFormat]]). - auto number_format = TRY(typed_this_object(vm)); - - // 4. If nf.[[BoundFormat]] is undefined, then - if (!number_format->bound_format()) { - // a. Let F be a new built-in function object as defined in Number Format Functions (16.1.4). - // b. Set F.[[NumberFormat]] to nf. - auto bound_format = NumberFormatFunction::create(realm, number_format); - - // c. Set nf.[[BoundFormat]] to F. - number_format->set_bound_format(bound_format); - } - - // 5. Return nf.[[BoundFormat]]. - return number_format->bound_format(); -} - -// 16.3.4 Intl.NumberFormat.prototype.formatToParts ( value ), https://tc39.es/ecma402/#sec-intl.numberformat.prototype.formattoparts -JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_to_parts) -{ - auto value = vm.argument(0); - - // 1. Let nf be the this value. - // 2. Perform ? RequireInternalSlot(nf, [[InitializedNumberFormat]]). - auto number_format = TRY(typed_this_object(vm)); - - // 3. Let x be ? ToIntlMathematicalValue(value). - auto mathematical_value = TRY(to_intl_mathematical_value(vm, value)); - - // 4. Return ? FormatNumericToParts(nf, x). - return format_numeric_to_parts(vm, number_format, move(mathematical_value)); -} - -// 16.3.5 Intl.NumberFormat.prototype.formatRange ( start, end ), https://tc39.es/ecma402/#sec-intl.numberformat.prototype.formatrange -JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_range) -{ - auto start = vm.argument(0); - auto end = vm.argument(1); - - // 1. Let nf be the this value. - // 2. Perform ? RequireInternalSlot(nf, [[InitializedNumberFormat]]). - auto number_format = TRY(typed_this_object(vm)); - - // 3. If start is undefined or end is undefined, throw a TypeError exception. - if (start.is_undefined()) - return vm.throw_completion(ErrorType::IsUndefined, "start"sv); - if (end.is_undefined()) - return vm.throw_completion(ErrorType::IsUndefined, "end"sv); - - // 4. Let x be ? ToIntlMathematicalValue(start). - auto x = TRY(to_intl_mathematical_value(vm, start)); - - // 5. Let y be ? ToIntlMathematicalValue(end). - auto y = TRY(to_intl_mathematical_value(vm, end)); - - // 6. Return ? FormatNumericRange(nf, x, y). - auto formatted = TRY(format_numeric_range(vm, number_format, move(x), move(y))); - return PrimitiveString::create(vm, move(formatted)); -} - -// 16.3.6 Intl.NumberFormat.prototype.formatRangeToParts ( start, end ), https://tc39.es/ecma402/#sec-intl.numberformat.prototype.formatrangetoparts -JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_range_to_parts) -{ - auto start = vm.argument(0); - auto end = vm.argument(1); - - // 1. Let nf be the this value. - // 2. Perform ? RequireInternalSlot(nf, [[InitializedNumberFormat]]). - auto number_format = TRY(typed_this_object(vm)); - - // 3. If start is undefined or end is undefined, throw a TypeError exception. - if (start.is_undefined()) - return vm.throw_completion(ErrorType::IsUndefined, "start"sv); - if (end.is_undefined()) - return vm.throw_completion(ErrorType::IsUndefined, "end"sv); - - // 4. Let x be ? ToIntlMathematicalValue(start). - auto x = TRY(to_intl_mathematical_value(vm, start)); - - // 5. Let y be ? ToIntlMathematicalValue(end). - auto y = TRY(to_intl_mathematical_value(vm, end)); - - // 6. Return ? FormatNumericRangeToParts(nf, x, y). - return TRY(format_numeric_range_to_parts(vm, number_format, move(x), move(y))); -} - -// 16.3.7 Intl.NumberFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.numberformat.prototype.resolvedoptions +// 16.3.2 Intl.NumberFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.numberformat.prototype.resolvedoptions JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::resolved_options) { auto& realm = *vm.current_realm(); @@ -188,4 +94,98 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::resolved_options) return options; } +// 16.3.3 get Intl.NumberFormat.prototype.format, https://tc39.es/ecma402/#sec-intl.numberformat.prototype.format +JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format) +{ + auto& realm = *vm.current_realm(); + + // 1. Let nf be the this value. + // 2. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then + // a. Set nf to ? UnwrapNumberFormat(nf). + // 3. Perform ? RequireInternalSlot(nf, [[InitializedNumberFormat]]). + auto number_format = TRY(typed_this_object(vm)); + + // 4. If nf.[[BoundFormat]] is undefined, then + if (!number_format->bound_format()) { + // a. Let F be a new built-in function object as defined in Number Format Functions (16.1.4). + // b. Set F.[[NumberFormat]] to nf. + auto bound_format = NumberFormatFunction::create(realm, number_format); + + // c. Set nf.[[BoundFormat]] to F. + number_format->set_bound_format(bound_format); + } + + // 5. Return nf.[[BoundFormat]]. + return number_format->bound_format(); +} + +// 16.3.4 Intl.NumberFormat.prototype.formatRange ( start, end ), https://tc39.es/ecma402/#sec-intl.numberformat.prototype.formatrange +JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_range) +{ + auto start = vm.argument(0); + auto end = vm.argument(1); + + // 1. Let nf be the this value. + // 2. Perform ? RequireInternalSlot(nf, [[InitializedNumberFormat]]). + auto number_format = TRY(typed_this_object(vm)); + + // 3. If start is undefined or end is undefined, throw a TypeError exception. + if (start.is_undefined()) + return vm.throw_completion(ErrorType::IsUndefined, "start"sv); + if (end.is_undefined()) + return vm.throw_completion(ErrorType::IsUndefined, "end"sv); + + // 4. Let x be ? ToIntlMathematicalValue(start). + auto x = TRY(to_intl_mathematical_value(vm, start)); + + // 5. Let y be ? ToIntlMathematicalValue(end). + auto y = TRY(to_intl_mathematical_value(vm, end)); + + // 6. Return ? FormatNumericRange(nf, x, y). + auto formatted = TRY(format_numeric_range(vm, number_format, move(x), move(y))); + return PrimitiveString::create(vm, move(formatted)); +} + +// 16.3.5 Intl.NumberFormat.prototype.formatRangeToParts ( start, end ), https://tc39.es/ecma402/#sec-intl.numberformat.prototype.formatrangetoparts +JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_range_to_parts) +{ + auto start = vm.argument(0); + auto end = vm.argument(1); + + // 1. Let nf be the this value. + // 2. Perform ? RequireInternalSlot(nf, [[InitializedNumberFormat]]). + auto number_format = TRY(typed_this_object(vm)); + + // 3. If start is undefined or end is undefined, throw a TypeError exception. + if (start.is_undefined()) + return vm.throw_completion(ErrorType::IsUndefined, "start"sv); + if (end.is_undefined()) + return vm.throw_completion(ErrorType::IsUndefined, "end"sv); + + // 4. Let x be ? ToIntlMathematicalValue(start). + auto x = TRY(to_intl_mathematical_value(vm, start)); + + // 5. Let y be ? ToIntlMathematicalValue(end). + auto y = TRY(to_intl_mathematical_value(vm, end)); + + // 6. Return ? FormatNumericRangeToParts(nf, x, y). + return TRY(format_numeric_range_to_parts(vm, number_format, move(x), move(y))); +} + +// 16.3.6 Intl.NumberFormat.prototype.formatToParts ( value ), https://tc39.es/ecma402/#sec-intl.numberformat.prototype.formattoparts +JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_to_parts) +{ + auto value = vm.argument(0); + + // 1. Let nf be the this value. + // 2. Perform ? RequireInternalSlot(nf, [[InitializedNumberFormat]]). + auto number_format = TRY(typed_this_object(vm)); + + // 3. Let x be ? ToIntlMathematicalValue(value). + auto mathematical_value = TRY(to_intl_mathematical_value(vm, value)); + + // 4. Return ? FormatNumericToParts(nf, x). + return format_numeric_to_parts(vm, number_format, move(mathematical_value)); +} + } diff --git a/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.h b/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.h index db56050b10d..4978f94b88b 100644 --- a/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.h +++ b/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Tim Flynn + * Copyright (c) 2021-2025, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -22,11 +22,11 @@ public: private: explicit NumberFormatPrototype(Realm&); + JS_DECLARE_NATIVE_FUNCTION(resolved_options); JS_DECLARE_NATIVE_FUNCTION(format); - JS_DECLARE_NATIVE_FUNCTION(format_to_parts); JS_DECLARE_NATIVE_FUNCTION(format_range); JS_DECLARE_NATIVE_FUNCTION(format_range_to_parts); - JS_DECLARE_NATIVE_FUNCTION(resolved_options); + JS_DECLARE_NATIVE_FUNCTION(format_to_parts); }; } diff --git a/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.cpp b/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.cpp index ff821d05032..d72232d42a1 100644 --- a/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.cpp +++ b/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.cpp @@ -27,58 +27,16 @@ void PluralRulesPrototype::initialize(Realm& realm) auto& vm = this->vm(); - // 17.3.2 Intl.PluralRules.prototype [ @@toStringTag ], https://tc39.es/ecma402/#sec-intl.pluralrules.prototype-tostringtag + // 17.3.5 Intl.PluralRules.prototype [ %Symbol.toStringTag% ], https://tc39.es/ecma402/#sec-intl.pluralrules.prototype-%symbol.tostringtag% define_direct_property(vm.well_known_symbol_to_string_tag(), PrimitiveString::create(vm, "Intl.PluralRules"_string), Attribute::Configurable); u8 attr = Attribute::Writable | Attribute::Configurable; + define_native_function(realm, vm.names.resolvedOptions, resolved_options, 0, attr); define_native_function(realm, vm.names.select, select, 1, attr); define_native_function(realm, vm.names.selectRange, select_range, 2, attr); - define_native_function(realm, vm.names.resolvedOptions, resolved_options, 0, attr); } -// 17.3.3 Intl.PluralRules.prototype.select ( value ), https://tc39.es/ecma402/#sec-intl.pluralrules.prototype.select -JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::select) -{ - // 1. Let pr be the this value. - // 2. Perform ? RequireInternalSlot(pr, [[InitializedPluralRules]]). - auto plural_rules = TRY(typed_this_object(vm)); - - // 3. Let n be ? ToNumber(value). - auto number = TRY(vm.argument(0).to_number(vm)); - - // 4. Return ! ResolvePlural(pr, n).[[PluralCategory]]. - auto plurality = resolve_plural(plural_rules, number); - return PrimitiveString::create(vm, Unicode::plural_category_to_string(plurality)); -} - -// 17.3.4 Intl.PluralRules.prototype.selectRange ( start, end ), https://tc39.es/ecma402/#sec-intl.pluralrules.prototype.selectrange -JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::select_range) -{ - auto start = vm.argument(0); - auto end = vm.argument(1); - - // 1. Let pr be the this value. - // 2. Perform ? RequireInternalSlot(pr, [[InitializedPluralRules]]). - auto plural_rules = TRY(typed_this_object(vm)); - - // 3. If start is undefined or end is undefined, throw a TypeError exception. - if (start.is_undefined()) - return vm.throw_completion(ErrorType::IsUndefined, "start"sv); - if (end.is_undefined()) - return vm.throw_completion(ErrorType::IsUndefined, "end"sv); - - // 4. Let x be ? ToNumber(start). - auto x = TRY(start.to_number(vm)); - - // 5. Let y be ? ToNumber(end). - auto y = TRY(end.to_number(vm)); - - // 6. Return ? ResolvePluralRange(pr, x, y). - auto plurality = TRY(resolve_plural_range(vm, plural_rules, x, y)); - return PrimitiveString::create(vm, Unicode::plural_category_to_string(plurality)); -} - -// 17.3.5 Intl.PluralRules.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.pluralrules.prototype.resolvedoptions +// 17.3.2 Intl.PluralRules.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.pluralrules.prototype.resolvedoptions JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::resolved_options) { auto& realm = *vm.current_realm(); @@ -127,4 +85,46 @@ JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::resolved_options) return options; } +// 17.3.3 Intl.PluralRules.prototype.select ( value ), https://tc39.es/ecma402/#sec-intl.pluralrules.prototype.select +JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::select) +{ + // 1. Let pr be the this value. + // 2. Perform ? RequireInternalSlot(pr, [[InitializedPluralRules]]). + auto plural_rules = TRY(typed_this_object(vm)); + + // 3. Let n be ? ToNumber(value). + auto number = TRY(vm.argument(0).to_number(vm)); + + // 4. Return ! ResolvePlural(pr, n).[[PluralCategory]]. + auto plurality = resolve_plural(plural_rules, number); + return PrimitiveString::create(vm, Unicode::plural_category_to_string(plurality)); +} + +// 17.3.4 Intl.PluralRules.prototype.selectRange ( start, end ), https://tc39.es/ecma402/#sec-intl.pluralrules.prototype.selectrange +JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::select_range) +{ + auto start = vm.argument(0); + auto end = vm.argument(1); + + // 1. Let pr be the this value. + // 2. Perform ? RequireInternalSlot(pr, [[InitializedPluralRules]]). + auto plural_rules = TRY(typed_this_object(vm)); + + // 3. If start is undefined or end is undefined, throw a TypeError exception. + if (start.is_undefined()) + return vm.throw_completion(ErrorType::IsUndefined, "start"sv); + if (end.is_undefined()) + return vm.throw_completion(ErrorType::IsUndefined, "end"sv); + + // 4. Let x be ? ToNumber(start). + auto x = TRY(start.to_number(vm)); + + // 5. Let y be ? ToNumber(end). + auto y = TRY(end.to_number(vm)); + + // 6. Return ? ResolvePluralRange(pr, x, y). + auto plurality = TRY(resolve_plural_range(vm, plural_rules, x, y)); + return PrimitiveString::create(vm, Unicode::plural_category_to_string(plurality)); +} + } diff --git a/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.h b/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.h index 66b5c09155d..4a69649b703 100644 --- a/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.h +++ b/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.h @@ -22,9 +22,9 @@ public: private: explicit PluralRulesPrototype(Realm&); + JS_DECLARE_NATIVE_FUNCTION(resolved_options); JS_DECLARE_NATIVE_FUNCTION(select); JS_DECLARE_NATIVE_FUNCTION(select_range); - JS_DECLARE_NATIVE_FUNCTION(resolved_options); }; } diff --git a/Libraries/LibJS/Runtime/Intl/RelativeTimeFormatPrototype.cpp b/Libraries/LibJS/Runtime/Intl/RelativeTimeFormatPrototype.cpp index f12a18e48f7..20f616dea94 100644 --- a/Libraries/LibJS/Runtime/Intl/RelativeTimeFormatPrototype.cpp +++ b/Libraries/LibJS/Runtime/Intl/RelativeTimeFormatPrototype.cpp @@ -25,13 +25,39 @@ void RelativeTimeFormatPrototype::initialize(Realm& realm) auto& vm = this->vm(); - // 18.3.2 Intl.RelativeTimeFormat.prototype[ @@toStringTag ], https://tc39.es/ecma402/#sec-Intl.RelativeTimeFormat.prototype-toStringTag + // 18.3.5 Intl.RelativeTimeFormat.prototype [ %Symbol.toStringTag% ], https://tc39.es/ecma402/#sec-Intl.RelativeTimeFormat.prototype-toStringTag define_direct_property(vm.well_known_symbol_to_string_tag(), PrimitiveString::create(vm, "Intl.RelativeTimeFormat"_string), Attribute::Configurable); u8 attr = Attribute::Writable | Attribute::Configurable; + define_native_function(realm, vm.names.resolvedOptions, resolved_options, 0, attr); define_native_function(realm, vm.names.format, format, 2, attr); define_native_function(realm, vm.names.formatToParts, format_to_parts, 2, attr); - define_native_function(realm, vm.names.resolvedOptions, resolved_options, 0, attr); +} + +// 18.3.2 Intl.RelativeTimeFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.relativetimeformat.prototype.resolvedoptions +JS_DEFINE_NATIVE_FUNCTION(RelativeTimeFormatPrototype::resolved_options) +{ + auto& realm = *vm.current_realm(); + + // 1. Let relativeTimeFormat be the this value. + // 2. Perform ? RequireInternalSlot(relativeTimeFormat, [[InitializedRelativeTimeFormat]]). + auto relative_time_format = TRY(typed_this_object(vm)); + + // 3. Let options be OrdinaryObjectCreate(%Object.prototype%). + auto options = Object::create(realm, realm.intrinsics().object_prototype()); + + // 4. For each row of Table 30, except the header row, in table order, do + // a. Let p be the Property value of the current row. + // b. Let v be the value of relativeTimeFormat's internal slot whose name is the Internal Slot value of the current row. + // c. Assert: v is not undefined. + // d. Perform ! CreateDataPropertyOrThrow(options, p, v). + MUST(options->create_data_property_or_throw(vm.names.locale, PrimitiveString::create(vm, relative_time_format->locale()))); + MUST(options->create_data_property_or_throw(vm.names.style, PrimitiveString::create(vm, relative_time_format->style_string()))); + MUST(options->create_data_property_or_throw(vm.names.numeric, PrimitiveString::create(vm, relative_time_format->numeric_string()))); + MUST(options->create_data_property_or_throw(vm.names.numberingSystem, PrimitiveString::create(vm, relative_time_format->numbering_system()))); + + // 5. Return options. + return options; } // 18.3.3 Intl.RelativeTimeFormat.prototype.format ( value, unit ), https://tc39.es/ecma402/#sec-Intl.RelativeTimeFormat.prototype.format @@ -69,30 +95,4 @@ JS_DEFINE_NATIVE_FUNCTION(RelativeTimeFormatPrototype::format_to_parts) return TRY(format_relative_time_to_parts(vm, relative_time_format, value.as_double(), unit.bytes_as_string_view())); } -// 18.3.5 Intl.RelativeTimeFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.relativetimeformat.prototype.resolvedoptions -JS_DEFINE_NATIVE_FUNCTION(RelativeTimeFormatPrototype::resolved_options) -{ - auto& realm = *vm.current_realm(); - - // 1. Let relativeTimeFormat be the this value. - // 2. Perform ? RequireInternalSlot(relativeTimeFormat, [[InitializedRelativeTimeFormat]]). - auto relative_time_format = TRY(typed_this_object(vm)); - - // 3. Let options be OrdinaryObjectCreate(%Object.prototype%). - auto options = Object::create(realm, realm.intrinsics().object_prototype()); - - // 4. For each row of Table 30, except the header row, in table order, do - // a. Let p be the Property value of the current row. - // b. Let v be the value of relativeTimeFormat's internal slot whose name is the Internal Slot value of the current row. - // c. Assert: v is not undefined. - // d. Perform ! CreateDataPropertyOrThrow(options, p, v). - MUST(options->create_data_property_or_throw(vm.names.locale, PrimitiveString::create(vm, relative_time_format->locale()))); - MUST(options->create_data_property_or_throw(vm.names.style, PrimitiveString::create(vm, relative_time_format->style_string()))); - MUST(options->create_data_property_or_throw(vm.names.numeric, PrimitiveString::create(vm, relative_time_format->numeric_string()))); - MUST(options->create_data_property_or_throw(vm.names.numberingSystem, PrimitiveString::create(vm, relative_time_format->numbering_system()))); - - // 5. Return options. - return options; -} - } diff --git a/Libraries/LibJS/Runtime/Intl/RelativeTimeFormatPrototype.h b/Libraries/LibJS/Runtime/Intl/RelativeTimeFormatPrototype.h index 1aa1c457de8..3e2ec49d852 100644 --- a/Libraries/LibJS/Runtime/Intl/RelativeTimeFormatPrototype.h +++ b/Libraries/LibJS/Runtime/Intl/RelativeTimeFormatPrototype.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Tim Flynn + * Copyright (c) 2022-2025, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -22,9 +22,9 @@ public: private: explicit RelativeTimeFormatPrototype(Realm&); + JS_DECLARE_NATIVE_FUNCTION(resolved_options); JS_DECLARE_NATIVE_FUNCTION(format); JS_DECLARE_NATIVE_FUNCTION(format_to_parts); - JS_DECLARE_NATIVE_FUNCTION(resolved_options); }; } diff --git a/Libraries/LibJS/Runtime/Intl/SegmentIterator.cpp b/Libraries/LibJS/Runtime/Intl/SegmentIterator.cpp index cfad1f5346e..ec77cb2d5d4 100644 --- a/Libraries/LibJS/Runtime/Intl/SegmentIterator.cpp +++ b/Libraries/LibJS/Runtime/Intl/SegmentIterator.cpp @@ -12,11 +12,11 @@ namespace JS::Intl { GC_DEFINE_ALLOCATOR(SegmentIterator); -// 19.6.1 CreateSegmentIterator ( segmenter, string ), https://tc39.es/ecma402/#sec-createsegmentsobject +// 19.6.1 CreateSegmentIterator ( segmenter, string ), https://tc39.es/ecma402/#sec-createsegmentiterator GC::Ref SegmentIterator::create(Realm& realm, Unicode::Segmenter const& segmenter, Utf16View const& string, Segments const& segments) { // 1. Let internalSlotsList be « [[IteratingSegmenter]], [[IteratedString]], [[IteratedStringNextSegmentCodeUnitIndex]] ». - // 2. Let iterator be OrdinaryObjectCreate(%SegmentIteratorPrototype%, internalSlotsList). + // 2. Let iterator be OrdinaryObjectCreate(%IntlSegmentIteratorPrototype%, internalSlotsList). // 3. Set iterator.[[IteratingSegmenter]] to segmenter. // 4. Set iterator.[[IteratedString]] to string. // 5. Set iterator.[[IteratedStringNextSegmentCodeUnitIndex]] to 0. diff --git a/Libraries/LibJS/Runtime/Intl/SegmentIteratorPrototype.cpp b/Libraries/LibJS/Runtime/Intl/SegmentIteratorPrototype.cpp index a4650d469b9..d4d356fc6fb 100644 --- a/Libraries/LibJS/Runtime/Intl/SegmentIteratorPrototype.cpp +++ b/Libraries/LibJS/Runtime/Intl/SegmentIteratorPrototype.cpp @@ -14,7 +14,7 @@ namespace JS::Intl { GC_DEFINE_ALLOCATOR(SegmentIteratorPrototype); -// 19.6.2 The %SegmentIteratorPrototype% Object, https://tc39.es/ecma402/#sec-%segmentiteratorprototype%-object +// 19.6.2 The %IntlSegmentIteratorPrototype% Object, https://tc39.es/ecma402/#sec-%intlsegmentiteratorprototype%-object SegmentIteratorPrototype::SegmentIteratorPrototype(Realm& realm) : PrototypeObject(realm.intrinsics().iterator_prototype()) { @@ -26,14 +26,14 @@ void SegmentIteratorPrototype::initialize(Realm& realm) auto& vm = this->vm(); - // 19.6.2.2 %SegmentIteratorPrototype% [ @@toStringTag ], https://tc39.es/ecma402/#sec-%segmentiteratorprototype%.@@tostringtag + // 19.6.2.2 %IntlSegmentIteratorPrototype% [ %Symbol.toStringTag% ], https://tc39.es/ecma402/#sec-%intlsegmentiteratorprototype%.%symbol.tostringtag% define_direct_property(vm.well_known_symbol_to_string_tag(), PrimitiveString::create(vm, "Segmenter String Iterator"_string), Attribute::Configurable); u8 attr = Attribute::Writable | Attribute::Configurable; define_native_function(realm, vm.names.next, next, 0, attr); } -// 19.6.2.1 %SegmentIteratorPrototype%.next ( ), https://tc39.es/ecma402/#sec-%segmentiteratorprototype%.next +// 19.6.2.1 %IntlSegmentIteratorPrototype%.next ( ), https://tc39.es/ecma402/#sec-%intlsegmentiteratorprototype%.next JS_DEFINE_NATIVE_FUNCTION(SegmentIteratorPrototype::next) { // 1. Let iterator be the this value. diff --git a/Libraries/LibJS/Runtime/Intl/SegmenterConstructor.cpp b/Libraries/LibJS/Runtime/Intl/SegmenterConstructor.cpp index a5279835ca4..8a68aaf973a 100644 --- a/Libraries/LibJS/Runtime/Intl/SegmenterConstructor.cpp +++ b/Libraries/LibJS/Runtime/Intl/SegmenterConstructor.cpp @@ -95,7 +95,7 @@ JS_DEFINE_NATIVE_FUNCTION(SegmenterConstructor::supported_locales_of) auto locales = vm.argument(0); auto options = vm.argument(1); - // 1. Let availableLocales be %Segmenter%.[[AvailableLocales]]. + // 1. Let availableLocales be %Intl.Segmenter%.[[AvailableLocales]]. // 2. Let requestedLocales be ? CanonicalizeLocaleList(locales). auto requested_locales = TRY(canonicalize_locale_list(vm, locales)); diff --git a/Libraries/LibJS/Runtime/Intl/SegmenterPrototype.cpp b/Libraries/LibJS/Runtime/Intl/SegmenterPrototype.cpp index 5eea5c83eba..79301a918ec 100644 --- a/Libraries/LibJS/Runtime/Intl/SegmenterPrototype.cpp +++ b/Libraries/LibJS/Runtime/Intl/SegmenterPrototype.cpp @@ -25,7 +25,7 @@ void SegmenterPrototype::initialize(Realm& realm) auto& vm = this->vm(); - // 19.3.2 Intl.Segmenter.prototype [ @@toStringTag ], https://tc39.es/ecma402/#sec-intl.segmenter.prototype-@@tostringtag + // 19.3.4 Intl.Segmenter.prototype [ %Symbol.toStringTag% ], https://tc39.es/ecma402/#sec-intl.segmenter.prototype-%symbol.tostringtag% define_direct_property(vm.well_known_symbol_to_string_tag(), PrimitiveString::create(vm, "Intl.Segmenter"_string), Attribute::Configurable); u8 attr = Attribute::Writable | Attribute::Configurable; @@ -33,7 +33,7 @@ void SegmenterPrototype::initialize(Realm& realm) define_native_function(realm, vm.names.segment, segment, 1, attr); } -// 19.3.4 Intl.Segmenter.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.segmenter.prototype.resolvedoptions +// 19.3.2 Intl.Segmenter.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.segmenter.prototype.resolvedoptions JS_DEFINE_NATIVE_FUNCTION(SegmenterPrototype::resolved_options) { auto& realm = *vm.current_realm(); diff --git a/Libraries/LibJS/Runtime/Intl/SegmenterPrototype.h b/Libraries/LibJS/Runtime/Intl/SegmenterPrototype.h index b5f62582121..58f9906f6cc 100644 --- a/Libraries/LibJS/Runtime/Intl/SegmenterPrototype.h +++ b/Libraries/LibJS/Runtime/Intl/SegmenterPrototype.h @@ -22,8 +22,8 @@ public: private: explicit SegmenterPrototype(Realm&); - JS_DECLARE_NATIVE_FUNCTION(segment); JS_DECLARE_NATIVE_FUNCTION(resolved_options); + JS_DECLARE_NATIVE_FUNCTION(segment); }; } diff --git a/Libraries/LibJS/Runtime/Intl/Segments.cpp b/Libraries/LibJS/Runtime/Intl/Segments.cpp index 0db35bff1c6..800da9905c6 100644 --- a/Libraries/LibJS/Runtime/Intl/Segments.cpp +++ b/Libraries/LibJS/Runtime/Intl/Segments.cpp @@ -16,7 +16,7 @@ GC_DEFINE_ALLOCATOR(Segments); GC::Ref Segments::create(Realm& realm, Unicode::Segmenter const& segmenter, Utf16String string) { // 1. Let internalSlotsList be « [[SegmentsSegmenter]], [[SegmentsString]] ». - // 2. Let segments be OrdinaryObjectCreate(%SegmentsPrototype%, internalSlotsList). + // 2. Let segments be OrdinaryObjectCreate(%IntlSegmentsPrototype%, internalSlotsList). // 3. Set segments.[[SegmentsSegmenter]] to segmenter. // 4. Set segments.[[SegmentsString]] to string. // 5. Return segments. diff --git a/Libraries/LibJS/Runtime/Intl/SegmentsPrototype.cpp b/Libraries/LibJS/Runtime/Intl/SegmentsPrototype.cpp index 26662ac625b..3be7b243856 100644 --- a/Libraries/LibJS/Runtime/Intl/SegmentsPrototype.cpp +++ b/Libraries/LibJS/Runtime/Intl/SegmentsPrototype.cpp @@ -13,7 +13,7 @@ namespace JS::Intl { GC_DEFINE_ALLOCATOR(SegmentsPrototype); -// 19.5.2 The %SegmentsPrototype% Object, https://tc39.es/ecma402/#sec-%segmentsprototype%-object +// 19.5.2 The %IntlSegmentsPrototype% Object, https://tc39.es/ecma402/#sec-%intlsegmentsprototype%-object SegmentsPrototype::SegmentsPrototype(Realm& realm) : PrototypeObject(realm.intrinsics().object_prototype()) { @@ -30,7 +30,7 @@ void SegmentsPrototype::initialize(Realm& realm) define_native_function(realm, vm.names.containing, containing, 1, attr); } -// 19.5.2.1 %SegmentsPrototype%.containing ( index ), https://tc39.es/ecma402/#sec-%segmentsprototype%.containing +// 19.5.2.1 %IntlSegmentsPrototype%.containing ( index ), https://tc39.es/ecma402/#sec-%intlsegmentsprototype%.containing JS_DEFINE_NATIVE_FUNCTION(SegmentsPrototype::containing) { // 1. Let segments be the this value. @@ -63,7 +63,7 @@ JS_DEFINE_NATIVE_FUNCTION(SegmentsPrototype::containing) return TRY(create_segment_data_object(vm, segmenter, string, start_index, end_index)); } -// 19.5.2.2 %SegmentsPrototype% [ @@iterator ] ( ), https://tc39.es/ecma402/#sec-%segmentsprototype%-@@iterator +// 19.5.2.2 %IntlSegmentsPrototype% [ %Symbol.iterator% ] ( ), https://tc39.es/ecma402/#sec-%intlsegmentsprototype%-%symbol.iterator% JS_DEFINE_NATIVE_FUNCTION(SegmentsPrototype::symbol_iterator) { auto& realm = *vm.current_realm();