From c2e5b20eb689faaf25f3ef235757b9eda0c37f95 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Thu, 14 Jul 2022 09:37:36 -0400 Subject: [PATCH] LibUnicode: Generate available values for the keywords co, kf, kn, hc This also ensures we only include values we actually support in the generated list of available values. --- .../LibUnicode/GenerateUnicodeLocale.cpp | 36 +++++++++++++++++-- .../CodeGenerators/LibUnicode/GeneratorUtil.h | 10 +++--- Userland/Libraries/LibUnicode/Forward.h | 2 ++ Userland/Libraries/LibUnicode/Locale.cpp | 6 ++++ Userland/Libraries/LibUnicode/Locale.h | 6 ++++ 5 files changed, 53 insertions(+), 7 deletions(-) diff --git a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeLocale.cpp b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeLocale.cpp index 1ec225e286..f0fec2da64 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeLocale.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeLocale.cpp @@ -413,7 +413,7 @@ static ErrorOr preprocess_languages(String locale_path, UnicodeLocaleData& static ErrorOr parse_unicode_extension_keywords(String bcp47_path, UnicodeLocaleData& locale_data) { - constexpr auto desired_keywords = Array { "ca"sv, "kf"sv, "kn"sv, "nu"sv }; + constexpr auto desired_keywords = Array { "ca"sv, "co"sv, "hc"sv, "kf"sv, "kn"sv, "nu"sv }; auto keywords = TRY(read_json_file(bcp47_path)); auto const& keyword_object = keywords.as_object().get("keyword"sv); @@ -430,10 +430,23 @@ static ErrorOr parse_unicode_extension_keywords(String bcp47_path, Unicode auto& keywords = locale_data.keywords.ensure(key); + // FIXME: ECMA-402 requires the list of supported collation types to include "default", but + // that type does not appear in collation.json. + if (key == "co" && !keywords.contains_slow("default"sv)) + keywords.append("default"sv); + value.as_object().for_each_member([&](auto const& keyword, auto const& properties) { if (!properties.is_object()) return; + // Filter out values not permitted by ECMA-402. + // https://tc39.es/ecma402/#sec-intl-collator-internal-slots + if (key == "co"sv && keyword.is_one_of("search"sv, "standard"sv)) + return; + // https://tc39.es/ecma402/#sec-intl.numberformat-internal-slots + if (key == "nu"sv && keyword.is_one_of("finance"sv, "native"sv, "traditio"sv)) + return; + if (auto const& preferred = properties.as_object().get("_preferred"sv); preferred.is_string()) { locale_data.keyword_aliases.ensure(key).append({ preferred.as_string(), keyword }); return; @@ -441,6 +454,7 @@ static ErrorOr parse_unicode_extension_keywords(String bcp47_path, Unicode if (auto const& alias = properties.as_object().get("_alias"sv); alias.is_string()) locale_data.keyword_aliases.ensure(key).append({ keyword, alias.as_string() }); + keywords.append(keyword); }); }); @@ -1127,8 +1141,20 @@ struct TextLayout { }; )~~~"); - generate_available_values(generator, "get_available_calendars"sv, locale_data.keywords.find("ca"sv)->value, locale_data.keyword_aliases.find("ca"sv)->value); - generate_available_values(generator, "get_available_number_systems"sv, locale_data.keywords.find("nu"sv)->value, locale_data.keyword_aliases.find("nu"sv)->value); + generate_available_values(generator, "get_available_calendars"sv, locale_data.keywords.find("ca"sv)->value, locale_data.keyword_aliases.find("ca"sv)->value, + [](auto calendar) { + // FIXME: Remove this filter when we support all calendars. + return calendar.is_one_of("gregory"sv, "iso8601"sv); + }); + generate_available_values(generator, "get_available_collation_case_orderings"sv, locale_data.keywords.find("kf"sv)->value, locale_data.keyword_aliases.find("kf"sv)->value); + generate_available_values(generator, "get_available_collation_numeric_orderings"sv, locale_data.keywords.find("kn"sv)->value, locale_data.keyword_aliases.find("kn"sv)->value); + generate_available_values(generator, "get_available_collation_types"sv, locale_data.keywords.find("co"sv)->value, locale_data.keyword_aliases.find("co"sv)->value, + [](auto collation) { + // FIXME: Remove this filter when we support all collation types. + return collation == "default"sv; + }); + generate_available_values(generator, "get_available_hour_cycles"sv, locale_data.keywords.find("hc"sv)->value); + generate_available_values(generator, "get_available_number_systems"sv, locale_data.keywords.find("nu"sv)->value); generate_available_values(generator, "get_available_currencies"sv, locale_data.currencies); locale_data.unique_display_patterns.generate(generator, "DisplayPatternImpl"sv, "s_display_patterns"sv, 30); @@ -1512,6 +1538,10 @@ Vector get_keywords_for_locale(StringView locale, StringView key) return values; } + // FIXME: Generate locale-preferred collation data when available in the CLDR. + if (key == "co"sv) + return Vector { get_available_collation_types() }; + auto locale_value = locale_from_string(locale); if (!locale_value.has_value()) return {}; diff --git a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GeneratorUtil.h b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GeneratorUtil.h index 0cd143737f..a0888b531c 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GeneratorUtil.h +++ b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GeneratorUtil.h @@ -526,18 +526,20 @@ static constexpr Array, @size@> @name@ { { } template -void generate_available_values(SourceGenerator& generator, StringView name, Vector const& values, Vector const& aliases = {}) +void generate_available_values(SourceGenerator& generator, StringView name, Vector const& values, Vector const& aliases = {}, Function value_filter = {}) { generator.set("name", name); - generator.set("size", String::number(values.size())); generator.append(R"~~~( Span @name@() { - static constexpr Array values { {)~~~"); + static constexpr auto values = Array {)~~~"); bool first = true; for (auto const& value : values) { + if (value_filter && !value_filter(value)) + continue; + generator.append(first ? " "sv : ", "sv); first = false; @@ -547,7 +549,7 @@ Span @name@() generator.append(String::formatted("\"{}\"sv", value)); } - generator.append(R"~~~( } }; + generator.append(R"~~~( }; return values.span(); } )~~~"); diff --git a/Userland/Libraries/LibUnicode/Forward.h b/Userland/Libraries/LibUnicode/Forward.h index 252da3bab5..3c438ecafe 100644 --- a/Userland/Libraries/LibUnicode/Forward.h +++ b/Userland/Libraries/LibUnicode/Forward.h @@ -28,8 +28,10 @@ enum class HourCycle : u8; enum class HourCycleRegion : u16; enum class Key : u8; enum class KeywordCalendar : u8; +enum class KeywordCollation : u8; enum class KeywordColCaseFirst : u8; enum class KeywordColNumeric : u8; +enum class KeywordHours : u8; enum class KeywordNumbers : u8; enum class Language : u16; enum class ListPatternStyle : u8; diff --git a/Userland/Libraries/LibUnicode/Locale.cpp b/Userland/Libraries/LibUnicode/Locale.cpp index ac4efd88b2..7dc887f1d8 100644 --- a/Userland/Libraries/LibUnicode/Locale.cpp +++ b/Userland/Libraries/LibUnicode/Locale.cpp @@ -767,6 +767,10 @@ StringView style_to_string(Style style) } Span __attribute__((weak)) get_available_calendars() { return {}; } +Span __attribute__((weak)) get_available_collation_case_orderings() { return {}; } +Span __attribute__((weak)) get_available_collation_numeric_orderings() { return {}; } +Span __attribute__((weak)) get_available_collation_types() { return {}; } +Span __attribute__((weak)) get_available_hour_cycles() { return {}; } Span __attribute__((weak)) get_available_number_systems() { return {}; } Optional __attribute__((weak)) locale_from_string(StringView) { return {}; } Optional __attribute__((weak)) language_from_string(StringView) { return {}; } @@ -777,6 +781,8 @@ Optional __attribute__((weak)) date_field_from_string(StringView) { r Optional __attribute__((weak)) list_pattern_type_from_string(StringView) { return {}; } Optional __attribute__((weak)) key_from_string(StringView) { return {}; } Optional __attribute__((weak)) keyword_ca_from_string(StringView) { return {}; } +Optional __attribute__((weak)) keyword_co_from_string(StringView) { return {}; } +Optional __attribute__((weak)) keyword_hc_from_string(StringView) { return {}; } Optional __attribute__((weak)) keyword_kf_from_string(StringView) { return {}; } Optional __attribute__((weak)) keyword_kn_from_string(StringView) { return {}; } Optional __attribute__((weak)) keyword_nu_from_string(StringView) { return {}; } diff --git a/Userland/Libraries/LibUnicode/Locale.h b/Userland/Libraries/LibUnicode/Locale.h index 4a0ae4a782..b42ad6e2f1 100644 --- a/Userland/Libraries/LibUnicode/Locale.h +++ b/Userland/Libraries/LibUnicode/Locale.h @@ -146,6 +146,10 @@ String const& default_locale(); bool is_locale_available(StringView locale); Span get_available_calendars(); +Span get_available_collation_case_orderings(); +Span get_available_collation_numeric_orderings(); +Span get_available_collation_types(); +Span get_available_hour_cycles(); Span get_available_number_systems(); Style style_from_string(StringView style); @@ -161,6 +165,8 @@ Optional list_pattern_type_from_string(StringView list_pattern_ Optional key_from_string(StringView key); Optional keyword_ca_from_string(StringView ca); +Optional keyword_co_from_string(StringView co); +Optional keyword_hc_from_string(StringView hc); Optional keyword_kf_from_string(StringView kf); Optional keyword_kn_from_string(StringView kn); Optional keyword_nu_from_string(StringView nu);