diff --git a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeNumberFormat.cpp b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeNumberFormat.cpp index 310a0165b4..d94e4b6dbc 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeNumberFormat.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeNumberFormat.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -631,11 +632,9 @@ static ErrorOr parse_units(String locale_units_path, UnicodeLocaleData& lo }; auto is_sanctioned_unit = [](StringView unit_name) { - // This is a copy of the units sanctioned for use within ECMA-402. LibUnicode generally tries to - // avoid being directly dependent on ECMA-402, but this rather significantly reduces the amount + // LibUnicode generally tries to avoid being directly dependent on ECMA-402, but this rather significantly reduces the amount // of data generated here, and ECMA-402 is currently the only consumer of this data. - // https://tc39.es/ecma402/#table-sanctioned-simple-unit-identifiers - constexpr auto sanctioned_units = AK::Array { "acre"sv, "bit"sv, "byte"sv, "celsius"sv, "centimeter"sv, "day"sv, "degree"sv, "fahrenheit"sv, "fluid-ounce"sv, "foot"sv, "gallon"sv, "gigabit"sv, "gigabyte"sv, "gram"sv, "hectare"sv, "hour"sv, "inch"sv, "kilobit"sv, "kilobyte"sv, "kilogram"sv, "kilometer"sv, "liter"sv, "megabit"sv, "megabyte"sv, "meter"sv, "mile"sv, "mile-scandinavian"sv, "milliliter"sv, "millimeter"sv, "millisecond"sv, "minute"sv, "month"sv, "ounce"sv, "percent"sv, "petabyte"sv, "pound"sv, "second"sv, "stone"sv, "terabit"sv, "terabyte"sv, "week"sv, "yard"sv, "year"sv }; + constexpr auto sanctioned_units = JS::Intl::sanctioned_single_unit_identifiers(); return find(sanctioned_units.begin(), sanctioned_units.end(), unit_name) != sanctioned_units.end(); }; diff --git a/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp index b3b536a1a6..711992647a 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp @@ -140,48 +140,46 @@ bool is_well_formed_currency_code(StringView currency) // 6.5.1 IsWellFormedUnitIdentifier ( unitIdentifier ), https://tc39.es/ecma402/#sec-iswellformedunitidentifier bool is_well_formed_unit_identifier(StringView unit_identifier) { - // 6.5.2 IsSanctionedSimpleUnitIdentifier ( unitIdentifier ), https://tc39.es/ecma402/#sec-iswellformedunitidentifier - constexpr auto is_sanctioned_simple_unit_identifier = [](StringView unit_identifier) { + // 6.5.2 IsSanctionedSingleUnitIdentifier ( unitIdentifier ), https://tc39.es/ecma402/#sec-issanctionedsingleunitidentifier + constexpr auto is_sanctioned_single_unit_identifier = [](StringView unit_identifier) { // 1. If unitIdentifier is listed in Table 2 below, return true. // 2. Else, return false. - static constexpr auto sanctioned_units = sanctioned_simple_unit_identifiers(); + static constexpr auto sanctioned_units = sanctioned_single_unit_identifiers(); return find(sanctioned_units.begin(), sanctioned_units.end(), unit_identifier) != sanctioned_units.end(); }; - // 1. If the result of IsSanctionedSimpleUnitIdentifier(unitIdentifier) is true, then - if (is_sanctioned_simple_unit_identifier(unit_identifier)) { + // 1. If ! IsSanctionedSingleUnitIdentifier(unitIdentifier) is true, then + if (is_sanctioned_single_unit_identifier(unit_identifier)) { // a. Return true. return true; } + // 2. Let i be ! StringIndexOf(unitIdentifier, "-per-", 0). auto indices = unit_identifier.find_all("-per-"sv); - // 2. If the substring "-per-" does not occur exactly once in unitIdentifier, then + // 3. If i is -1 or ! StringIndexOf(unitIdentifier, "-per-", i + 1) is not -1, then if (indices.size() != 1) { // a. Return false. return false; } - // 3. Let numerator be the substring of unitIdentifier from the beginning to just before "-per-". + // 4. Assert: The five-character substring "-per-" occurs exactly once in unitIdentifier, at index i. + // NOTE: We skip this because the indices vector being of size 1 already verifies this invariant. + + // 5. Let numerator be the substring of unitIdentifier from 0 to i. auto numerator = unit_identifier.substring_view(0, indices[0]); - // 4. If the result of IsSanctionedSimpleUnitIdentifier(numerator) is false, then - if (!is_sanctioned_simple_unit_identifier(numerator)) { - // a. Return false. - return false; - } - - // 5. Let denominator be the substring of unitIdentifier from just after "-per-" to the end. + // 6. Let denominator be the substring of unitIdentifier from i + 5. auto denominator = unit_identifier.substring_view(indices[0] + 5); - // 6. If the result of IsSanctionedSimpleUnitIdentifier(denominator) is false, then - if (!is_sanctioned_simple_unit_identifier(denominator)) { - // a. Return false. - return false; + // 7. If ! IsSanctionedSingleUnitIdentifier(numerator) and ! IsSanctionedSingleUnitIdentifier(denominator) are both true, then + if (is_sanctioned_single_unit_identifier(numerator) && is_sanctioned_single_unit_identifier(denominator)) { + // a. Return true. + return true; } - // 7. Return true. - return true; + // 8. Return false. + return false; } // 9.2.1 CanonicalizeLocaleList ( locales ), https://tc39.es/ecma402/#sec-canonicalizelocalelist diff --git a/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.h b/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.h index e4b8270583..55f146cee1 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.h +++ b/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.h @@ -54,7 +54,8 @@ struct PatternPartition { String value; }; -constexpr auto sanctioned_simple_unit_identifiers() +// Table 2: Single units sanctioned for use in ECMAScript, https://tc39.es/ecma402/#table-sanctioned-single-unit-identifiers +constexpr auto sanctioned_single_unit_identifiers() { return AK::Array { "acre"sv, "bit"sv, "byte"sv, "celsius"sv, "centimeter"sv, "day"sv, "degree"sv, "fahrenheit"sv, "fluid-ounce"sv, "foot"sv, "gallon"sv, "gigabit"sv, "gigabyte"sv, "gram"sv, "hectare"sv, "hour"sv, "inch"sv, "kilobit"sv, "kilobyte"sv, "kilogram"sv, "kilometer"sv, "liter"sv, "megabit"sv, "megabyte"sv, "meter"sv, "mile"sv, "mile-scandinavian"sv, "milliliter"sv, "millimeter"sv, "millisecond"sv, "minute"sv, "month"sv, "ounce"sv, "percent"sv, "petabyte"sv, "pound"sv, "second"sv, "stone"sv, "terabit"sv, "terabyte"sv, "week"sv, "yard"sv, "year"sv }; } diff --git a/Userland/Libraries/LibJS/Runtime/Intl/Intl.cpp b/Userland/Libraries/LibJS/Runtime/Intl/Intl.cpp index edd3c7abef..fd0a2f6a29 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/Intl.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/Intl.cpp @@ -141,7 +141,7 @@ JS_DEFINE_NATIVE_FUNCTION(Intl::supported_values_of) // 7. Else if key is "unit", then else if (key == "unit"sv) { // a. Let list be ! AvailableUnits( ). - static auto units = sanctioned_simple_unit_identifiers(); + static auto units = sanctioned_single_unit_identifiers(); list = units.span(); } // 8. Else,