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.
This commit is contained in:
Timothy Flynn 2022-07-14 09:37:36 -04:00 committed by Andreas Kling
parent a660040806
commit c2e5b20eb6
Notes: sideshowbarker 2024-07-17 08:55:42 +09:00
5 changed files with 53 additions and 7 deletions

View file

@ -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) 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 keywords = TRY(read_json_file(bcp47_path));
auto const& keyword_object = keywords.as_object().get("keyword"sv); 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); 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) { value.as_object().for_each_member([&](auto const& keyword, auto const& properties) {
if (!properties.is_object()) if (!properties.is_object())
return; 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()) { if (auto const& preferred = properties.as_object().get("_preferred"sv); preferred.is_string()) {
locale_data.keyword_aliases.ensure(key).append({ preferred.as_string(), keyword }); locale_data.keyword_aliases.ensure(key).append({ preferred.as_string(), keyword });
return; 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()) if (auto const& alias = properties.as_object().get("_alias"sv); alias.is_string())
locale_data.keyword_aliases.ensure(key).append({ keyword, alias.as_string() }); locale_data.keyword_aliases.ensure(key).append({ keyword, alias.as_string() });
keywords.append(keyword); 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_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); [](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); 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); 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; 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); auto locale_value = locale_from_string(locale);
if (!locale_value.has_value()) if (!locale_value.has_value())
return {}; return {};

View file

@ -526,18 +526,20 @@ static constexpr Array<Span<@type@ const>, @size@> @name@ { {
} }
template<typename T> 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("name", name);
generator.set("size", String::number(values.size()));
generator.append(R"~~~( generator.append(R"~~~(
Span<StringView const> @name@() Span<StringView const> @name@()
{ {
static constexpr Array<StringView, @size@> values { {)~~~"); static constexpr auto values = Array {)~~~");
bool first = true; bool first = true;
for (auto const& value : values) { for (auto const& value : values) {
if (value_filter && !value_filter(value))
continue;
generator.append(first ? " "sv : ", "sv); generator.append(first ? " "sv : ", "sv);
first = false; first = false;
@ -547,7 +549,7 @@ Span<StringView const> @name@()
generator.append(String::formatted("\"{}\"sv", value)); generator.append(String::formatted("\"{}\"sv", value));
} }
generator.append(R"~~~( } }; generator.append(R"~~~( };
return values.span(); return values.span();
} }
)~~~"); )~~~");

View file

@ -28,8 +28,10 @@ enum class HourCycle : u8;
enum class HourCycleRegion : u16; enum class HourCycleRegion : u16;
enum class Key : u8; enum class Key : u8;
enum class KeywordCalendar : u8; enum class KeywordCalendar : u8;
enum class KeywordCollation : u8;
enum class KeywordColCaseFirst : u8; enum class KeywordColCaseFirst : u8;
enum class KeywordColNumeric : u8; enum class KeywordColNumeric : u8;
enum class KeywordHours : u8;
enum class KeywordNumbers : u8; enum class KeywordNumbers : u8;
enum class Language : u16; enum class Language : u16;
enum class ListPatternStyle : u8; enum class ListPatternStyle : u8;

View file

@ -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_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 {}; } Span<StringView const> __attribute__((weak)) get_available_number_systems() { return {}; }
Optional<Locale> __attribute__((weak)) locale_from_string(StringView) { return {}; } Optional<Locale> __attribute__((weak)) locale_from_string(StringView) { return {}; }
Optional<Language> __attribute__((weak)) language_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<ListPatternType> __attribute__((weak)) list_pattern_type_from_string(StringView) { return {}; }
Optional<Key> __attribute__((weak)) key_from_string(StringView) { return {}; } Optional<Key> __attribute__((weak)) key_from_string(StringView) { return {}; }
Optional<KeywordCalendar> __attribute__((weak)) keyword_ca_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<KeywordColCaseFirst> __attribute__((weak)) keyword_kf_from_string(StringView) { return {}; }
Optional<KeywordColNumeric> __attribute__((weak)) keyword_kn_from_string(StringView) { return {}; } Optional<KeywordColNumeric> __attribute__((weak)) keyword_kn_from_string(StringView) { return {}; }
Optional<KeywordNumbers> __attribute__((weak)) keyword_nu_from_string(StringView) { return {}; } Optional<KeywordNumbers> __attribute__((weak)) keyword_nu_from_string(StringView) { return {}; }

View file

@ -146,6 +146,10 @@ String const& default_locale();
bool is_locale_available(StringView locale); bool is_locale_available(StringView locale);
Span<StringView const> get_available_calendars(); 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(); Span<StringView const> get_available_number_systems();
Style style_from_string(StringView style); 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<Key> key_from_string(StringView key);
Optional<KeywordCalendar> keyword_ca_from_string(StringView ca); 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<KeywordColCaseFirst> keyword_kf_from_string(StringView kf);
Optional<KeywordColNumeric> keyword_kn_from_string(StringView kn); Optional<KeywordColNumeric> keyword_kn_from_string(StringView kn);
Optional<KeywordNumbers> keyword_nu_from_string(StringView nu); Optional<KeywordNumbers> keyword_nu_from_string(StringView nu);