Browse Source

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.
Timothy Flynn 3 years ago
parent
commit
c2e5b20eb6

+ 33 - 3
Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeLocale.cpp

@@ -413,7 +413,7 @@ static ErrorOr<void> preprocess_languages(String locale_path, UnicodeLocaleData&
 
 static ErrorOr<void> 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<void> 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<void> 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<StringView> 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<StringView> { get_available_collation_types() };
+
     auto locale_value = locale_from_string(locale);
     if (!locale_value.has_value())
         return {};

+ 6 - 4
Meta/Lagom/Tools/CodeGenerators/LibUnicode/GeneratorUtil.h

@@ -526,18 +526,20 @@ static constexpr Array<Span<@type@ const>, @size@> @name@ { {
 }
 
 template<typename T>
-void generate_available_values(SourceGenerator& generator, StringView name, Vector<T> const& values, Vector<Alias> const& aliases = {})
+void generate_available_values(SourceGenerator& generator, StringView name, Vector<T> const& values, Vector<Alias> const& aliases = {}, Function<bool(StringView)> value_filter = {})
 {
     generator.set("name", name);
-    generator.set("size", String::number(values.size()));
 
     generator.append(R"~~~(
 Span<StringView const> @name@()
 {
-    static constexpr Array<StringView, @size@> 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<StringView const> @name@()
             generator.append(String::formatted("\"{}\"sv", value));
     }
 
-    generator.append(R"~~~( } };
+    generator.append(R"~~~( };
     return values.span();
 }
 )~~~");

+ 2 - 0
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;

+ 6 - 0
Userland/Libraries/LibUnicode/Locale.cpp

@@ -767,6 +767,10 @@ StringView style_to_string(Style style)
 }
 
 Span<StringView const> __attribute__((weak)) get_available_calendars() { return {}; }
+Span<StringView const> __attribute__((weak)) get_available_collation_case_orderings() { return {}; }
+Span<StringView const> __attribute__((weak)) get_available_collation_numeric_orderings() { return {}; }
+Span<StringView const> __attribute__((weak)) get_available_collation_types() { return {}; }
+Span<StringView const> __attribute__((weak)) get_available_hour_cycles() { return {}; }
 Span<StringView const> __attribute__((weak)) get_available_number_systems() { return {}; }
 Optional<Locale> __attribute__((weak)) locale_from_string(StringView) { return {}; }
 Optional<Language> __attribute__((weak)) language_from_string(StringView) { return {}; }
@@ -777,6 +781,8 @@ Optional<DateField> __attribute__((weak)) date_field_from_string(StringView) { r
 Optional<ListPatternType> __attribute__((weak)) list_pattern_type_from_string(StringView) { return {}; }
 Optional<Key> __attribute__((weak)) key_from_string(StringView) { return {}; }
 Optional<KeywordCalendar> __attribute__((weak)) keyword_ca_from_string(StringView) { return {}; }
+Optional<KeywordCollation> __attribute__((weak)) keyword_co_from_string(StringView) { return {}; }
+Optional<KeywordHours> __attribute__((weak)) keyword_hc_from_string(StringView) { return {}; }
 Optional<KeywordColCaseFirst> __attribute__((weak)) keyword_kf_from_string(StringView) { return {}; }
 Optional<KeywordColNumeric> __attribute__((weak)) keyword_kn_from_string(StringView) { return {}; }
 Optional<KeywordNumbers> __attribute__((weak)) keyword_nu_from_string(StringView) { return {}; }

+ 6 - 0
Userland/Libraries/LibUnicode/Locale.h

@@ -146,6 +146,10 @@ String const& default_locale();
 bool is_locale_available(StringView locale);
 
 Span<StringView const> get_available_calendars();
+Span<StringView const> get_available_collation_case_orderings();
+Span<StringView const> get_available_collation_numeric_orderings();
+Span<StringView const> get_available_collation_types();
+Span<StringView const> get_available_hour_cycles();
 Span<StringView const> get_available_number_systems();
 
 Style style_from_string(StringView style);
@@ -161,6 +165,8 @@ Optional<ListPatternType> list_pattern_type_from_string(StringView list_pattern_
 
 Optional<Key> key_from_string(StringView key);
 Optional<KeywordCalendar> keyword_ca_from_string(StringView ca);
+Optional<KeywordCollation> keyword_co_from_string(StringView co);
+Optional<KeywordHours> keyword_hc_from_string(StringView hc);
 Optional<KeywordColCaseFirst> keyword_kf_from_string(StringView kf);
 Optional<KeywordColNumeric> keyword_kn_from_string(StringView kn);
 Optional<KeywordNumbers> keyword_nu_from_string(StringView nu);