1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-23 18:17:41 +00:00

LibJS: Use consistent ASCII case-transformation and string language

Also update the incorrect spec link for IsWellFormedCurrencyCode.

These are editorial changes in the Intl spec. See:
6939b44
3a775eb
97a7940
129c790
42ec908
ea25c36
This commit is contained in:
Timothy Flynn 2022-03-28 09:53:06 -04:00 committed by Linus Groh
parent 72674d7905
commit 1a76839e8d
5 changed files with 21 additions and 21 deletions

View file

@ -407,7 +407,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_locale_string)
// 2. Let len be ? ToLength(? Get(array, "length")). // 2. Let len be ? ToLength(? Get(array, "length")).
auto length = TRY(length_of_array_like(global_object, *this_object)); auto length = TRY(length_of_array_like(global_object, *this_object));
// 3. Let separator be the String value for the list-separator String appropriate for the host environment's current locale (this is derived in an implementation-defined way). // 3. Let separator be the implementation-defined list-separator String value appropriate for the host environment's current locale (such as ", ").
constexpr auto separator = ","sv; constexpr auto separator = ","sv;
// 4. Let R be the empty String. // 4. Let R be the empty String.

View file

@ -121,15 +121,15 @@ String canonicalize_unicode_locale_id(Unicode::LocaleID& locale)
return locale_id.release_value(); return locale_id.release_value();
} }
// 6.3.1 IsWellFormedCurrencyCode ( currency ), https://tc39.es/ecma402/#sec-canonicalcodefordisplaynames // 6.3.1 IsWellFormedCurrencyCode ( currency ), https://tc39.es/ecma402/#sec-iswellformedcurrencycode
bool is_well_formed_currency_code(StringView currency) bool is_well_formed_currency_code(StringView currency)
{ {
// 1. Let normalized be the result of mapping currency to upper case as described in 6.1. // 1. If the length of currency is not 3, return false.
// 2. If the number of elements in normalized is not 3, return false.
if (currency.length() != 3) if (currency.length() != 3)
return false; return false;
// 3. If normalized contains any character that is not in the range "A" to "Z" (U+0041 to U+005A), return false. // 2. Let normalized be the ASCII-uppercase of currency.
// 3. If normalized contains any code unit outside of 0x0041 through 0x005A (corresponding to Unicode characters LATIN CAPITAL LETTER A through LATIN CAPITAL LETTER Z), return false.
if (!all_of(currency, is_ascii_alpha)) if (!all_of(currency, is_ascii_alpha))
return false; return false;

View file

@ -116,8 +116,7 @@ ThrowCompletionOr<Value> canonical_code_for_display_names(GlobalObject& global_o
if (!locale_id.has_value()) if (!locale_id.has_value())
return vm.throw_completion<RangeError>(global_object, ErrorType::IntlInvalidLanguageTag, code); return vm.throw_completion<RangeError>(global_object, ErrorType::IntlInvalidLanguageTag, code);
// c. Set code to CanonicalizeUnicodeLocaleId(code). // c. Return ! CanonicalizeUnicodeLocaleId(code).
// d. Return code.
auto canonicalized_tag = JS::Intl::canonicalize_unicode_locale_id(*locale_id); auto canonicalized_tag = JS::Intl::canonicalize_unicode_locale_id(*locale_id);
return js_string(vm, move(canonicalized_tag)); return js_string(vm, move(canonicalized_tag));
} }
@ -128,8 +127,7 @@ ThrowCompletionOr<Value> canonical_code_for_display_names(GlobalObject& global_o
if (!Unicode::is_unicode_region_subtag(code)) if (!Unicode::is_unicode_region_subtag(code))
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, code, "region"sv); return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, code, "region"sv);
// b. Let code be the result of mapping code to upper case as described in 6.1. // b. Return the ASCII-uppercase of code.
// c. Return code.
return js_string(vm, code.to_uppercase_string()); return js_string(vm, code.to_uppercase_string());
} }
@ -139,8 +137,13 @@ ThrowCompletionOr<Value> canonical_code_for_display_names(GlobalObject& global_o
if (!Unicode::is_unicode_script_subtag(code)) if (!Unicode::is_unicode_script_subtag(code))
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, code, "script"sv); return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, code, "script"sv);
// b. Let code be the result of mapping the first character in code to upper case, and mapping the second, third, and fourth character in code to lower case, as described in 6.1. // Assert: The length of code is 4, and every code unit of code represents an ASCII letter (0x0041 through 0x005A and 0x0061 through 0x007A, both inclusive).
// c. Return code. VERIFY(code.length() == 4);
VERIFY(all_of(code, is_ascii_alpha));
// c. Let first be the ASCII-uppercase of the substring of code from 0 to 1.
// d. Let rest be the ASCII-lowercase of the substring of code from 1.
// e. Return the string-concatenation of first and rest.
return js_string(vm, code.to_titlecase_string()); return js_string(vm, code.to_titlecase_string());
} }
@ -154,8 +157,7 @@ ThrowCompletionOr<Value> canonical_code_for_display_names(GlobalObject& global_o
if (code.contains('_')) if (code.contains('_'))
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, code, "calendar"sv); return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, code, "calendar"sv);
// c. Let code be the result of mapping code to lower case as described in 6.1. // c. Return the ASCII-lowercase of code.
// d. Return code.
return js_string(vm, code.to_lowercase_string()); return js_string(vm, code.to_lowercase_string());
} }
@ -176,8 +178,7 @@ ThrowCompletionOr<Value> canonical_code_for_display_names(GlobalObject& global_o
if (!is_well_formed_currency_code(code)) if (!is_well_formed_currency_code(code))
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, code, "currency"sv); return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, code, "currency"sv);
// 8. Let code be the result of mapping code to upper case as described in 6.1. // 8. Return the ASCII-uppercase of code.
// 9. Return code.
return js_string(vm, code.to_uppercase_string()); return js_string(vm, code.to_uppercase_string());
} }

