LibJS: Port Intl locale resolution to String
This commit is contained in:
parent
2f1184ccdb
commit
bb4b6d8ce3
Notes:
sideshowbarker
2024-07-17 03:19:14 +09:00
Author: https://github.com/trflynn89 Commit: https://github.com/SerenityOS/serenity/commit/bb4b6d8ce3 Pull-request: https://github.com/SerenityOS/serenity/pull/17092 Reviewed-by: https://github.com/linusg
20 changed files with 208 additions and 205 deletions
|
@ -80,7 +80,7 @@ ThrowCompletionOr<Optional<::Locale::LocaleID>> is_structurally_valid_language_t
|
|||
}
|
||||
|
||||
// 6.2.3 CanonicalizeUnicodeLocaleId ( locale ), https://tc39.es/ecma402/#sec-canonicalizeunicodelocaleid
|
||||
ThrowCompletionOr<DeprecatedString> canonicalize_unicode_locale_id(VM& vm, ::Locale::LocaleID& locale)
|
||||
ThrowCompletionOr<String> canonicalize_unicode_locale_id(VM& vm, ::Locale::LocaleID& locale)
|
||||
{
|
||||
// Note: This implementation differs from the spec in how Step 3 is implemented. The spec assumes
|
||||
// the input to this method is a string, and is written such that operations are performed on parts
|
||||
|
@ -118,7 +118,7 @@ ThrowCompletionOr<DeprecatedString> canonicalize_unicode_locale_id(VM& vm, ::Loc
|
|||
VERIFY(locale_id.has_value());
|
||||
|
||||
// 4. Return localeId.
|
||||
return locale_id->to_deprecated_string();
|
||||
return locale_id.release_value();
|
||||
}
|
||||
|
||||
// 6.3.1 IsWellFormedCurrencyCode ( currency ), https://tc39.es/ecma402/#sec-iswellformedcurrencycode
|
||||
|
@ -183,18 +183,18 @@ bool is_well_formed_unit_identifier(StringView unit_identifier)
|
|||
}
|
||||
|
||||
// 9.2.1 CanonicalizeLocaleList ( locales ), https://tc39.es/ecma402/#sec-canonicalizelocalelist
|
||||
ThrowCompletionOr<Vector<DeprecatedString>> canonicalize_locale_list(VM& vm, Value locales)
|
||||
ThrowCompletionOr<Vector<String>> canonicalize_locale_list(VM& vm, Value locales)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
// 1. If locales is undefined, then
|
||||
if (locales.is_undefined()) {
|
||||
// a. Return a new empty List.
|
||||
return Vector<DeprecatedString> {};
|
||||
return Vector<String> {};
|
||||
}
|
||||
|
||||
// 2. Let seen be a new empty List.
|
||||
Vector<DeprecatedString> seen;
|
||||
Vector<String> seen;
|
||||
|
||||
Object* object = nullptr;
|
||||
// 3. If Type(locales) is String or Type(locales) is Object and locales has an [[InitializedLocale]] internal slot, then
|
||||
|
@ -228,9 +228,9 @@ ThrowCompletionOr<Vector<DeprecatedString>> canonicalize_locale_list(VM& vm, Val
|
|||
|
||||
// ii. If Type(kValue) is not String or Object, throw a TypeError exception.
|
||||
if (!key_value.is_string() && !key_value.is_object())
|
||||
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOrString, key_value.to_string_without_side_effects());
|
||||
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOrString, key_value);
|
||||
|
||||
DeprecatedString tag;
|
||||
String tag;
|
||||
|
||||
// iii. If Type(kValue) is Object and kValue has an [[InitializedLocale]] internal slot, then
|
||||
if (key_value.is_object() && is<Locale>(key_value.as_object())) {
|
||||
|
@ -240,7 +240,7 @@ ThrowCompletionOr<Vector<DeprecatedString>> canonicalize_locale_list(VM& vm, Val
|
|||
// iv. Else,
|
||||
else {
|
||||
// 1. Let tag be ? ToString(kValue).
|
||||
tag = TRY(key_value.to_deprecated_string(vm));
|
||||
tag = TRY(key_value.to_string(vm));
|
||||
}
|
||||
|
||||
// v. If ! IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception.
|
||||
|
@ -264,7 +264,7 @@ ThrowCompletionOr<Vector<DeprecatedString>> canonicalize_locale_list(VM& vm, Val
|
|||
}
|
||||
|
||||
// 9.2.2 BestAvailableLocale ( availableLocales, locale ), https://tc39.es/ecma402/#sec-bestavailablelocale
|
||||
Optional<DeprecatedString> best_available_locale(StringView locale)
|
||||
Optional<StringView> best_available_locale(StringView locale)
|
||||
{
|
||||
// 1. Let candidate be locale.
|
||||
StringView candidate = locale;
|
||||
|
@ -290,12 +290,12 @@ Optional<DeprecatedString> best_available_locale(StringView locale)
|
|||
}
|
||||
|
||||
struct MatcherResult {
|
||||
DeprecatedString locale;
|
||||
String locale;
|
||||
Vector<::Locale::Extension> extensions {};
|
||||
};
|
||||
|
||||
// 9.2.3 LookupMatcher ( availableLocales, requestedLocales ), https://tc39.es/ecma402/#sec-lookupmatcher
|
||||
static ThrowCompletionOr<MatcherResult> lookup_matcher(VM& vm, Vector<DeprecatedString> const& requested_locales)
|
||||
static ThrowCompletionOr<MatcherResult> lookup_matcher(VM& vm, Vector<String> const& requested_locales)
|
||||
{
|
||||
// 1. Let result be a new Record.
|
||||
MatcherResult result {};
|
||||
|
@ -307,7 +307,7 @@ static ThrowCompletionOr<MatcherResult> lookup_matcher(VM& vm, Vector<Deprecated
|
|||
|
||||
// a. Let noExtensionsLocale be the String value that is locale with any Unicode locale extension sequences removed.
|
||||
auto extensions = locale_id->remove_extension_type<::Locale::LocaleExtension>();
|
||||
auto no_extensions_locale = locale_id->to_deprecated_string();
|
||||
auto no_extensions_locale = TRY_OR_THROW_OOM(vm, locale_id->to_string());
|
||||
|
||||
// b. Let availableLocale be ! BestAvailableLocale(availableLocales, noExtensionsLocale).
|
||||
auto available_locale = best_available_locale(no_extensions_locale);
|
||||
|
@ -315,7 +315,7 @@ static ThrowCompletionOr<MatcherResult> lookup_matcher(VM& vm, Vector<Deprecated
|
|||
// c. If availableLocale is not undefined, then
|
||||
if (available_locale.has_value()) {
|
||||
// i. Set result.[[locale]] to availableLocale.
|
||||
result.locale = available_locale.release_value();
|
||||
result.locale = TRY_OR_THROW_OOM(vm, String::from_utf8(*available_locale));
|
||||
|
||||
// ii. If locale and noExtensionsLocale are not the same String value, then
|
||||
if (locale != no_extensions_locale) {
|
||||
|
@ -331,14 +331,14 @@ static ThrowCompletionOr<MatcherResult> lookup_matcher(VM& vm, Vector<Deprecated
|
|||
|
||||
// 3. Let defLocale be ! DefaultLocale().
|
||||
// 4. Set result.[[locale]] to defLocale.
|
||||
result.locale = ::Locale::default_locale();
|
||||
result.locale = TRY_OR_THROW_OOM(vm, String::from_utf8(::Locale::default_locale()));
|
||||
|
||||
// 5. Return result.
|
||||
return result;
|
||||
}
|
||||
|
||||
// 9.2.4 BestFitMatcher ( availableLocales, requestedLocales ), https://tc39.es/ecma402/#sec-bestfitmatcher
|
||||
static ThrowCompletionOr<MatcherResult> best_fit_matcher(VM& vm, Vector<DeprecatedString> const& requested_locales)
|
||||
static ThrowCompletionOr<MatcherResult> best_fit_matcher(VM& vm, Vector<String> const& requested_locales)
|
||||
{
|
||||
// The algorithm is implementation dependent, but should produce results that a typical user of the requested locales would
|
||||
// perceive as at least as good as those produced by the LookupMatcher abstract operation.
|
||||
|
@ -346,14 +346,14 @@ static ThrowCompletionOr<MatcherResult> best_fit_matcher(VM& vm, Vector<Deprecat
|
|||
}
|
||||
|
||||
// 9.2.6 InsertUnicodeExtensionAndCanonicalize ( locale, extension ), https://tc39.es/ecma402/#sec-insert-unicode-extension-and-canonicalize
|
||||
ThrowCompletionOr<DeprecatedString> insert_unicode_extension_and_canonicalize(VM& vm, ::Locale::LocaleID locale, ::Locale::LocaleExtension extension)
|
||||
ThrowCompletionOr<String> insert_unicode_extension_and_canonicalize(VM& vm, ::Locale::LocaleID locale, ::Locale::LocaleExtension extension)
|
||||
{
|
||||
// Note: This implementation differs from the spec in how the extension is inserted. The spec assumes
|
||||
// the input to this method is a string, and is written such that operations are performed on parts
|
||||
// of that string. LibUnicode gives us the parsed locale in a structure, so we can mutate that
|
||||
// structure directly.
|
||||
TRY_OR_THROW_OOM(vm, locale.extensions.try_append(move(extension)));
|
||||
return TRY(canonicalize_unicode_locale_id(vm, locale));
|
||||
return canonicalize_unicode_locale_id(vm, locale);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -377,7 +377,7 @@ static auto& find_key_in_value(T& value, StringView key)
|
|||
}
|
||||
|
||||
// 9.2.7 ResolveLocale ( availableLocales, requestedLocales, options, relevantExtensionKeys, localeData ), https://tc39.es/ecma402/#sec-resolvelocale
|
||||
ThrowCompletionOr<LocaleResult> resolve_locale(VM& vm, Vector<DeprecatedString> const& requested_locales, LocaleOptions const& options, Span<StringView const> relevant_extension_keys)
|
||||
ThrowCompletionOr<LocaleResult> resolve_locale(VM& vm, Vector<String> const& requested_locales, LocaleOptions const& options, Span<StringView const> relevant_extension_keys)
|
||||
{
|
||||
// 1. Let matcher be options.[[localeMatcher]].
|
||||
auto const& matcher = options.locale_matcher;
|
||||
|
@ -434,9 +434,9 @@ ThrowCompletionOr<LocaleResult> resolve_locale(VM& vm, Vector<DeprecatedString>
|
|||
// f. Assert: Type(value) is either String or Null.
|
||||
// NOTE: ECMA-402 assumes keyLocaleData is sorted by locale preference. Our list is sorted
|
||||
// alphabetically, so we get the locale's preferred value from LibUnicode.
|
||||
Optional<DeprecatedString> value;
|
||||
Optional<String> value;
|
||||
if (auto preference = ::Locale::get_preferred_keyword_value_for_locale(found_locale, key); preference.has_value())
|
||||
value = *preference;
|
||||
value = TRY_OR_THROW_OOM(vm, String::from_utf8(*preference));
|
||||
|
||||
// g. Let supportedExtensionAddition be "".
|
||||
Optional<::Locale::Keyword> supported_extension_addition {};
|
||||
|
@ -456,7 +456,7 @@ ThrowCompletionOr<LocaleResult> resolve_locale(VM& vm, Vector<DeprecatedString>
|
|||
// a. If keyLocaleData contains requestedValue, then
|
||||
if (key_locale_data.contains_slow(requested_value)) {
|
||||
// i. Let value be requestedValue.
|
||||
value = requested_value.to_deprecated_string();
|
||||
value = move(requested_value);
|
||||
|
||||
// ii. Let supportedExtensionAddition be the string-concatenation of "-", key, "-", and value.
|
||||
supported_extension_addition = ::Locale::Keyword { TRY_OR_THROW_OOM(vm, String::from_utf8(key)), move(entry.value) };
|
||||
|
@ -465,7 +465,7 @@ ThrowCompletionOr<LocaleResult> resolve_locale(VM& vm, Vector<DeprecatedString>
|
|||
// 4. Else if keyLocaleData contains "true", then
|
||||
else if (key_locale_data.contains_slow("true"sv)) {
|
||||
// a. Let value be "true".
|
||||
value = "true"sv;
|
||||
value = TRY_OR_THROW_OOM(vm, String::from_utf8("true"sv));
|
||||
|
||||
// b. Let supportedExtensionAddition be the string-concatenation of "-" and key.
|
||||
supported_extension_addition = ::Locale::Keyword { TRY_OR_THROW_OOM(vm, String::from_utf8(key)), {} };
|
||||
|
@ -483,14 +483,12 @@ ThrowCompletionOr<LocaleResult> resolve_locale(VM& vm, Vector<DeprecatedString>
|
|||
if (options_value.has_value()) {
|
||||
// 1. Let optionsValue be the string optionsValue after performing the algorithm steps to transform Unicode extension values to canonical syntax per Unicode Technical Standard #35 LDML § 3.2.1 Canonical Unicode Locale Identifiers, treating key as ukey and optionsValue as uvalue productions.
|
||||
// 2. Let optionsValue be the string optionsValue after performing the algorithm steps to replace Unicode extension values with their canonical form per Unicode Technical Standard #35 LDML § 3.2.1 Canonical Unicode Locale Identifiers, treating key as ukey and optionsValue as uvalue productions.
|
||||
auto options_value_string = TRY_OR_THROW_OOM(vm, String::from_deprecated_string(*options_value));
|
||||
TRY_OR_THROW_OOM(vm, ::Locale::canonicalize_unicode_extension_values(key, options_value_string, true));
|
||||
options_value = options_value_string.to_deprecated_string();
|
||||
TRY_OR_THROW_OOM(vm, ::Locale::canonicalize_unicode_extension_values(key, *options_value, true));
|
||||
|
||||
// 3. If optionsValue is the empty String, then
|
||||
if (options_value->is_empty()) {
|
||||
// a. Let optionsValue be "true".
|
||||
options_value = "true"sv;
|
||||
options_value = TRY_OR_THROW_OOM(vm, String::from_utf8("true"sv));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -528,10 +526,10 @@ ThrowCompletionOr<LocaleResult> resolve_locale(VM& vm, Vector<DeprecatedString>
|
|||
}
|
||||
|
||||
// 9.2.8 LookupSupportedLocales ( availableLocales, requestedLocales ), https://tc39.es/ecma402/#sec-lookupsupportedlocales
|
||||
static ThrowCompletionOr<Vector<DeprecatedString>> lookup_supported_locales(VM& vm, Vector<DeprecatedString> const& requested_locales)
|
||||
static ThrowCompletionOr<Vector<String>> lookup_supported_locales(VM& vm, Vector<String> const& requested_locales)
|
||||
{
|
||||
// 1. Let subset be a new empty List.
|
||||
Vector<DeprecatedString> subset;
|
||||
Vector<String> subset;
|
||||
|
||||
// 2. For each element locale of requestedLocales, do
|
||||
for (auto const& locale : requested_locales) {
|
||||
|
@ -540,7 +538,7 @@ static ThrowCompletionOr<Vector<DeprecatedString>> lookup_supported_locales(VM&
|
|||
|
||||
// a. Let noExtensionsLocale be the String value that is locale with any Unicode locale extension sequences removed.
|
||||
locale_id->remove_extension_type<::Locale::LocaleExtension>();
|
||||
auto no_extensions_locale = locale_id->to_deprecated_string();
|
||||
auto no_extensions_locale = TRY_OR_THROW_OOM(vm, locale_id->to_string());
|
||||
|
||||
// b. Let availableLocale be ! BestAvailableLocale(availableLocales, noExtensionsLocale).
|
||||
auto available_locale = best_available_locale(no_extensions_locale);
|
||||
|
@ -555,7 +553,7 @@ static ThrowCompletionOr<Vector<DeprecatedString>> lookup_supported_locales(VM&
|
|||
}
|
||||
|
||||
// 9.2.9 BestFitSupportedLocales ( availableLocales, requestedLocales ), https://tc39.es/ecma402/#sec-bestfitsupportedlocales
|
||||
static ThrowCompletionOr<Vector<DeprecatedString>> best_fit_supported_locales(VM& vm, Vector<DeprecatedString> const& requested_locales)
|
||||
static ThrowCompletionOr<Vector<String>> best_fit_supported_locales(VM& vm, Vector<String> const& requested_locales)
|
||||
{
|
||||
// The BestFitSupportedLocales abstract operation returns the subset of the provided BCP 47
|
||||
// language priority list requestedLocales for which availableLocales has a matching locale
|
||||
|
@ -567,7 +565,7 @@ static ThrowCompletionOr<Vector<DeprecatedString>> best_fit_supported_locales(VM
|
|||
}
|
||||
|
||||
// 9.2.10 SupportedLocales ( availableLocales, requestedLocales, options ), https://tc39.es/ecma402/#sec-supportedlocales
|
||||
ThrowCompletionOr<Array*> supported_locales(VM& vm, Vector<DeprecatedString> const& requested_locales, Value options)
|
||||
ThrowCompletionOr<Array*> supported_locales(VM& vm, Vector<String> const& requested_locales, Value options)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
|
@ -577,7 +575,7 @@ ThrowCompletionOr<Array*> supported_locales(VM& vm, Vector<DeprecatedString> con
|
|||
// 2. Let matcher be ? GetOption(options, "localeMatcher", string, « "lookup", "best fit" », "best fit").
|
||||
auto matcher = TRY(get_option(vm, *options_object, vm.names.localeMatcher, OptionType::String, { "lookup"sv, "best fit"sv }, "best fit"sv));
|
||||
|
||||
Vector<DeprecatedString> supported_locales;
|
||||
Vector<String> supported_locales;
|
||||
|
||||
// 3. If matcher is "best fit", then
|
||||
if (TRY(matcher.as_string().utf8_string_view()) == "best fit"sv) {
|
||||
|
@ -591,7 +589,7 @@ ThrowCompletionOr<Array*> supported_locales(VM& vm, Vector<DeprecatedString> con
|
|||
}
|
||||
|
||||
// 5. Return CreateArrayFromList(supportedLocales).
|
||||
return Array::create_from<DeprecatedString>(realm, supported_locales, [&vm](auto& locale) { return PrimitiveString::create(vm, locale); }).ptr();
|
||||
return Array::create_from<String>(realm, supported_locales, [&vm](auto& locale) { return PrimitiveString::create(vm, move(locale)); }).ptr();
|
||||
}
|
||||
|
||||
// 9.2.12 CoerceOptionsToObject ( options ), https://tc39.es/ecma402/#sec-coerceoptionstoobject
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <AK/DeprecatedString.h>
|
||||
#include <AK/Span.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/Variant.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibJS/Forward.h>
|
||||
|
@ -21,23 +22,23 @@ namespace JS::Intl {
|
|||
|
||||
struct LocaleOptions {
|
||||
Value locale_matcher;
|
||||
Optional<DeprecatedString> ca; // [[Calendar]]
|
||||
Optional<DeprecatedString> co; // [[Collation]]
|
||||
Optional<DeprecatedString> hc; // [[HourCycle]]
|
||||
Optional<DeprecatedString> kf; // [[CaseFirst]]
|
||||
Optional<DeprecatedString> kn; // [[Numeric]]
|
||||
Optional<DeprecatedString> nu; // [[NumberingSystem]]
|
||||
Optional<String> ca; // [[Calendar]]
|
||||
Optional<String> co; // [[Collation]]
|
||||
Optional<String> hc; // [[HourCycle]]
|
||||
Optional<String> kf; // [[CaseFirst]]
|
||||
Optional<String> kn; // [[Numeric]]
|
||||
Optional<String> nu; // [[NumberingSystem]]
|
||||
};
|
||||
|
||||
struct LocaleResult {
|
||||
DeprecatedString locale;
|
||||
DeprecatedString data_locale;
|
||||
Optional<DeprecatedString> ca; // [[Calendar]]
|
||||
Optional<DeprecatedString> co; // [[Collation]]
|
||||
Optional<DeprecatedString> hc; // [[HourCycle]]
|
||||
Optional<DeprecatedString> kf; // [[CaseFirst]]
|
||||
Optional<DeprecatedString> kn; // [[Numeric]]
|
||||
Optional<DeprecatedString> nu; // [[NumberingSystem]]
|
||||
String locale;
|
||||
String data_locale;
|
||||
Optional<String> ca; // [[Calendar]]
|
||||
Optional<String> co; // [[Collation]]
|
||||
Optional<String> hc; // [[HourCycle]]
|
||||
Optional<String> kf; // [[CaseFirst]]
|
||||
Optional<String> kn; // [[Numeric]]
|
||||
Optional<String> nu; // [[NumberingSystem]]
|
||||
};
|
||||
|
||||
struct PatternPartition {
|
||||
|
@ -80,14 +81,14 @@ struct PatternPartitionWithSource : public PatternPartition {
|
|||
using StringOrBoolean = Variant<StringView, bool>;
|
||||
|
||||
ThrowCompletionOr<Optional<::Locale::LocaleID>> is_structurally_valid_language_tag(VM&, StringView locale);
|
||||
ThrowCompletionOr<DeprecatedString> canonicalize_unicode_locale_id(VM&, ::Locale::LocaleID& locale);
|
||||
ThrowCompletionOr<String> canonicalize_unicode_locale_id(VM&, ::Locale::LocaleID& locale);
|
||||
bool is_well_formed_currency_code(StringView currency);
|
||||
bool is_well_formed_unit_identifier(StringView unit_identifier);
|
||||
ThrowCompletionOr<Vector<DeprecatedString>> canonicalize_locale_list(VM&, Value locales);
|
||||
Optional<DeprecatedString> best_available_locale(StringView locale);
|
||||
ThrowCompletionOr<DeprecatedString> insert_unicode_extension_and_canonicalize(VM&, ::Locale::LocaleID locale_id, ::Locale::LocaleExtension extension);
|
||||
ThrowCompletionOr<LocaleResult> resolve_locale(VM&, Vector<DeprecatedString> const& requested_locales, LocaleOptions const& options, Span<StringView const> relevant_extension_keys);
|
||||
ThrowCompletionOr<Array*> supported_locales(VM&, Vector<DeprecatedString> const& requested_locales, Value options);
|
||||
ThrowCompletionOr<Vector<String>> canonicalize_locale_list(VM&, Value locales);
|
||||
Optional<StringView> best_available_locale(StringView locale);
|
||||
ThrowCompletionOr<String> insert_unicode_extension_and_canonicalize(VM&, ::Locale::LocaleID locale_id, ::Locale::LocaleExtension extension);
|
||||
ThrowCompletionOr<LocaleResult> resolve_locale(VM&, Vector<String> const& requested_locales, LocaleOptions const& options, Span<StringView const> relevant_extension_keys);
|
||||
ThrowCompletionOr<Array*> supported_locales(VM&, Vector<String> const& requested_locales, Value options);
|
||||
ThrowCompletionOr<Object*> coerce_options_to_object(VM&, Value options);
|
||||
ThrowCompletionOr<StringOrBoolean> get_string_or_boolean_option(VM&, Object const& options, PropertyKey const& property, Span<StringView const> values, StringOrBoolean true_value, StringOrBoolean falsy_value, StringOrBoolean fallback);
|
||||
ThrowCompletionOr<Optional<int>> default_number_option(VM&, Value value, int minimum, int maximum, Optional<int> fallback);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/Array.h>
|
||||
#include <AK/DeprecatedString.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/StringView.h>
|
||||
#include <LibJS/Runtime/Intl/CollatorCompareFunction.h>
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
|
@ -45,8 +45,8 @@ public:
|
|||
|
||||
virtual ~Collator() override = default;
|
||||
|
||||
DeprecatedString const& locale() const { return m_locale; }
|
||||
void set_locale(DeprecatedString locale) { m_locale = move(locale); }
|
||||
String const& locale() const { return m_locale; }
|
||||
void set_locale(String locale) { m_locale = move(locale); }
|
||||
|
||||
Usage usage() const { return m_usage; }
|
||||
void set_usage(StringView usage);
|
||||
|
@ -60,8 +60,8 @@ public:
|
|||
void set_case_first(StringView case_first);
|
||||
StringView case_first_string() const;
|
||||
|
||||
DeprecatedString const& collation() const { return m_collation; }
|
||||
void set_collation(DeprecatedString collation) { m_collation = move(collation); }
|
||||
String const& collation() const { return m_collation; }
|
||||
void set_collation(String collation) { m_collation = move(collation); }
|
||||
|
||||
bool ignore_punctuation() const { return m_ignore_punctuation; }
|
||||
void set_ignore_punctuation(bool ignore_punctuation) { m_ignore_punctuation = ignore_punctuation; }
|
||||
|
@ -77,11 +77,11 @@ private:
|
|||
|
||||
virtual void visit_edges(Visitor&) override;
|
||||
|
||||
DeprecatedString m_locale; // [[Locale]]
|
||||
String m_locale; // [[Locale]]
|
||||
Usage m_usage { Usage::Sort }; // [[Usage]]
|
||||
Sensitivity m_sensitivity { Sensitivity::Variant }; // [[Sensitivity]]
|
||||
CaseFirst m_case_first { CaseFirst::False }; // [[CaseFirst]]
|
||||
DeprecatedString m_collation; // [[Collation]]
|
||||
String m_collation; // [[Collation]]
|
||||
bool m_ignore_punctuation { false }; // [[IgnorePunctuation]]
|
||||
bool m_numeric { false }; // [[Numeric]]
|
||||
CollatorCompareFunction* m_bound_compare { nullptr }; // [[BoundCompare]]
|
||||
|
|
|
@ -53,7 +53,7 @@ static ThrowCompletionOr<Collator*> initialize_collator(VM& vm, Collator& collat
|
|||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, collation, "collation"sv);
|
||||
|
||||
// 12. Set opt.[[co]] to collation.
|
||||
opt.co = TRY(collation.as_string().deprecated_string());
|
||||
opt.co = TRY(collation.as_string().utf8_string());
|
||||
}
|
||||
|
||||
// 13. Let numeric be ? GetOption(options, "numeric", boolean, empty, undefined).
|
||||
|
@ -62,14 +62,16 @@ static ThrowCompletionOr<Collator*> initialize_collator(VM& vm, Collator& collat
|
|||
// 14. If numeric is not undefined, then
|
||||
// a. Let numeric be ! ToString(numeric).
|
||||
// 15. Set opt.[[kn]] to numeric.
|
||||
if (!numeric.is_undefined())
|
||||
opt.kn = MUST(numeric.to_deprecated_string(vm));
|
||||
if (!numeric.is_undefined()) {
|
||||
// NOTE: We TRY this operation only to propagate OOM errors.
|
||||
opt.kn = TRY(numeric.to_string(vm));
|
||||
}
|
||||
|
||||
// 16. Let caseFirst be ? GetOption(options, "caseFirst", string, « "upper", "lower", "false" », undefined).
|
||||
// 17. Set opt.[[kf]] to caseFirst.
|
||||
auto case_first = TRY(get_option(vm, *options, vm.names.caseFirst, OptionType::String, { "upper"sv, "lower"sv, "false"sv }, Empty {}));
|
||||
if (!case_first.is_undefined())
|
||||
opt.kf = TRY(case_first.as_string().deprecated_string());
|
||||
opt.kf = TRY(case_first.as_string().utf8_string());
|
||||
|
||||
// 18. Let relevantExtensionKeys be %Collator%.[[RelevantExtensionKeys]].
|
||||
auto relevant_extension_keys = Collator::relevant_extension_keys();
|
||||
|
@ -83,7 +85,7 @@ static ThrowCompletionOr<Collator*> initialize_collator(VM& vm, Collator& collat
|
|||
// 21. Let collation be r.[[co]].
|
||||
// 22. If collation is null, let collation be "default".
|
||||
// 23. Set collator.[[Collation]] to collation.
|
||||
collator.set_collation(result.co.has_value() ? result.co.release_value() : "default");
|
||||
collator.set_collation(result.co.has_value() ? result.co.release_value() : TRY_OR_THROW_OOM(vm, String::from_utf8("default"sv)));
|
||||
|
||||
// 24. If relevantExtensionKeys contains "kn", then
|
||||
if (relevant_extension_keys.span().contains_slow("kn"sv) && result.kn.has_value()) {
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <AK/Array.h>
|
||||
#include <AK/DeprecatedString.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/StringView.h>
|
||||
#include <AK/Time.h>
|
||||
#include <AK/Types.h>
|
||||
|
@ -43,17 +44,17 @@ public:
|
|||
|
||||
virtual ~DateTimeFormat() override = default;
|
||||
|
||||
DeprecatedString const& locale() const { return m_locale; }
|
||||
void set_locale(DeprecatedString locale) { m_locale = move(locale); }
|
||||
String const& locale() const { return m_locale; }
|
||||
void set_locale(String locale) { m_locale = move(locale); }
|
||||
|
||||
DeprecatedString const& data_locale() const { return m_data_locale; }
|
||||
void set_data_locale(DeprecatedString data_locale) { m_data_locale = move(data_locale); }
|
||||
String const& data_locale() const { return m_data_locale; }
|
||||
void set_data_locale(String data_locale) { m_data_locale = move(data_locale); }
|
||||
|
||||
DeprecatedString const& calendar() const { return m_calendar; }
|
||||
void set_calendar(DeprecatedString calendar) { m_calendar = move(calendar); }
|
||||
String const& calendar() const { return m_calendar; }
|
||||
void set_calendar(String calendar) { m_calendar = move(calendar); }
|
||||
|
||||
DeprecatedString const& numbering_system() const { return m_numbering_system; }
|
||||
void set_numbering_system(DeprecatedString numbering_system) { m_numbering_system = move(numbering_system); }
|
||||
String const& numbering_system() const { return m_numbering_system; }
|
||||
void set_numbering_system(String numbering_system) { m_numbering_system = move(numbering_system); }
|
||||
|
||||
bool has_hour_cycle() const { return m_hour_cycle.has_value(); }
|
||||
::Locale::HourCycle hour_cycle() const { return *m_hour_cycle; }
|
||||
|
@ -134,9 +135,9 @@ private:
|
|||
|
||||
virtual void visit_edges(Visitor&) override;
|
||||
|
||||
DeprecatedString m_locale; // [[Locale]]
|
||||
DeprecatedString m_calendar; // [[Calendar]]
|
||||
DeprecatedString m_numbering_system; // [[NumberingSystem]]
|
||||
String m_locale; // [[Locale]]
|
||||
String m_calendar; // [[Calendar]]
|
||||
String m_numbering_system; // [[NumberingSystem]]
|
||||
Optional<::Locale::HourCycle> m_hour_cycle; // [[HourCycle]]
|
||||
DeprecatedString m_time_zone; // [[TimeZone]]
|
||||
Optional<Style> m_date_style; // [[DateStyle]]
|
||||
|
@ -144,7 +145,7 @@ private:
|
|||
Vector<::Locale::CalendarRangePattern> m_range_patterns; // [[RangePatterns]]
|
||||
NativeFunction* m_bound_format { nullptr }; // [[BoundFormat]]
|
||||
|
||||
DeprecatedString m_data_locale;
|
||||
String m_data_locale;
|
||||
};
|
||||
|
||||
enum class OptionRequired {
|
||||
|
|
|
@ -110,7 +110,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM& vm, DateTimeF
|
|||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, calendar, "calendar"sv);
|
||||
|
||||
// 8. Set opt.[[ca]] to calendar.
|
||||
opt.ca = TRY(calendar.as_string().deprecated_string());
|
||||
opt.ca = TRY(calendar.as_string().utf8_string());
|
||||
}
|
||||
|
||||
// 9. Let numberingSystem be ? GetOption(options, "numberingSystem", string, empty, undefined).
|
||||
|
@ -123,7 +123,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM& vm, DateTimeF
|
|||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, numbering_system, "numberingSystem"sv);
|
||||
|
||||
// 11. Set opt.[[nu]] to numberingSystem.
|
||||
opt.nu = TRY(numbering_system.as_string().deprecated_string());
|
||||
opt.nu = TRY(numbering_system.as_string().utf8_string());
|
||||
}
|
||||
|
||||
// 12. Let hour12 be ? GetOption(options, "hour12", boolean, empty, undefined).
|
||||
|
@ -140,7 +140,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM& vm, DateTimeF
|
|||
|
||||
// 15. Set opt.[[hc]] to hourCycle.
|
||||
if (!hour_cycle.is_nullish())
|
||||
opt.hc = TRY(hour_cycle.as_string().deprecated_string());
|
||||
opt.hc = TRY(hour_cycle.as_string().utf8_string());
|
||||
|
||||
// 16. Let localeData be %DateTimeFormat%.[[LocaleData]].
|
||||
// 17. Let r be ResolveLocale(%DateTimeFormat%.[[AvailableLocales]], requestedLocales, opt, %DateTimeFormat%.[[RelevantExtensionKeys]], localeData).
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/DeprecatedString.h>
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/StringView.h>
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
#include <LibLocale/Locale.h>
|
||||
|
@ -41,8 +41,8 @@ class DisplayNames final : public Object {
|
|||
public:
|
||||
virtual ~DisplayNames() override = default;
|
||||
|
||||
DeprecatedString const& locale() const { return m_locale; }
|
||||
void set_locale(DeprecatedString locale) { m_locale = move(locale); }
|
||||
String const& locale() const { return m_locale; }
|
||||
void set_locale(String locale) { m_locale = move(locale); }
|
||||
|
||||
::Locale::Style style() const { return m_style; }
|
||||
void set_style(StringView style) { m_style = ::Locale::style_from_string(style); }
|
||||
|
@ -64,7 +64,7 @@ public:
|
|||
private:
|
||||
DisplayNames(Object& prototype);
|
||||
|
||||
DeprecatedString m_locale; // [[Locale]]
|
||||
String m_locale; // [[Locale]]
|
||||
::Locale::Style m_style { ::Locale::Style::Long }; // [[Style]]
|
||||
Type m_type { Type::Invalid }; // [[Type]]
|
||||
Fallback m_fallback { Fallback::Invalid }; // [[Fallback]]
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <AK/Array.h>
|
||||
#include <AK/DeprecatedString.h>
|
||||
#include <AK/String.h>
|
||||
#include <LibJS/Runtime/Intl/AbstractOperations.h>
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
#include <LibJS/Runtime/Temporal/Duration.h>
|
||||
|
@ -51,18 +52,18 @@ public:
|
|||
|
||||
virtual ~DurationFormat() override = default;
|
||||
|
||||
void set_locale(DeprecatedString locale) { m_locale = move(locale); }
|
||||
DeprecatedString const& locale() const { return m_locale; }
|
||||
void set_locale(String locale) { m_locale = move(locale); }
|
||||
String const& locale() const { return m_locale; }
|
||||
|
||||
void set_data_locale(DeprecatedString data_locale) { m_data_locale = move(data_locale); }
|
||||
DeprecatedString const& data_locale() const { return m_data_locale; }
|
||||
void set_data_locale(String data_locale) { m_data_locale = move(data_locale); }
|
||||
String const& data_locale() const { return m_data_locale; }
|
||||
|
||||
void set_numbering_system(DeprecatedString numbering_system) { m_numbering_system = move(numbering_system); }
|
||||
DeprecatedString const& numbering_system() const { return m_numbering_system; }
|
||||
void set_numbering_system(String numbering_system) { m_numbering_system = move(numbering_system); }
|
||||
String const& numbering_system() const { return m_numbering_system; }
|
||||
|
||||
void set_style(StringView style) { m_style = style_from_string(style); }
|
||||
Style style() const { return m_style; }
|
||||
DeprecatedString style_string() const { return style_to_string(m_style); }
|
||||
StringView style_string() const { return style_to_string(m_style); }
|
||||
|
||||
void set_years_style(StringView years_style) { m_years_style = date_style_from_string(years_style); }
|
||||
ValueStyle years_style() const { return m_years_style; }
|
||||
|
@ -160,9 +161,9 @@ private:
|
|||
static Display display_from_string(StringView display);
|
||||
static StringView display_to_string(Display);
|
||||
|
||||
DeprecatedString m_locale; // [[Locale]]
|
||||
DeprecatedString m_data_locale; // [[DataLocale]]
|
||||
DeprecatedString m_numbering_system; // [[NumberingSystem]]
|
||||
String m_locale; // [[Locale]]
|
||||
String m_data_locale; // [[DataLocale]]
|
||||
String m_numbering_system; // [[NumberingSystem]]
|
||||
Style m_style { Style::Long }; // [[Style]]
|
||||
ValueStyle m_years_style { ValueStyle::Long }; // [[YearsStyle]]
|
||||
Display m_years_display { Display::Auto }; // [[YearsDisplay]]
|
||||
|
|
|
@ -74,7 +74,7 @@ ThrowCompletionOr<NonnullGCPtr<Object>> DurationFormatConstructor::construct(Fun
|
|||
// 8. Let opt be the Record { [[localeMatcher]]: matcher, [[nu]]: numberingSystem }.
|
||||
LocaleOptions opt {};
|
||||
opt.locale_matcher = matcher;
|
||||
opt.nu = numbering_system.is_undefined() ? Optional<DeprecatedString>() : TRY(numbering_system.as_string().deprecated_string());
|
||||
opt.nu = numbering_system.is_undefined() ? Optional<String>() : TRY(numbering_system.as_string().utf8_string());
|
||||
|
||||
// 9. Let r be ResolveLocale(%DurationFormat%.[[AvailableLocales]], requestedLocales, opt, %DurationFormat%.[[RelevantExtensionKeys]], %DurationFormat%.[[LocaleData]]).
|
||||
auto result = TRY(resolve_locale(vm, requested_locales, opt, DurationFormat::relevant_extension_keys()));
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <AK/DeprecatedString.h>
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/StringView.h>
|
||||
#include <AK/Variant.h>
|
||||
#include <AK/Vector.h>
|
||||
|
@ -30,8 +31,8 @@ public:
|
|||
|
||||
virtual ~ListFormat() override = default;
|
||||
|
||||
DeprecatedString const& locale() const { return m_locale; }
|
||||
void set_locale(DeprecatedString locale) { m_locale = move(locale); }
|
||||
String const& locale() const { return m_locale; }
|
||||
void set_locale(String locale) { m_locale = move(locale); }
|
||||
|
||||
Type type() const { return m_type; }
|
||||
void set_type(StringView type);
|
||||
|
@ -44,7 +45,7 @@ public:
|
|||
private:
|
||||
explicit ListFormat(Object& prototype);
|
||||
|
||||
DeprecatedString m_locale; // [[Locale]]
|
||||
String m_locale; // [[Locale]]
|
||||
Type m_type { Type::Invalid }; // [[Type]]
|
||||
::Locale::Style m_style { ::Locale::Style::Long }; // [[Style]]
|
||||
};
|
||||
|
|
|
@ -14,9 +14,34 @@
|
|||
|
||||
namespace JS::Intl {
|
||||
|
||||
NonnullGCPtr<Locale> Locale::create(Realm& realm, ::Locale::LocaleID const& locale_id)
|
||||
ThrowCompletionOr<NonnullGCPtr<Locale>> Locale::create(Realm& realm, ::Locale::LocaleID locale_id)
|
||||
{
|
||||
return realm.heap().allocate<Locale>(realm, locale_id, *realm.intrinsics().intl_locale_prototype());
|
||||
auto locale = realm.heap().allocate<Locale>(realm, *realm.intrinsics().intl_locale_prototype());
|
||||
locale->set_locale(TRY_OR_THROW_OOM(realm.vm(), locale_id.to_string()));
|
||||
|
||||
for (auto& extension : locale_id.extensions) {
|
||||
if (!extension.has<::Locale::LocaleExtension>())
|
||||
continue;
|
||||
|
||||
for (auto& keyword : extension.get<::Locale::LocaleExtension>().keywords) {
|
||||
if (keyword.key == "ca"sv)
|
||||
locale->set_calendar(move(keyword.value));
|
||||
else if (keyword.key == "co"sv)
|
||||
locale->set_collation(move(keyword.value));
|
||||
else if (keyword.key == "hc"sv)
|
||||
locale->set_hour_cycle(move(keyword.value));
|
||||
else if (keyword.key == "kf"sv)
|
||||
locale->set_case_first(move(keyword.value));
|
||||
else if (keyword.key == "kn"sv)
|
||||
locale->set_numeric(keyword.value.is_empty());
|
||||
else if (keyword.key == "nu"sv)
|
||||
locale->set_numbering_system(move(keyword.value));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return locale;
|
||||
}
|
||||
|
||||
// 14 Locale Objects, https://tc39.es/ecma402/#locale-objects
|
||||
|
@ -25,37 +50,8 @@ Locale::Locale(Object& prototype)
|
|||
{
|
||||
}
|
||||
|
||||
Locale::Locale(::Locale::LocaleID const& locale_id, Object& prototype)
|
||||
: Object(ConstructWithPrototypeTag::Tag, prototype)
|
||||
{
|
||||
set_locale(locale_id.to_deprecated_string());
|
||||
|
||||
for (auto const& extension : locale_id.extensions) {
|
||||
if (!extension.has<::Locale::LocaleExtension>())
|
||||
continue;
|
||||
|
||||
for (auto const& keyword : extension.get<::Locale::LocaleExtension>().keywords) {
|
||||
if (keyword.key == "ca"sv) {
|
||||
set_calendar(keyword.value.to_deprecated_string());
|
||||
} else if (keyword.key == "co"sv) {
|
||||
set_collation(keyword.value.to_deprecated_string());
|
||||
} else if (keyword.key == "hc"sv) {
|
||||
set_hour_cycle(keyword.value.to_deprecated_string());
|
||||
} else if (keyword.key == "kf"sv) {
|
||||
set_case_first(keyword.value.to_deprecated_string());
|
||||
} else if (keyword.key == "kn"sv) {
|
||||
set_numeric(keyword.value.is_empty());
|
||||
} else if (keyword.key == "nu"sv) {
|
||||
set_numbering_system(keyword.value.to_deprecated_string());
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 1.1.1 CreateArrayFromListOrRestricted ( list , restricted )
|
||||
static Array* create_array_from_list_or_restricted(VM& vm, Vector<StringView> list, Optional<DeprecatedString> restricted)
|
||||
static Array* create_array_from_list_or_restricted(VM& vm, Vector<StringView> list, Optional<String> restricted)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
|
@ -75,7 +71,7 @@ static Array* create_array_from_list_or_restricted(VM& vm, Vector<StringView> li
|
|||
Array* calendars_of_locale(VM& vm, Locale const& locale_object)
|
||||
{
|
||||
// 1. Let restricted be loc.[[Calendar]].
|
||||
Optional<DeprecatedString> restricted = locale_object.has_calendar() ? locale_object.calendar() : Optional<DeprecatedString> {};
|
||||
Optional<String> restricted = locale_object.has_calendar() ? locale_object.calendar() : Optional<String> {};
|
||||
|
||||
// 2. Let locale be loc.[[Locale]].
|
||||
auto const& locale = locale_object.locale();
|
||||
|
@ -94,7 +90,7 @@ Array* calendars_of_locale(VM& vm, Locale const& locale_object)
|
|||
Array* collations_of_locale(VM& vm, Locale const& locale_object)
|
||||
{
|
||||
// 1. Let restricted be loc.[[Collation]].
|
||||
Optional<DeprecatedString> restricted = locale_object.has_collation() ? locale_object.collation() : Optional<DeprecatedString> {};
|
||||
Optional<String> restricted = locale_object.has_collation() ? locale_object.collation() : Optional<String> {};
|
||||
|
||||
// 2. Let locale be loc.[[Locale]].
|
||||
auto const& locale = locale_object.locale();
|
||||
|
@ -113,7 +109,7 @@ Array* collations_of_locale(VM& vm, Locale const& locale_object)
|
|||
Array* hour_cycles_of_locale(VM& vm, Locale const& locale_object)
|
||||
{
|
||||
// 1. Let restricted be loc.[[HourCycle]].
|
||||
Optional<DeprecatedString> restricted = locale_object.has_hour_cycle() ? locale_object.hour_cycle() : Optional<DeprecatedString> {};
|
||||
Optional<String> restricted = locale_object.has_hour_cycle() ? locale_object.hour_cycle() : Optional<String> {};
|
||||
|
||||
// 2. Let locale be loc.[[Locale]].
|
||||
auto const& locale = locale_object.locale();
|
||||
|
@ -132,7 +128,7 @@ Array* hour_cycles_of_locale(VM& vm, Locale const& locale_object)
|
|||
Array* numbering_systems_of_locale(VM& vm, Locale const& locale_object)
|
||||
{
|
||||
// 1. Let restricted be loc.[[NumberingSystem]].
|
||||
Optional<DeprecatedString> restricted = locale_object.has_numbering_system() ? locale_object.numbering_system() : Optional<DeprecatedString> {};
|
||||
Optional<String> restricted = locale_object.has_numbering_system() ? locale_object.numbering_system() : Optional<String> {};
|
||||
|
||||
// 2. Let locale be loc.[[Locale]].
|
||||
auto const& locale = locale_object.locale();
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/Array.h>
|
||||
#include <AK/DeprecatedString.h>
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibJS/Runtime/Completion.h>
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
|
@ -21,7 +21,7 @@ class Locale final : public Object {
|
|||
JS_OBJECT(Locale, Object);
|
||||
|
||||
public:
|
||||
static NonnullGCPtr<Locale> create(Realm&, ::Locale::LocaleID const&);
|
||||
static ThrowCompletionOr<NonnullGCPtr<Locale>> create(Realm&, ::Locale::LocaleID);
|
||||
|
||||
static constexpr auto relevant_extension_keys()
|
||||
{
|
||||
|
@ -36,43 +36,42 @@ public:
|
|||
|
||||
virtual ~Locale() override = default;
|
||||
|
||||
DeprecatedString const& locale() const { return m_locale; }
|
||||
void set_locale(DeprecatedString locale) { m_locale = move(locale); }
|
||||
String const& locale() const { return m_locale; }
|
||||
void set_locale(String locale) { m_locale = move(locale); }
|
||||
|
||||
bool has_calendar() const { return m_calendar.has_value(); }
|
||||
DeprecatedString const& calendar() const { return m_calendar.value(); }
|
||||
void set_calendar(DeprecatedString calendar) { m_calendar = move(calendar); }
|
||||
String const& calendar() const { return m_calendar.value(); }
|
||||
void set_calendar(String calendar) { m_calendar = move(calendar); }
|
||||
|
||||
bool has_case_first() const { return m_case_first.has_value(); }
|
||||
DeprecatedString const& case_first() const { return m_case_first.value(); }
|
||||
void set_case_first(DeprecatedString case_first) { m_case_first = move(case_first); }
|
||||
String const& case_first() const { return m_case_first.value(); }
|
||||
void set_case_first(String case_first) { m_case_first = move(case_first); }
|
||||
|
||||
bool has_collation() const { return m_collation.has_value(); }
|
||||
DeprecatedString const& collation() const { return m_collation.value(); }
|
||||
void set_collation(DeprecatedString collation) { m_collation = move(collation); }
|
||||
String const& collation() const { return m_collation.value(); }
|
||||
void set_collation(String collation) { m_collation = move(collation); }
|
||||
|
||||
bool has_hour_cycle() const { return m_hour_cycle.has_value(); }
|
||||
DeprecatedString const& hour_cycle() const { return m_hour_cycle.value(); }
|
||||
void set_hour_cycle(DeprecatedString hour_cycle) { m_hour_cycle = move(hour_cycle); }
|
||||
String const& hour_cycle() const { return m_hour_cycle.value(); }
|
||||
void set_hour_cycle(String hour_cycle) { m_hour_cycle = move(hour_cycle); }
|
||||
|
||||
bool has_numbering_system() const { return m_numbering_system.has_value(); }
|
||||
DeprecatedString const& numbering_system() const { return m_numbering_system.value(); }
|
||||
void set_numbering_system(DeprecatedString numbering_system) { m_numbering_system = move(numbering_system); }
|
||||
String const& numbering_system() const { return m_numbering_system.value(); }
|
||||
void set_numbering_system(String numbering_system) { m_numbering_system = move(numbering_system); }
|
||||
|
||||
bool numeric() const { return m_numeric; }
|
||||
void set_numeric(bool numeric) { m_numeric = numeric; }
|
||||
|
||||
private:
|
||||
explicit Locale(Object& prototype);
|
||||
Locale(::Locale::LocaleID const&, Object& prototype);
|
||||
|
||||
DeprecatedString m_locale; // [[Locale]]
|
||||
Optional<DeprecatedString> m_calendar; // [[Calendar]]
|
||||
Optional<DeprecatedString> m_case_first; // [[CaseFirst]]
|
||||
Optional<DeprecatedString> m_collation; // [[Collation]]
|
||||
Optional<DeprecatedString> m_hour_cycle; // [[HourCycle]]
|
||||
Optional<DeprecatedString> m_numbering_system; // [[NumberingSystem]]
|
||||
bool m_numeric { false }; // [[Numeric]]
|
||||
String m_locale; // [[Locale]]
|
||||
Optional<String> m_calendar; // [[Calendar]]
|
||||
Optional<String> m_case_first; // [[CaseFirst]]
|
||||
Optional<String> m_collation; // [[Collation]]
|
||||
Optional<String> m_hour_cycle; // [[HourCycle]]
|
||||
Optional<String> m_numbering_system; // [[NumberingSystem]]
|
||||
bool m_numeric { false }; // [[Numeric]]
|
||||
};
|
||||
|
||||
// Table 1: WeekInfo Record Fields, https://tc39.es/proposal-intl-locale-info/#table-locale-weekinfo-record
|
||||
|
|
|
@ -41,7 +41,7 @@ static ThrowCompletionOr<Optional<String>> get_string_option(VM& vm, Object cons
|
|||
}
|
||||
|
||||
// 14.1.2 ApplyOptionsToTag ( tag, options ), https://tc39.es/ecma402/#sec-apply-options-to-tag
|
||||
static ThrowCompletionOr<DeprecatedString> apply_options_to_tag(VM& vm, StringView tag, Object const& options)
|
||||
static ThrowCompletionOr<String> apply_options_to_tag(VM& vm, StringView tag, Object const& options)
|
||||
{
|
||||
// 1. Assert: Type(tag) is String.
|
||||
// 2. Assert: Type(options) is Object.
|
||||
|
@ -200,7 +200,7 @@ static ThrowCompletionOr<LocaleAndKeys> apply_unicode_extension_to_tag(VM& vm, S
|
|||
|
||||
// 7. Let locale be the String value that is tag with any Unicode locale extension sequences removed.
|
||||
locale_id->remove_extension_type<::Locale::LocaleExtension>();
|
||||
auto locale = locale_id->to_string().release_value_but_fixme_should_propagate_errors();
|
||||
auto locale = TRY_OR_THROW_OOM(vm, locale_id->to_string());
|
||||
|
||||
// 8. Let newExtension be a Unicode BCP 47 U Extension based on attributes and keywords.
|
||||
::Locale::LocaleExtension new_extension { move(attributes), move(keywords) };
|
||||
|
@ -208,7 +208,7 @@ static ThrowCompletionOr<LocaleAndKeys> apply_unicode_extension_to_tag(VM& vm, S
|
|||
// 9. If newExtension is not the empty String, then
|
||||
if (!new_extension.attributes.is_empty() || !new_extension.keywords.is_empty()) {
|
||||
// a. Let locale be ! InsertUnicodeExtensionAndCanonicalize(locale, newExtension).
|
||||
locale = TRY_OR_THROW_OOM(vm, String::from_deprecated_string(TRY(insert_unicode_extension_and_canonicalize(vm, locale_id.release_value(), move(new_extension)))));
|
||||
locale = TRY(insert_unicode_extension_and_canonicalize(vm, locale_id.release_value(), move(new_extension)));
|
||||
}
|
||||
|
||||
// 10. Set result.[[locale]] to locale.
|
||||
|
@ -262,7 +262,7 @@ ThrowCompletionOr<NonnullGCPtr<Object>> LocaleConstructor::construct(FunctionObj
|
|||
// 6. Let locale be ? OrdinaryCreateFromConstructor(NewTarget, "%Locale.prototype%", internalSlotsList).
|
||||
auto locale = TRY(ordinary_create_from_constructor<Locale>(vm, new_target, &Intrinsics::intl_locale_prototype));
|
||||
|
||||
DeprecatedString tag;
|
||||
String tag;
|
||||
|
||||
// 7. If Type(tag) is not String or Object, throw a TypeError exception.
|
||||
if (!tag_value.is_string() && !tag_value.is_object())
|
||||
|
@ -277,7 +277,7 @@ ThrowCompletionOr<NonnullGCPtr<Object>> LocaleConstructor::construct(FunctionObj
|
|||
// 9. Else,
|
||||
else {
|
||||
// a. Let tag be ? ToString(tag).
|
||||
tag = TRY(tag_value.to_deprecated_string(vm));
|
||||
tag = TRY(tag_value.to_string(vm));
|
||||
}
|
||||
|
||||
// 10. Set options to ? CoerceOptionsToObject(options).
|
||||
|
@ -328,28 +328,28 @@ ThrowCompletionOr<NonnullGCPtr<Object>> LocaleConstructor::construct(FunctionObj
|
|||
auto result = TRY(apply_unicode_extension_to_tag(vm, tag, move(opt), relevant_extension_keys));
|
||||
|
||||
// 30. Set locale.[[Locale]] to r.[[locale]].
|
||||
locale->set_locale(result.locale.to_deprecated_string());
|
||||
locale->set_locale(move(result.locale));
|
||||
// 31. Set locale.[[Calendar]] to r.[[ca]].
|
||||
if (result.ca.has_value())
|
||||
locale->set_calendar(result.ca->to_deprecated_string());
|
||||
locale->set_calendar(result.ca.release_value());
|
||||
// 32. Set locale.[[Collation]] to r.[[co]].
|
||||
if (result.co.has_value())
|
||||
locale->set_collation(result.co->to_deprecated_string());
|
||||
locale->set_collation(result.co.release_value());
|
||||
// 33. Set locale.[[HourCycle]] to r.[[hc]].
|
||||
if (result.hc.has_value())
|
||||
locale->set_hour_cycle(result.hc->to_deprecated_string());
|
||||
locale->set_hour_cycle(result.hc.release_value());
|
||||
|
||||
// 34. If relevantExtensionKeys contains "kf", then
|
||||
if (relevant_extension_keys.span().contains_slow("kf"sv)) {
|
||||
// a. Set locale.[[CaseFirst]] to r.[[kf]].
|
||||
if (result.kf.has_value())
|
||||
locale->set_case_first(result.kf->to_deprecated_string());
|
||||
locale->set_case_first(result.kf.release_value());
|
||||
}
|
||||
|
||||
// 35. If relevantExtensionKeys contains "kn", then
|
||||
if (relevant_extension_keys.span().contains_slow("kn"sv)) {
|
||||
// a. If SameValue(r.[[kn]], "true") is true or r.[[kn]] is the empty String, then
|
||||
if (result.kn.has_value() && (same_value(PrimitiveString::create(vm, *result.kn), PrimitiveString::create(vm, "true")) || result.kn->is_empty())) {
|
||||
if (result.kn.has_value() && (result.kn == "true"sv || result.kn->is_empty())) {
|
||||
// i. Set locale.[[Numeric]] to true.
|
||||
locale->set_numeric(true);
|
||||
}
|
||||
|
@ -362,7 +362,7 @@ ThrowCompletionOr<NonnullGCPtr<Object>> LocaleConstructor::construct(FunctionObj
|
|||
|
||||
// 36. Set locale.[[NumberingSystem]] to r.[[nu]].
|
||||
if (result.nu.has_value())
|
||||
locale->set_numbering_system(result.nu->to_deprecated_string());
|
||||
locale->set_numbering_system(result.nu.release_value());
|
||||
|
||||
// 37. Return locale.
|
||||
return locale;
|
||||
|
|
|
@ -69,7 +69,8 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::maximize)
|
|||
locale->language_id = maximal.release_value();
|
||||
|
||||
// 4. Return ! Construct(%Locale%, maximal).
|
||||
return Locale::create(realm, *locale);
|
||||
// NOTE: We TRY this operation only to propagate OOM errors.
|
||||
return TRY(Locale::create(realm, locale.release_value()));
|
||||
}
|
||||
|
||||
// 14.3.4 Intl.Locale.prototype.minimize ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.minimize
|
||||
|
@ -89,7 +90,8 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::minimize)
|
|||
locale->language_id = minimal.release_value();
|
||||
|
||||
// 4. Return ! Construct(%Locale%, minimal).
|
||||
return Locale::create(realm, *locale);
|
||||
// NOTE: We TRY this operation only to propagate OOM errors.
|
||||
return TRY(Locale::create(realm, locale.release_value()));
|
||||
}
|
||||
|
||||
// 14.3.5 Intl.Locale.prototype.toString ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.toString
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <AK/Array.h>
|
||||
#include <AK/DeprecatedString.h>
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/String.h>
|
||||
#include <LibJS/Runtime/Intl/AbstractOperations.h>
|
||||
#include <LibJS/Runtime/Intl/MathematicalValue.h>
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
|
@ -58,11 +59,11 @@ public:
|
|||
|
||||
virtual ~NumberFormatBase() override = default;
|
||||
|
||||
DeprecatedString const& locale() const { return m_locale; }
|
||||
void set_locale(DeprecatedString locale) { m_locale = move(locale); }
|
||||
String const& locale() const { return m_locale; }
|
||||
void set_locale(String locale) { m_locale = move(locale); }
|
||||
|
||||
DeprecatedString const& data_locale() const { return m_data_locale; }
|
||||
void set_data_locale(DeprecatedString data_locale) { m_data_locale = move(data_locale); }
|
||||
String const& data_locale() const { return m_data_locale; }
|
||||
void set_data_locale(String data_locale) { m_data_locale = move(data_locale); }
|
||||
|
||||
int min_integer_digits() const { return m_min_integer_digits; }
|
||||
void set_min_integer_digits(int min_integer_digits) { m_min_integer_digits = min_integer_digits; }
|
||||
|
@ -102,8 +103,8 @@ protected:
|
|||
explicit NumberFormatBase(Object& prototype);
|
||||
|
||||
private:
|
||||
DeprecatedString m_locale; // [[Locale]]
|
||||
DeprecatedString m_data_locale; // [[DataLocale]]
|
||||
String m_locale; // [[Locale]]
|
||||
String m_data_locale; // [[DataLocale]]
|
||||
int m_min_integer_digits { 0 }; // [[MinimumIntegerDigits]]
|
||||
Optional<int> m_min_fraction_digits {}; // [[MinimumFractionDigits]]
|
||||
Optional<int> m_max_fraction_digits {}; // [[MaximumFractionDigits]]
|
||||
|
@ -178,16 +179,16 @@ public:
|
|||
|
||||
virtual ~NumberFormat() override = default;
|
||||
|
||||
DeprecatedString const& numbering_system() const { return m_numbering_system; }
|
||||
void set_numbering_system(DeprecatedString numbering_system) { m_numbering_system = move(numbering_system); }
|
||||
String const& numbering_system() const { return m_numbering_system; }
|
||||
void set_numbering_system(String numbering_system) { m_numbering_system = move(numbering_system); }
|
||||
|
||||
Style style() const { return m_style; }
|
||||
StringView style_string() const;
|
||||
void set_style(StringView style);
|
||||
|
||||
bool has_currency() const { return m_currency.has_value(); }
|
||||
DeprecatedString const& currency() const { return m_currency.value(); }
|
||||
void set_currency(DeprecatedString currency) { m_currency = move(currency); }
|
||||
String const& currency() const { return m_currency.value(); }
|
||||
void set_currency(String currency) { m_currency = move(currency); }
|
||||
|
||||
bool has_currency_display() const { return m_currency_display.has_value(); }
|
||||
CurrencyDisplay currency_display() const { return *m_currency_display; }
|
||||
|
@ -201,8 +202,8 @@ public:
|
|||
void set_currency_sign(StringView set_currency_sign);
|
||||
|
||||
bool has_unit() const { return m_unit.has_value(); }
|
||||
DeprecatedString const& unit() const { return m_unit.value(); }
|
||||
void set_unit(DeprecatedString unit) { m_unit = move(unit); }
|
||||
String const& unit() const { return m_unit.value(); }
|
||||
void set_unit(String unit) { m_unit = move(unit); }
|
||||
|
||||
bool has_unit_display() const { return m_unit_display.has_value(); }
|
||||
::Locale::Style unit_display() const { return *m_unit_display; }
|
||||
|
@ -238,14 +239,14 @@ private:
|
|||
|
||||
virtual void visit_edges(Visitor&) override;
|
||||
|
||||
DeprecatedString m_locale; // [[Locale]]
|
||||
DeprecatedString m_data_locale; // [[DataLocale]]
|
||||
DeprecatedString m_numbering_system; // [[NumberingSystem]]
|
||||
String m_locale; // [[Locale]]
|
||||
String m_data_locale; // [[DataLocale]]
|
||||
String m_numbering_system; // [[NumberingSystem]]
|
||||
Style m_style { Style::Invalid }; // [[Style]]
|
||||
Optional<DeprecatedString> m_currency {}; // [[Currency]]
|
||||
Optional<String> m_currency {}; // [[Currency]]
|
||||
Optional<CurrencyDisplay> m_currency_display {}; // [[CurrencyDisplay]]
|
||||
Optional<CurrencySign> m_currency_sign {}; // [[CurrencySign]]
|
||||
Optional<DeprecatedString> m_unit {}; // [[Unit]]
|
||||
Optional<String> m_unit {}; // [[Unit]]
|
||||
Optional<::Locale::Style> m_unit_display {}; // [[UnitDisplay]]
|
||||
UseGrouping m_use_grouping { false }; // [[UseGrouping]]
|
||||
Notation m_notation { Notation::Invalid }; // [[Notation]]
|
||||
|
|
|
@ -107,7 +107,7 @@ ThrowCompletionOr<NumberFormat*> initialize_number_format(VM& vm, NumberFormat&
|
|||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, numbering_system, "numberingSystem"sv);
|
||||
|
||||
// 8. Set opt.[[nu]] to numberingSystem.
|
||||
opt.nu = TRY(numbering_system.as_string().deprecated_string());
|
||||
opt.nu = TRY(numbering_system.as_string().utf8_string());
|
||||
}
|
||||
|
||||
// 9. Let localeData be %NumberFormat%.[[LocaleData]].
|
||||
|
@ -454,7 +454,7 @@ ThrowCompletionOr<void> set_number_format_unit_options(VM& vm, NumberFormat& int
|
|||
// 14. If style is "currency", then
|
||||
if (intl_object.style() == NumberFormat::Style::Currency) {
|
||||
// a. Set intlObj.[[Currency]] to the ASCII-uppercase of currency.
|
||||
intl_object.set_currency(TRY(currency.as_string().deprecated_string()).to_uppercase());
|
||||
intl_object.set_currency(TRY_OR_THROW_OOM(vm, TRY(currency.as_string().utf8_string()).to_uppercase()));
|
||||
|
||||
// c. Set intlObj.[[CurrencyDisplay]] to currencyDisplay.
|
||||
intl_object.set_currency_display(TRY(currency_display.as_string().utf8_string_view()));
|
||||
|
@ -466,7 +466,7 @@ ThrowCompletionOr<void> set_number_format_unit_options(VM& vm, NumberFormat& int
|
|||
// 15. If style is "unit", then
|
||||
if (intl_object.style() == NumberFormat::Style::Unit) {
|
||||
// a. Set intlObj.[[Unit]] to unit.
|
||||
intl_object.set_unit(TRY(unit.as_string().utf8_string_view()));
|
||||
intl_object.set_unit(TRY(unit.as_string().utf8_string()));
|
||||
|
||||
// b. Set intlObj.[[UnitDisplay]] to unitDisplay.
|
||||
intl_object.set_unit_display(TRY(unit_display.as_string().utf8_string_view()));
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <AK/Array.h>
|
||||
#include <AK/DeprecatedString.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/StringView.h>
|
||||
#include <LibJS/Runtime/Completion.h>
|
||||
#include <LibJS/Runtime/Intl/AbstractOperations.h>
|
||||
|
@ -35,14 +36,14 @@ public:
|
|||
|
||||
virtual ~RelativeTimeFormat() override = default;
|
||||
|
||||
DeprecatedString const& locale() const { return m_locale; }
|
||||
void set_locale(DeprecatedString locale) { m_locale = move(locale); }
|
||||
String const& locale() const { return m_locale; }
|
||||
void set_locale(String locale) { m_locale = move(locale); }
|
||||
|
||||
DeprecatedString const& data_locale() const { return m_data_locale; }
|
||||
void set_data_locale(DeprecatedString data_locale) { m_data_locale = move(data_locale); }
|
||||
String const& data_locale() const { return m_data_locale; }
|
||||
void set_data_locale(String data_locale) { m_data_locale = move(data_locale); }
|
||||
|
||||
DeprecatedString const& numbering_system() const { return m_numbering_system; }
|
||||
void set_numbering_system(DeprecatedString numbering_system) { m_numbering_system = move(numbering_system); }
|
||||
String const& numbering_system() const { return m_numbering_system; }
|
||||
void set_numbering_system(String numbering_system) { m_numbering_system = move(numbering_system); }
|
||||
|
||||
::Locale::Style style() const { return m_style; }
|
||||
void set_style(StringView style) { m_style = ::Locale::style_from_string(style); }
|
||||
|
@ -63,9 +64,9 @@ private:
|
|||
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
||||
DeprecatedString m_locale; // [[Locale]]
|
||||
DeprecatedString m_data_locale; // [[DataLocale]]
|
||||
DeprecatedString m_numbering_system; // [[NumberingSystem]]
|
||||
String m_locale; // [[Locale]]
|
||||
String m_data_locale; // [[DataLocale]]
|
||||
String m_numbering_system; // [[NumberingSystem]]
|
||||
::Locale::Style m_style { ::Locale::Style::Long }; // [[Style]]
|
||||
Numeric m_numeric { Numeric::Always }; // [[Numeric]]
|
||||
NumberFormat* m_number_format { nullptr }; // [[NumberFormat]]
|
||||
|
|
|
@ -105,7 +105,7 @@ ThrowCompletionOr<RelativeTimeFormat*> initialize_relative_time_format(VM& vm, R
|
|||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, numbering_system, "numberingSystem"sv);
|
||||
|
||||
// 8. Set opt.[[nu]] to numberingSystem.
|
||||
opt.nu = TRY(numbering_system.as_string().deprecated_string());
|
||||
opt.nu = TRY(numbering_system.as_string().utf8_string());
|
||||
}
|
||||
|
||||
// 9. Let localeData be %RelativeTimeFormat%.[[LocaleData]].
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/DeprecatedString.h>
|
||||
#include <AK/String.h>
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
|
||||
namespace JS::Intl {
|
||||
|
@ -23,8 +23,8 @@ public:
|
|||
|
||||
virtual ~Segmenter() override = default;
|
||||
|
||||
DeprecatedString const& locale() const { return m_locale; }
|
||||
void set_locale(DeprecatedString locale) { m_locale = move(locale); }
|
||||
String const& locale() const { return m_locale; }
|
||||
void set_locale(String locale) { m_locale = move(locale); }
|
||||
|
||||
SegmenterGranularity segmenter_granularity() const { return m_segmenter_granularity; }
|
||||
void set_segmenter_granularity(StringView);
|
||||
|
@ -33,7 +33,7 @@ public:
|
|||
private:
|
||||
explicit Segmenter(Object& prototype);
|
||||
|
||||
DeprecatedString m_locale; // [[Locale]]
|
||||
String m_locale; // [[Locale]]
|
||||
SegmenterGranularity m_segmenter_granularity { SegmenterGranularity::Grapheme }; // [[SegmenterGranularity]]
|
||||
};
|
||||
|
||||
|
|
|
@ -901,7 +901,7 @@ static ThrowCompletionOr<String> transform_case(VM& vm, String const& string, Va
|
|||
|
||||
// 4. Let noExtensionsLocale be the String value that is requestedLocale with any Unicode locale extension sequences (6.2.1) removed.
|
||||
requested_locale->remove_extension_type<Locale::LocaleExtension>();
|
||||
auto no_extensions_locale = requested_locale->to_deprecated_string();
|
||||
auto no_extensions_locale = TRY_OR_THROW_OOM(vm, requested_locale->to_string());
|
||||
|
||||
// 5. Let availableLocales be a List with language tags that includes the languages for which the Unicode Character Database contains language sensitive case mappings. Implementations may add additional language tags if they support case mapping for additional locales.
|
||||
// 6. Let locale be ! BestAvailableLocale(availableLocales, noExtensionsLocale).
|
||||
|
|
Loading…
Add table
Reference in a new issue