summaryrefslogtreecommitdiff
path: root/Meta/Lagom
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2021-11-13 10:15:33 -0500
committerLinus Groh <mail@linusgroh.de>2021-11-13 19:01:25 +0000
commitc65dea64bd9adaef6955981c5f633cca485218aa (patch)
tree989e7f31f9c2e521152f80ade1a772d2740573af /Meta/Lagom
parentd872d030f128937dc839fc5e3682fe2ab87a7907 (diff)
downloadserenity-c65dea64bd9adaef6955981c5f633cca485218aa.zip
LibJS+LibUnicode: Don't remove {currency} keys in GetNumberFormatPattern
In order to implement Intl.NumberFormat.prototype.formatToParts, do not replace {currency} keys in the format pattern before ECMA-402 tells us to. Otherwise, the array return by formatToParts will not contain the expected currency key. Early replacement was done to avoid resolving the currency display more than once, as it involves a couple of round trips to search through LibUnicode data. So this adds a non-standard method to NumberFormat to do this resolution and cache the result. Another side effect of this change is that LibUnicode must replace unit format patterns of the form "{0} {1}" during code generation. These were previously skipped during code generation because LibJS would just replace the keys with the currency display at runtime. But now that the currency display injection is delayed, any {0} or {1} keys in the format pattern will cause PartitionNumberPattern to abort.
Diffstat (limited to 'Meta/Lagom')
-rw-r--r--Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeNumberFormat.cpp20
1 files changed, 7 insertions, 13 deletions
diff --git a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeNumberFormat.cpp b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeNumberFormat.cpp
index fb19c3ae95..0c828ba5bc 100644
--- a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeNumberFormat.cpp
+++ b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeNumberFormat.cpp
@@ -79,24 +79,23 @@ struct UnicodeLocaleData {
Vector<String> numeric_symbols;
};
-static void parse_number_pattern(String pattern, UnicodeLocaleData& locale_data, NumberFormat& format, bool is_unit_pattern = false)
+static void parse_number_pattern(String pattern, UnicodeLocaleData& locale_data, NumberFormat& format)
{
// https://unicode.org/reports/tr35/tr35-numbers.html#Number_Format_Patterns
// https://cldr.unicode.org/translation/number-currency-formats/number-and-currency-patterns
auto replace_patterns = [&](String pattern) {
- if (is_unit_pattern) {
- // Skip parsing unit patterns, which are of the form "{0} {1}", and do not contain any
- // of the replacement patterns below.
- return pattern;
- }
-
static HashMap<StringView, StringView> replacements = {
+ { "{0}"sv, "{number}"sv },
+ { "{1}"sv, "{currency}"sv },
{ "%"sv, "{percentSign}"sv },
{ "+"sv, "{plusSign}"sv },
{ "-"sv, "{minusSign}"sv },
{ "ยค"sv, "{currency}"sv }, // U+00A4 Currency Sign
};
+ for (auto const& replacement : replacements)
+ pattern = pattern.replace(replacement.key, replacement.value, true);
+
if (auto start_number_index = pattern.find_any_of("#0"sv, String::SearchDirection::Forward); start_number_index.has_value()) {
auto end_number_index = *start_number_index + 1;
@@ -111,9 +110,6 @@ static void parse_number_pattern(String pattern, UnicodeLocaleData& locale_data,
pattern.substring_view(end_number_index));
}
- for (auto const& replacement : replacements)
- pattern = pattern.replace(replacement.key, replacement.value, true);
-
return pattern;
};
@@ -173,18 +169,16 @@ static void parse_number_systems(String locale_numbers_path, UnicodeLocaleData&
return;
NumberFormat format {};
- bool is_unit_pattern = false;
if (auto type = split_key[0].template to_uint<u64>(); type.has_value()) {
VERIFY(*type % 10 == 0);
format.magnitude = static_cast<u8>(log10(*type));
} else {
VERIFY(split_key[0] == "unitPattern"sv);
- is_unit_pattern = true;
}
format.plurality = NumberFormat::plurality_from_string(split_key[2]);
- parse_number_pattern(value.as_string(), locale_data, format, is_unit_pattern);
+ parse_number_pattern(value.as_string(), locale_data, format);
result.append(move(format));
});