View file

@ -941,7 +941,7 @@ RawFormatResult to_raw_precision(GlobalObject& global_object, Value number, int
// 7. Else, // 7. Else,
else { else {
// a. Assert: e < 0. // a. Assert: e < 0.
// b. Let m be the string-concatenation of the String value "0.", (e+1) occurrences of the character "0", and m. // b. Let m be the string-concatenation of "0.", (e+1) occurrences of the character "0", and m.
result.formatted_string = String::formatted( result.formatted_string = String::formatted(
"0.{}{}", "0.{}{}",
String::repeated('0', -1 * (exponent + 1)), String::repeated('0', -1 * (exponent + 1)),
@ -981,7 +981,7 @@ RawFormatResult to_raw_fixed(GlobalObject& global_object, Value number, int min_
// 4. Let xFinal be n / 10^f. // 4. Let xFinal be n / 10^f.
result.rounded_number = divide_by_power(global_object, n, fraction); result.rounded_number = divide_by_power(global_object, n, fraction);
// 5. If n = 0, let m be the String "0". Otherwise, let m be the String consisting of the digits of the decimal representation of n (in order, with no leading zeroes). // 5. If n = 0, let m be "0". Otherwise, let m be the String consisting of the digits of the decimal representation of n (in order, with no leading zeroes).
result.formatted_string = is_zero(n) ? String("0"sv) : number_to_string(n); result.formatted_string = is_zero(n) ? String("0"sv) : number_to_string(n);
// 6. If f ≠ 0, then // 6. If f ≠ 0, then

View file

@ -336,7 +336,7 @@ ThrowCompletionOr<void> set_number_format_unit_options(GlobalObject& global_obje
return vm.throw_completion<TypeError>(global_object, ErrorType::IntlOptionUndefined, "currency"sv, "style"sv, style); return vm.throw_completion<TypeError>(global_object, ErrorType::IntlOptionUndefined, "currency"sv, "style"sv, style);
} }
// 7. Else, // 7. Else,
// a. If the result of IsWellFormedCurrencyCode(currency) is false, throw a RangeError exception. // a. If ! IsWellFormedCurrencyCode(currency) is false, throw a RangeError exception.
else if (!is_well_formed_currency_code(currency.as_string().string())) else if (!is_well_formed_currency_code(currency.as_string().string()))
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, currency, "currency"sv); return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, currency, "currency"sv);
@ -356,7 +356,7 @@ ThrowCompletionOr<void> set_number_format_unit_options(GlobalObject& global_obje
return vm.throw_completion<TypeError>(global_object, ErrorType::IntlOptionUndefined, "unit"sv, "style"sv, style); return vm.throw_completion<TypeError>(global_object, ErrorType::IntlOptionUndefined, "unit"sv, "style"sv, style);
} }
// 12. Else, // 12. Else,
// a. If the result of IsWellFormedUnitIdentifier(unit) is false, throw a RangeError exception. // a. If ! IsWellFormedUnitIdentifier(unit) is false, throw a RangeError exception.
else if (!is_well_formed_unit_identifier(unit.as_string().string())) else if (!is_well_formed_unit_identifier(unit.as_string().string()))
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, unit, "unit"sv); return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, unit, "unit"sv);
@ -365,8 +365,7 @@ ThrowCompletionOr<void> set_number_format_unit_options(GlobalObject& global_obje
// 14. If style is "currency", then // 14. If style is "currency", then
if (intl_object.style() == NumberFormat::Style::Currency) { if (intl_object.style() == NumberFormat::Style::Currency) {
// a. Let currency be the result of converting currency to upper case as specified in 6.1. // a. Set intlObj.[[Currency]] to the ASCII-uppercase of currency.
// b. Set intlObj.[[Currency]] to currency.
intl_object.set_currency(currency.as_string().string().to_uppercase()); intl_object.set_currency(currency.as_string().string().to_uppercase());
// c. Set intlObj.[[CurrencyDisplay]] to currencyDisplay. // c. Set intlObj.[[CurrencyDisplay]] to currencyDisplay.