mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-23 01:59:58 +00:00
parsedate解析月份,月份静态常量提取,优化时间解析
Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IAMPWY Signed-off-by: jiangmengyang <jiangmengyang3@huawei.com> Change-Id: Ib03f02d99d4de4742b0c3c89558fcef87a2ef188
This commit is contained in:
parent
76ae8ff357
commit
1119d6a746
@ -16,6 +16,10 @@
|
||||
#include "ecmascript/date_parse.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
const std::array<CString, MOUTH_PER_YEAR> DateParse::MONTH_NAME = {
|
||||
"jan", "feb", "mar", "apr", "may", "jun",
|
||||
"jul", "aug", "sep", "oct", "nov", "dec"
|
||||
};
|
||||
bool DateParse::ParseDateString(const char *str, int length, int *time)
|
||||
{
|
||||
StringReader reader(str, length);
|
||||
@ -327,12 +331,8 @@ DateParse::DateValueType DateParse::DateProxy::MatchKeyWord(const CString &str,
|
||||
*value = 1;
|
||||
return DATE_TIME_ZONE;
|
||||
}
|
||||
std::array<CString, MOUTH_PER_YEAR> monthName = {
|
||||
"jan", "feb", "mar", "apr", "may", "jun",
|
||||
"jul", "aug", "sep", "oct", "nov", "dec"
|
||||
};
|
||||
for (int i = 0; i < MOUTH_PER_YEAR; i++) {
|
||||
if (str == monthName[i]) {
|
||||
if (str == DateParse::MONTH_NAME[i]) {
|
||||
*value = i + 1;
|
||||
return DATE_MONTH;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
namespace panda::ecmascript {
|
||||
class DateParse {
|
||||
public:
|
||||
static const std::array<CString, MOUTH_PER_YEAR> MONTH_NAME;
|
||||
static bool ParseDateString(const char *str, int length, int *time);
|
||||
|
||||
private:
|
||||
|
@ -33,6 +33,34 @@ const std::map<CaseFirstOption, UColAttributeValue> JSCollator::uColAttributeVal
|
||||
{CaseFirstOption::FALSE_OPTION, UCOL_OFF},
|
||||
{CaseFirstOption::UNDEFINED, UCOL_OFF}
|
||||
};
|
||||
const std::vector<LocaleMatcherOption> JSCollator::LOCALE_MATCHER_OPTION = {
|
||||
LocaleMatcherOption::LOOKUP, LocaleMatcherOption::BEST_FIT
|
||||
};
|
||||
const std::vector<std::string> JSCollator::LOCALE_MATCHER_OPTION_NAME = {"lookup", "best fit"};
|
||||
|
||||
const std::vector<CaseFirstOption> JSCollator::CASE_FIRST_OPTION = {
|
||||
CaseFirstOption::UPPER, CaseFirstOption::LOWER, CaseFirstOption::FALSE_OPTION
|
||||
};
|
||||
const std::vector<std::string> JSCollator::CASE_FIRST_OPTION_NAME = {"upper", "lower", "false"};
|
||||
|
||||
const std::set<std::string> JSCollator::RELEVANT_EXTENSION_KEYS = {"co", "kn", "kf"};
|
||||
|
||||
const std::vector<SensitivityOption> JSCollator::SENSITIVITY_OPTION = {
|
||||
SensitivityOption::BASE, SensitivityOption::ACCENT,
|
||||
SensitivityOption::CASE, SensitivityOption::VARIANT
|
||||
};
|
||||
const std::vector<std::string> JSCollator::SENSITIVITY_OPTION_NAME = {"base", "accent", "case", "variant"};
|
||||
|
||||
const std::vector<UsageOption> JSCollator::USAGE_OPTION = {UsageOption::SORT, UsageOption::SEARCH};
|
||||
const std::vector<std::string> JSCollator::USAGE_OPTION_NAME = {"sort", "search"};
|
||||
|
||||
// All the available locales that are statically known to fulfill fast path conditions.
|
||||
const char* const JSCollator::FAST_LOCALE[] = {
|
||||
"en-US", "en", "fr", "es", "de", "pt", "it", "ca",
|
||||
"de-AT", "fi", "id", "id-ID", "ms", "nl", "pl", "ro",
|
||||
"sl", "sv", "sw", "vi", "en-DE", "en-GB",
|
||||
};
|
||||
|
||||
|
||||
JSHandle<TaggedArray> JSCollator::GetAvailableLocales(JSThread *thread, bool enableLocaleCache)
|
||||
{
|
||||
@ -99,7 +127,7 @@ JSHandle<JSCollator> JSCollator::InitializeCollator(JSThread *thread,
|
||||
}
|
||||
// 4. Let usage be ? GetOption(options, "usage", "string", « "sort", "search" », "sort").
|
||||
auto usage = JSLocale::GetOptionOfString<UsageOption>(thread, optionsObject, globalConst->GetHandledUsageString(),
|
||||
{UsageOption::SORT, UsageOption::SEARCH}, {"sort", "search"},
|
||||
JSCollator::USAGE_OPTION, JSCollator::USAGE_OPTION_NAME,
|
||||
UsageOption::SORT);
|
||||
RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSCollator, thread);
|
||||
collator->SetUsage(usage);
|
||||
@ -107,7 +135,7 @@ JSHandle<JSCollator> JSCollator::InitializeCollator(JSThread *thread,
|
||||
// 5. Let matcher be ? GetOption(options, "localeMatcher", "string", « "lookup", "best fit" », "best fit").
|
||||
auto matcher = JSLocale::GetOptionOfString<LocaleMatcherOption>(
|
||||
thread, optionsObject, globalConst->GetHandledLocaleMatcherString(),
|
||||
{LocaleMatcherOption::LOOKUP, LocaleMatcherOption::BEST_FIT}, {"lookup", "best fit"},
|
||||
JSCollator::LOCALE_MATCHER_OPTION, JSCollator::LOCALE_MATCHER_OPTION_NAME,
|
||||
LocaleMatcherOption::BEST_FIT);
|
||||
RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSCollator, thread);
|
||||
|
||||
@ -138,13 +166,12 @@ JSHandle<JSCollator> JSCollator::InitializeCollator(JSThread *thread,
|
||||
// 14. Let caseFirst be ? GetOption(options, "caseFirst", "string", « "upper", "lower", "false" », undefined).
|
||||
CaseFirstOption caseFirst = JSLocale::GetOptionOfString<CaseFirstOption>(
|
||||
thread, optionsObject, globalConst->GetHandledCaseFirstString(),
|
||||
{CaseFirstOption::UPPER, CaseFirstOption::LOWER, CaseFirstOption::FALSE_OPTION}, {"upper", "lower", "false"},
|
||||
JSCollator::CASE_FIRST_OPTION, JSCollator::CASE_FIRST_OPTION_NAME,
|
||||
CaseFirstOption::UNDEFINED);
|
||||
RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSCollator, thread);
|
||||
collator->SetCaseFirst(caseFirst);
|
||||
|
||||
// 16. Let relevantExtensionKeys be %Collator%.[[RelevantExtensionKeys]].
|
||||
std::set<std::string> relevantExtensionKeys = {"co", "kn", "kf"};
|
||||
|
||||
// 17. Let r be ResolveLocale(%Collator%.[[AvailableLocales]], requestedLocales, opt,
|
||||
// %Collator%.[[RelevantExtensionKeys]], localeData).
|
||||
@ -155,7 +182,7 @@ JSHandle<JSCollator> JSCollator::InitializeCollator(JSThread *thread,
|
||||
availableLocales = GetAvailableLocales(thread, enableLocaleCache);
|
||||
}
|
||||
ResolvedLocale r =
|
||||
JSLocale::ResolveLocale(thread, availableLocales, requestedLocales, matcher, relevantExtensionKeys);
|
||||
JSLocale::ResolveLocale(thread, availableLocales, requestedLocales, matcher, RELEVANT_EXTENSION_KEYS);
|
||||
RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSCollator, thread);
|
||||
icu::Locale icuLocale = r.localeData;
|
||||
JSHandle<EcmaString> localeStr = intl::LocaleHelper::ToLanguageTag(thread, icuLocale);
|
||||
@ -251,8 +278,8 @@ JSHandle<JSCollator> JSCollator::InitializeCollator(JSThread *thread,
|
||||
// undefined).
|
||||
SensitivityOption sensitivity = JSLocale::GetOptionOfString<SensitivityOption>(
|
||||
thread, optionsObject, globalConst->GetHandledSensitivityString(),
|
||||
{SensitivityOption::BASE, SensitivityOption::ACCENT, SensitivityOption::CASE, SensitivityOption::VARIANT},
|
||||
{"base", "accent", "case", "variant"}, SensitivityOption::UNDEFINED);
|
||||
JSCollator::SENSITIVITY_OPTION, JSCollator::SENSITIVITY_OPTION_NAME,
|
||||
SensitivityOption::UNDEFINED);
|
||||
RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSCollator, thread);
|
||||
// 25. If sensitivity is undefined, then
|
||||
// a. If usage is "sort", then
|
||||
@ -474,12 +501,6 @@ JSHandle<JSObject> JSCollator::ResolvedOptions(JSThread *thread, const JSHandle<
|
||||
CompareStringsOption JSCollator::CompareStringsOptionFor(JSThread* thread,
|
||||
JSHandle<JSTaggedValue> locales)
|
||||
{
|
||||
// All the available locales that are statically known to fulfill fast path conditions.
|
||||
static const char* const FAST_LOCALE[] = {
|
||||
"en-US", "en", "fr", "es", "de", "pt", "it", "ca",
|
||||
"de-AT", "fi", "id", "id-ID", "ms", "nl", "pl", "ro",
|
||||
"sl", "sv", "sw", "vi", "en-DE", "en-GB",
|
||||
};
|
||||
if (locales->IsUndefined()) {
|
||||
auto context = thread->GetCurrentEcmaContext();
|
||||
auto defaultCompareOption = context->GetDefaultCompareStringsOption();
|
||||
|
@ -35,6 +35,23 @@ public:
|
||||
|
||||
static const std::map<CaseFirstOption, UColAttributeValue> uColAttributeValueMap;
|
||||
|
||||
static const std::vector<LocaleMatcherOption> LOCALE_MATCHER_OPTION;
|
||||
static const std::vector<std::string> LOCALE_MATCHER_OPTION_NAME;
|
||||
|
||||
static const std::vector<CaseFirstOption> CASE_FIRST_OPTION;
|
||||
static const std::vector<std::string> CASE_FIRST_OPTION_NAME;
|
||||
|
||||
static const std::set<std::string> RELEVANT_EXTENSION_KEYS;
|
||||
|
||||
static const std::vector<SensitivityOption> SENSITIVITY_OPTION;
|
||||
static const std::vector<std::string> SENSITIVITY_OPTION_NAME;
|
||||
|
||||
static const std::vector<UsageOption> USAGE_OPTION;
|
||||
static const std::vector<std::string> USAGE_OPTION_NAME;
|
||||
|
||||
// All the available locales that are statically known to fulfill fast path conditions.
|
||||
static const char *const FAST_LOCALE[];
|
||||
|
||||
CAST_CHECK(JSCollator, IsJSCollator);
|
||||
|
||||
static constexpr size_t ICU_FIELD_OFFSET = JSObject::SIZE;
|
||||
|
@ -35,6 +35,41 @@
|
||||
#endif
|
||||
|
||||
namespace panda::ecmascript {
|
||||
|
||||
const std::vector<LocaleMatcherOption> JSDisplayNames::LOCALE_MATCHER_OPTION = {
|
||||
LocaleMatcherOption::LOOKUP, LocaleMatcherOption::BEST_FIT
|
||||
};
|
||||
const std::vector<std::string> JSDisplayNames::LOCALE_MATCHER_OPTION_NAME = {"lookup", "best fit"};
|
||||
|
||||
const std::vector<StyOption> JSDisplayNames::STY_OPTION = {
|
||||
StyOption::NARROW, StyOption::SHORT, StyOption::LONG
|
||||
};
|
||||
const std::vector<std::string> JSDisplayNames::STY_OPTION_NAME = {"narrow", "short", "long"};
|
||||
|
||||
const std::vector<TypednsOption> JSDisplayNames::TYPED_NS_OPTION = {
|
||||
TypednsOption::LANGUAGE, TypednsOption::REGION,
|
||||
TypednsOption::SCRIPT, TypednsOption::CURRENCY,
|
||||
TypednsOption::CALENDAR, TypednsOption::DATETIMEFIELD
|
||||
};
|
||||
const std::vector<std::string> JSDisplayNames::TYPED_NS_OPTION_NAME = {
|
||||
"language", "region", "script", "currency",
|
||||
"calendar", "dateTimeField"
|
||||
};
|
||||
|
||||
const std::vector<FallbackOption> JSDisplayNames::FALLBACK_OPTION = {
|
||||
FallbackOption::CODE, FallbackOption::NONE
|
||||
};
|
||||
const std::vector<std::string> JSDisplayNames::FALLBACK_OPTION_OPTION_NAME = {
|
||||
"code", "none"
|
||||
};
|
||||
|
||||
const std::vector<LanguageDisplayOption> JSDisplayNames::LANGUAGE_DISPLAY_OPTION = {
|
||||
LanguageDisplayOption::DIALECT, LanguageDisplayOption::STANDARD
|
||||
};
|
||||
const std::vector<std::string> JSDisplayNames::LANGUAGE_DISPLAY_OPTION_NAME = {
|
||||
"dialect", "standard"
|
||||
};
|
||||
|
||||
icu::LocaleDisplayNames *JSDisplayNames::GetIcuLocaleDisplayNames() const
|
||||
{
|
||||
ASSERT(GetIcuLDN().IsJSNativePointer());
|
||||
@ -125,8 +160,9 @@ JSHandle<JSDisplayNames> JSDisplayNames::InitializeDisplayNames(JSThread *thread
|
||||
// 8. Let matcher be ? GetOption(options, "localeMatcher", "string", « "lookup", "best fit" », "best fit").
|
||||
JSHandle<JSTaggedValue> property = globalConst->GetHandledLocaleMatcherString();
|
||||
auto matcher = JSLocale::GetOptionOfString<LocaleMatcherOption>(
|
||||
thread, optionsObject, property, {LocaleMatcherOption::LOOKUP, LocaleMatcherOption::BEST_FIT},
|
||||
{"lookup", "best fit"}, LocaleMatcherOption::BEST_FIT);
|
||||
thread, optionsObject, property,
|
||||
JSDisplayNames::LOCALE_MATCHER_OPTION, JSDisplayNames::LOCALE_MATCHER_OPTION_NAME,
|
||||
LocaleMatcherOption::BEST_FIT);
|
||||
RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSDisplayNames, thread);
|
||||
|
||||
// 10. Let r be ResolveLocale(%DisplayNames%.[[AvailableLocales]], requestedLocales, opt,
|
||||
@ -146,8 +182,8 @@ JSHandle<JSDisplayNames> JSDisplayNames::InitializeDisplayNames(JSThread *thread
|
||||
// 11. Let style be ? GetOption(options, "style", "string", « "narrow", "short", "long" », "long").
|
||||
property = globalConst->GetHandledStyleString();
|
||||
auto StyOpt = JSLocale::GetOptionOfString<StyOption>(thread, optionsObject, property,
|
||||
{StyOption::NARROW, StyOption::SHORT, StyOption::LONG},
|
||||
{"narrow", "short", "long"}, StyOption::LONG);
|
||||
JSDisplayNames::STY_OPTION, JSDisplayNames::STY_OPTION_NAME,
|
||||
StyOption::LONG);
|
||||
RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSDisplayNames, thread);
|
||||
|
||||
// 12. Set DisplayNames.[[Style]] to style.
|
||||
@ -157,12 +193,8 @@ JSHandle<JSDisplayNames> JSDisplayNames::InitializeDisplayNames(JSThread *thread
|
||||
// "undefined").
|
||||
property = globalConst->GetHandledTypeString();
|
||||
auto type = JSLocale::GetOptionOfString<TypednsOption>(thread, optionsObject, property,
|
||||
{TypednsOption::LANGUAGE, TypednsOption::REGION,
|
||||
TypednsOption::SCRIPT, TypednsOption::CURRENCY,
|
||||
TypednsOption::CALENDAR, TypednsOption::DATETIMEFIELD},
|
||||
{"language", "region", "script", "currency",
|
||||
"calendar", "dateTimeField"},
|
||||
TypednsOption::UNDEFINED);
|
||||
JSDisplayNames::TYPED_NS_OPTION, JSDisplayNames::TYPED_NS_OPTION_NAME,
|
||||
TypednsOption::UNDEFINED);
|
||||
RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSDisplayNames, thread);
|
||||
|
||||
// 14. If type is undefined, throw a TypeError exception.
|
||||
@ -176,8 +208,8 @@ JSHandle<JSDisplayNames> JSDisplayNames::InitializeDisplayNames(JSThread *thread
|
||||
// 16. Let fallback be ? GetOption(options, "fallback", "string", « "code", "none" », "code").
|
||||
property = globalConst->GetHandledFallbackString();
|
||||
auto fallback = JSLocale::GetOptionOfString<FallbackOption>(thread, optionsObject, property,
|
||||
{FallbackOption::CODE, FallbackOption::NONE},
|
||||
{"code", "none"}, FallbackOption::CODE);
|
||||
JSDisplayNames::FALLBACK_OPTION, JSDisplayNames::FALLBACK_OPTION_OPTION_NAME,
|
||||
FallbackOption::CODE);
|
||||
RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSDisplayNames, thread);
|
||||
|
||||
// 17. Set displayNames.[[Fallback]] to fallback.
|
||||
@ -186,8 +218,9 @@ JSHandle<JSDisplayNames> JSDisplayNames::InitializeDisplayNames(JSThread *thread
|
||||
// Let languageDisplay be ? GetOption(options, "languageDisplay", string, « "dialect", "standard" », "dialect").
|
||||
property = globalConst->GetHandledLanguageDisplayString();
|
||||
auto langDisplay = JSLocale::GetOptionOfString<LanguageDisplayOption>(
|
||||
thread, optionsObject, property, {LanguageDisplayOption::DIALECT, LanguageDisplayOption::STANDARD},
|
||||
{"dialect", "standard"}, LanguageDisplayOption::DIALECT);
|
||||
thread, optionsObject, property,
|
||||
JSDisplayNames::LANGUAGE_DISPLAY_OPTION,
|
||||
JSDisplayNames::LANGUAGE_DISPLAY_OPTION_NAME, LanguageDisplayOption::DIALECT);
|
||||
RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSDisplayNames, thread);
|
||||
displayNames->SetLanguageDisplay(langDisplay);
|
||||
|
||||
|
@ -63,6 +63,20 @@ enum class LanguageDisplayOption : uint8_t {
|
||||
|
||||
class JSDisplayNames : public JSObject {
|
||||
public:
|
||||
static const std::vector<LocaleMatcherOption> LOCALE_MATCHER_OPTION;
|
||||
static const std::vector<std::string> LOCALE_MATCHER_OPTION_NAME;
|
||||
|
||||
static const std::vector<StyOption> STY_OPTION;
|
||||
static const std::vector<std::string> STY_OPTION_NAME;
|
||||
|
||||
static const std::vector<TypednsOption> TYPED_NS_OPTION;
|
||||
static const std::vector<std::string> TYPED_NS_OPTION_NAME;
|
||||
|
||||
static const std::vector<FallbackOption> FALLBACK_OPTION;
|
||||
static const std::vector<std::string> FALLBACK_OPTION_OPTION_NAME;
|
||||
|
||||
static const std::vector<LanguageDisplayOption> LANGUAGE_DISPLAY_OPTION;
|
||||
static const std::vector<std::string> LANGUAGE_DISPLAY_OPTION_NAME;
|
||||
CAST_CHECK(JSDisplayNames, IsJSDisplayNames);
|
||||
|
||||
static constexpr size_t LOCALE_OFFSET = JSObject::SIZE;
|
||||
|
@ -34,7 +34,27 @@
|
||||
#endif
|
||||
|
||||
namespace panda::ecmascript {
|
||||
const std::string LATN_STRING = "latn";
|
||||
const std::string JSLocale::LATN_STRING = "latn";
|
||||
|
||||
const std::vector<LocaleMatcherOption> JSLocale::LOCALE_MATCHER_OPTION = {
|
||||
LocaleMatcherOption::LOOKUP, LocaleMatcherOption::BEST_FIT
|
||||
};
|
||||
const std::vector<std::string> JSLocale::LOCALE_MATCHER_OPTION_NAME = {
|
||||
"lookup", "best fit"
|
||||
};
|
||||
|
||||
const std::map<std::string, std::set<std::string>> JSLocale::LOCALE_MAP = {
|
||||
{"hc", {"h11", "h12", "h23", "h24"}},
|
||||
{"lb", {"strict", "normal", "loose"}},
|
||||
{"kn", {"true", "false"}},
|
||||
{"kf", {"upper", "lower", "false"}}
|
||||
};
|
||||
|
||||
const std::vector<std::string> JSLocale::HOUR_CYCLE = {"h11", "h12", "h23", "h24"};
|
||||
const std::vector<std::string> JSLocale::CASE_FIRST = {"upper", "lower", "false"};
|
||||
|
||||
const std::set<std::string> JSLocale::WELL_NUMBER_SYSTEM = {"native", "traditio", "finance"};
|
||||
const std::set<std::string> JSLocale::WELL_COLLATION = {"standard", "search"};
|
||||
// 6.4.1 IsValidTimeZoneName ( timeZone )
|
||||
bool JSLocale::IsValidTimeZoneName(const icu::TimeZone &tz)
|
||||
{
|
||||
@ -236,7 +256,7 @@ JSHandle<JSArray> JSLocale::SupportedLocales(JSThread *thread, const JSHandle<Ta
|
||||
|
||||
[[maybe_unused]] LocaleMatcherOption matcher = GetOptionOfString<LocaleMatcherOption>(thread,
|
||||
obj, globalConst->GetHandledLocaleMatcherString(),
|
||||
{LocaleMatcherOption::LOOKUP, LocaleMatcherOption::BEST_FIT}, {"lookup", "best fit"},
|
||||
JSLocale::LOCALE_MATCHER_OPTION, JSLocale::LOCALE_MATCHER_OPTION_NAME,
|
||||
LocaleMatcherOption::BEST_FIT);
|
||||
RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSArray, thread);
|
||||
}
|
||||
@ -445,13 +465,6 @@ ResolvedLocale JSLocale::ResolveLocale(JSThread *thread, const JSHandle<TaggedAr
|
||||
[[maybe_unused]] LocaleMatcherOption matcher,
|
||||
const std::set<std::string> &relevantExtensionKeys)
|
||||
{
|
||||
std::map<std::string, std::set<std::string>> localeMap = {
|
||||
{"hc", {"h11", "h12", "h23", "h24"}},
|
||||
{"lb", {"strict", "normal", "loose"}},
|
||||
{"kn", {"true", "false"}},
|
||||
{"kf", {"upper", "lower", "false"}}
|
||||
};
|
||||
|
||||
// 1. Let matcher be options.[[localeMatcher]].
|
||||
// 2. If matcher is "lookup" "lookup", then
|
||||
// a. Let r be LookupMatcher(availableLocales, requestedLocales).
|
||||
@ -497,9 +510,12 @@ ResolvedLocale JSLocale::ResolveLocale(JSThread *thread, const JSHandle<TaggedAr
|
||||
// c. Let keyLocaleData be foundLocaleData.[[<key>]].
|
||||
// e. Let value be keyLocaleData[0].
|
||||
if ((key != "ca") && (key != "co") && (key != "nu")) {
|
||||
keyLocaleData = localeMap[key];
|
||||
auto find = JSLocale::LOCALE_MAP.find(key);
|
||||
if (find != JSLocale::LOCALE_MAP.end()) {
|
||||
keyLocaleData = find->second;
|
||||
}
|
||||
if (key == "") {
|
||||
keyLocaleData = localeMap["lb"];
|
||||
keyLocaleData = JSLocale::LOCALE_MAP.at("lb");
|
||||
}
|
||||
value = *keyLocaleData.begin();
|
||||
}
|
||||
@ -627,7 +643,7 @@ std::string JSLocale::GetNumberingSystem(const icu::Locale &icuLocale)
|
||||
if (U_SUCCESS(status) != 0) {
|
||||
return numberingSystem->getName();
|
||||
}
|
||||
return LATN_STRING;
|
||||
return JSLocale::LATN_STRING;
|
||||
}
|
||||
|
||||
bool JSLocale::IsWellFormedCurrencyCode(const std::string ¤cy)
|
||||
@ -857,8 +873,6 @@ bool BuildOptionsTags(const JSHandle<EcmaString> &tag, icu::LocaleBuilder *build
|
||||
|
||||
bool InsertOptions(JSThread *thread, const JSHandle<JSObject> &options, icu::LocaleBuilder *builder)
|
||||
{
|
||||
const std::vector<std::string> hourCycleValues = {"h11", "h12", "h23", "h24"};
|
||||
const std::vector<std::string> caseFirstValues = {"upper", "lower", "false"};
|
||||
const std::vector<std::string> emptyValues = {};
|
||||
const GlobalEnvConstants *globalConst = thread->GlobalConstants();
|
||||
std::string strResult;
|
||||
@ -885,7 +899,7 @@ bool InsertOptions(JSThread *thread, const JSHandle<JSObject> &options, icu::Loc
|
||||
}
|
||||
|
||||
bool findhc = JSLocale::GetOptionOfString(thread, options, globalConst->GetHandledHourCycleString(),
|
||||
hourCycleValues, &strResult);
|
||||
JSLocale::HOUR_CYCLE, &strResult);
|
||||
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false);
|
||||
if (findhc) {
|
||||
if (!uloc_toLegacyType(uloc_toLegacyKey("hc"), strResult.c_str())) {
|
||||
@ -896,7 +910,7 @@ bool InsertOptions(JSThread *thread, const JSHandle<JSObject> &options, icu::Loc
|
||||
}
|
||||
|
||||
bool findkf = JSLocale::GetOptionOfString(thread, options, globalConst->GetHandledCaseFirstString(),
|
||||
caseFirstValues, &strResult);
|
||||
JSLocale::CASE_FIRST, &strResult);
|
||||
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false);
|
||||
if (findkf) {
|
||||
if (!uloc_toLegacyType(uloc_toLegacyKey("kf"), strResult.c_str())) {
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "unicode/uversion.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
|
||||
enum class OptionType : uint8_t { STRING = 0x01, BOOLEAN };
|
||||
enum class LocaleMatcherOption : uint8_t { LOOKUP = 0x01, BEST_FIT, EXCEPTION };
|
||||
enum class FormatMatcherOption : uint8_t { BASIC = 0x01, BEST_FIT, EXCEPTION };
|
||||
@ -148,6 +149,18 @@ struct TagElements {
|
||||
|
||||
class JSLocale : public JSObject {
|
||||
public:
|
||||
static const std::set<std::string> WELL_NUMBER_SYSTEM;
|
||||
static const std::set<std::string> WELL_COLLATION;
|
||||
|
||||
static const std::string LATN_STRING;
|
||||
|
||||
static const std::vector<LocaleMatcherOption> LOCALE_MATCHER_OPTION;
|
||||
static const std::vector<std::string> LOCALE_MATCHER_OPTION_NAME;
|
||||
|
||||
static const std::map<std::string, std::set<std::string>> LOCALE_MAP;
|
||||
|
||||
static const std::vector<std::string> HOUR_CYCLE;
|
||||
static const std::vector<std::string> CASE_FIRST;
|
||||
static JSLocale *Cast(TaggedObject *object)
|
||||
{
|
||||
ASSERT(JSTaggedValue(object).IsJSLocale());
|
||||
@ -321,8 +334,7 @@ public:
|
||||
|
||||
static bool IsWellNumberingSystem(const std::string &value)
|
||||
{
|
||||
std::set<std::string> irregularList = {"native", "traditio", "finance"};
|
||||
if (irregularList.find(value) != irregularList.end()) {
|
||||
if (JSLocale::WELL_NUMBER_SYSTEM.find(value) != JSLocale::WELL_NUMBER_SYSTEM.end()) {
|
||||
return false;
|
||||
}
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
@ -335,8 +347,7 @@ public:
|
||||
|
||||
static bool IsWellCollation(const icu::Locale &locale, const std::string &value)
|
||||
{
|
||||
std::set<std::string> irregularList = {"standard", "search"};
|
||||
if (irregularList.find(value) != irregularList.end()) {
|
||||
if (JSLocale::WELL_COLLATION.find(value) != JSLocale::WELL_COLLATION.end()) {
|
||||
return false;
|
||||
}
|
||||
return IsWellExtension<icu::Collator>(locale, "collation", value);
|
||||
|
@ -19,8 +19,57 @@
|
||||
#include "ecmascript/object_factory-inl.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
constexpr uint32_t DEFAULT_FRACTION_DIGITS = 2;
|
||||
constexpr uint32_t PERUNIT_STRING = 5;
|
||||
|
||||
const std::vector<StyleOption> JSNumberFormat::STYLE_OPTION = {
|
||||
StyleOption::DECIMAL, StyleOption::PERCENT, StyleOption::CURRENCY, StyleOption::UNIT
|
||||
};
|
||||
const std::vector<std::string> JSNumberFormat::STYLE_OPTION_NAME = {
|
||||
"decimal", "percent", "currency", "unit"
|
||||
};
|
||||
|
||||
const std::vector<CurrencyDisplayOption> JSNumberFormat::CURRENCY_DISPLAY_OPTION = {
|
||||
CurrencyDisplayOption::CODE, CurrencyDisplayOption::SYMBOL,
|
||||
CurrencyDisplayOption::NARROWSYMBOL, CurrencyDisplayOption::NAME
|
||||
};
|
||||
const std::vector<std::string> JSNumberFormat::CURRENCY_DISPLAY_OPTION_NAME = {
|
||||
"code", "symbol", "narrowSymbol", "name"
|
||||
};
|
||||
|
||||
const std::vector<CurrencySignOption> JSNumberFormat::CURRENCY_SIGN_OPTION = {
|
||||
CurrencySignOption::STANDARD, CurrencySignOption::ACCOUNTING
|
||||
};
|
||||
const std::vector<std::string> JSNumberFormat::CURRENCY_SIGN_OPTION_NAME = {"standard", "accounting"};
|
||||
|
||||
const std::vector<UnitDisplayOption> JSNumberFormat::UNIT_DISPLAY_OPTION = {
|
||||
UnitDisplayOption::SHORT, UnitDisplayOption::NARROW, UnitDisplayOption::LONG
|
||||
};
|
||||
const std::vector<std::string> JSNumberFormat::UNIT_DISPLAY_OPTION_NAME = {"short", "narrow", "long"};
|
||||
|
||||
const std::vector<LocaleMatcherOption> JSNumberFormat::LOCALE_MATCHER_OPTION = {
|
||||
LocaleMatcherOption::LOOKUP, LocaleMatcherOption::BEST_FIT
|
||||
};
|
||||
const std::vector<std::string> JSNumberFormat::LOCALE_MATCHER_OPTION_NAME = {"lookup", "best fit"};
|
||||
|
||||
const std::vector<NotationOption> JSNumberFormat::NOTATION_OPTION = {
|
||||
NotationOption::STANDARD, NotationOption::SCIENTIFIC,
|
||||
NotationOption::ENGINEERING, NotationOption::COMPACT
|
||||
};
|
||||
const std::vector<std::string> JSNumberFormat::NOTATION_OPTION_NAME = {
|
||||
"standard", "scientific", "engineering", "compact"
|
||||
};
|
||||
|
||||
const std::vector<SignDisplayOption> JSNumberFormat::SIGN_DISPLAY_OPTION = {
|
||||
SignDisplayOption::AUTO, SignDisplayOption::NEVER,
|
||||
SignDisplayOption::ALWAYS, SignDisplayOption::EXCEPTZERO
|
||||
};
|
||||
const std::vector<std::string> JSNumberFormat::SIGN_DISPLAY_OPTION_NAME = {
|
||||
"auto", "never", "always", "exceptZero"
|
||||
};
|
||||
|
||||
const std::vector<CompactDisplayOption> JSNumberFormat::COMPACT_DISPLAY_OPTION = {
|
||||
CompactDisplayOption::SHORT, CompactDisplayOption::LONG
|
||||
};
|
||||
const std::vector<std::string> JSNumberFormat::COMPACT_DISPLAY_OPTION_NAME = {"short", "long"};
|
||||
|
||||
JSHandle<JSTaggedValue> OptionToEcmaString(JSThread *thread, StyleOption style)
|
||||
{
|
||||
@ -225,7 +274,7 @@ bool IsWellFormedUnitIdentifier(const std::string &unit, icu::MeasureUnit &icuUn
|
||||
|
||||
// 2. If the substring "-per-" does not occur exactly once in unitIdentifier,
|
||||
// a. then false
|
||||
size_t afterPos = pos + PERUNIT_STRING;
|
||||
size_t afterPos = pos + JSNumberFormat::PERUNIT_STRING;
|
||||
if (pos == std::string::npos || unit.find("-per-", afterPos) != std::string::npos) {
|
||||
return false;
|
||||
}
|
||||
@ -241,7 +290,7 @@ bool IsWellFormedUnitIdentifier(const std::string &unit, icu::MeasureUnit &icuUn
|
||||
}
|
||||
|
||||
// 5. Let denominator be the substring of unitIdentifier from just after "-per-" to the end.
|
||||
std::string denominator = unit.substr(pos + PERUNIT_STRING);
|
||||
std::string denominator = unit.substr(pos + JSNumberFormat::PERUNIT_STRING);
|
||||
|
||||
// 6. If the result of IsSanctionedUnitIdentifier(denominator) is false, then
|
||||
// a. Return false
|
||||
@ -270,8 +319,8 @@ FractionDigitsOption SetNumberFormatUnitOptions(JSThread *thread,
|
||||
JSHandle<JSTaggedValue> property = globalConst->GetHandledStyleString();
|
||||
auto style = JSLocale::GetOptionOfString<StyleOption>(
|
||||
thread, optionsObject, property,
|
||||
{StyleOption::DECIMAL, StyleOption::PERCENT, StyleOption::CURRENCY, StyleOption::UNIT},
|
||||
{"decimal", "percent", "currency", "unit"}, StyleOption::DECIMAL);
|
||||
JSNumberFormat::STYLE_OPTION, JSNumberFormat::STYLE_OPTION_NAME,
|
||||
StyleOption::DECIMAL);
|
||||
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, fractionDigitsOption);
|
||||
|
||||
// 4. Set intlObj.[[Style]] to style.
|
||||
@ -307,17 +356,17 @@ FractionDigitsOption SetNumberFormatUnitOptions(JSThread *thread,
|
||||
property = globalConst->GetHandledCurrencyDisplayString();
|
||||
auto currencyDisplay = JSLocale::GetOptionOfString<CurrencyDisplayOption>(
|
||||
thread, optionsObject, property,
|
||||
{CurrencyDisplayOption::CODE, CurrencyDisplayOption::SYMBOL, CurrencyDisplayOption::NARROWSYMBOL,
|
||||
CurrencyDisplayOption::NAME},
|
||||
{"code", "symbol", "narrowSymbol", "name"}, CurrencyDisplayOption::SYMBOL);
|
||||
JSNumberFormat::CURRENCY_DISPLAY_OPTION, JSNumberFormat::CURRENCY_DISPLAY_OPTION_NAME,
|
||||
CurrencyDisplayOption::SYMBOL);
|
||||
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, fractionDigitsOption);
|
||||
numberFormat->SetCurrencyDisplay(currencyDisplay);
|
||||
|
||||
// 9. Let currencySign be ? GetOption(options, "currencySign", "string", « "standard", "accounting" », "standard").
|
||||
property = globalConst->GetHandledCurrencySignString();
|
||||
auto currencySign = JSLocale::GetOptionOfString<CurrencySignOption>(
|
||||
thread, optionsObject, property, {CurrencySignOption::STANDARD, CurrencySignOption::ACCOUNTING},
|
||||
{"standard", "accounting"}, CurrencySignOption::STANDARD);
|
||||
thread, optionsObject, property,
|
||||
JSNumberFormat::CURRENCY_SIGN_OPTION, JSNumberFormat::CURRENCY_SIGN_OPTION_NAME,
|
||||
CurrencySignOption::STANDARD);
|
||||
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, fractionDigitsOption);
|
||||
numberFormat->SetCurrencySign(currencySign);
|
||||
|
||||
@ -351,8 +400,9 @@ FractionDigitsOption SetNumberFormatUnitOptions(JSThread *thread,
|
||||
// 13. Let unitDisplay be ? GetOption(options, "unitDisplay", "string", « "short", "narrow", "long" », "short").
|
||||
property = globalConst->GetHandledUnitDisplayString();
|
||||
auto unitDisplay = JSLocale::GetOptionOfString<UnitDisplayOption>(
|
||||
thread, optionsObject, property, {UnitDisplayOption::SHORT, UnitDisplayOption::NARROW, UnitDisplayOption::LONG},
|
||||
{"short", "narrow", "long"}, UnitDisplayOption::SHORT);
|
||||
thread, optionsObject, property,
|
||||
JSNumberFormat::UNIT_DISPLAY_OPTION, JSNumberFormat::UNIT_DISPLAY_OPTION_NAME,
|
||||
UnitDisplayOption::SHORT);
|
||||
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, fractionDigitsOption);
|
||||
numberFormat->SetUnitDisplay(unitDisplay);
|
||||
|
||||
@ -463,8 +513,9 @@ void JSNumberFormat::InitializeNumberFormat(JSThread *thread, const JSHandle<JSN
|
||||
// 5. Let matcher be ? GetOption(options, "localeMatcher", "string", « "lookup", "best fit" », "best fit").
|
||||
JSHandle<JSTaggedValue> property = globalConst->GetHandledLocaleMatcherString();
|
||||
auto matcher = JSLocale::GetOptionOfString<LocaleMatcherOption>(
|
||||
thread, optionsObject, property, {LocaleMatcherOption::LOOKUP, LocaleMatcherOption::BEST_FIT},
|
||||
{"lookup", "best fit"}, LocaleMatcherOption::BEST_FIT);
|
||||
thread, optionsObject, property,
|
||||
JSNumberFormat::LOCALE_MATCHER_OPTION, JSNumberFormat::LOCALE_MATCHER_OPTION_NAME,
|
||||
LocaleMatcherOption::BEST_FIT);
|
||||
RETURN_IF_ABRUPT_COMPLETION(thread);
|
||||
|
||||
// 7. Let numberingSystem be ? GetOption(options, "numberingSystem", "string", undefined, undefined).
|
||||
@ -569,8 +620,8 @@ void JSNumberFormat::InitializeNumberFormat(JSThread *thread, const JSHandle<JSN
|
||||
property = globalConst->GetHandledNotationString();
|
||||
auto notation = JSLocale::GetOptionOfString<NotationOption>(
|
||||
thread, optionsObject, property,
|
||||
{NotationOption::STANDARD, NotationOption::SCIENTIFIC, NotationOption::ENGINEERING, NotationOption::COMPACT},
|
||||
{"standard", "scientific", "engineering", "compact"}, NotationOption::STANDARD);
|
||||
JSNumberFormat::NOTATION_OPTION, JSNumberFormat::NOTATION_OPTION_NAME,
|
||||
NotationOption::STANDARD);
|
||||
RETURN_IF_ABRUPT_COMPLETION(thread);
|
||||
numberFormat->SetNotation(notation);
|
||||
|
||||
@ -583,7 +634,8 @@ void JSNumberFormat::InitializeNumberFormat(JSThread *thread, const JSHandle<JSN
|
||||
// 22. Let compactDisplay be ? GetOptionOfString(options, "compactDisplay", "string", « "short", "long" », "short").
|
||||
property = globalConst->GetHandledCompactDisplayString();
|
||||
auto compactDisplay = JSLocale::GetOptionOfString<CompactDisplayOption>(
|
||||
thread, optionsObject, property, {CompactDisplayOption::SHORT, CompactDisplayOption::LONG}, {"short", "long"},
|
||||
thread, optionsObject, property,
|
||||
JSNumberFormat::COMPACT_DISPLAY_OPTION, JSNumberFormat::COMPACT_DISPLAY_OPTION_NAME,
|
||||
CompactDisplayOption::SHORT);
|
||||
numberFormat->SetCompactDisplay(compactDisplay);
|
||||
|
||||
@ -632,8 +684,8 @@ void JSNumberFormat::InitializeNumberFormat(JSThread *thread, const JSHandle<JSN
|
||||
property = globalConst->GetHandledSignDisplayString();
|
||||
auto signDisplay = JSLocale::GetOptionOfString<SignDisplayOption>(
|
||||
thread, optionsObject, property,
|
||||
{SignDisplayOption::AUTO, SignDisplayOption::NEVER, SignDisplayOption::ALWAYS, SignDisplayOption::EXCEPTZERO},
|
||||
{"auto", "never", "always", "exceptZero"}, SignDisplayOption::AUTO);
|
||||
JSNumberFormat::SIGN_DISPLAY_OPTION, JSNumberFormat::SIGN_DISPLAY_OPTION_NAME,
|
||||
SignDisplayOption::AUTO);
|
||||
RETURN_IF_ABRUPT_COMPLETION(thread);
|
||||
numberFormat->SetSignDisplay(signDisplay);
|
||||
|
||||
@ -701,7 +753,7 @@ int32_t JSNumberFormat::CurrencyDigits(const icu::UnicodeString ¤cy)
|
||||
if (U_SUCCESS(status)) {
|
||||
return fractionDigits;
|
||||
}
|
||||
return DEFAULT_FRACTION_DIGITS;
|
||||
return JSNumberFormat::DEFAULT_FRACTION_DIGITS;
|
||||
}
|
||||
|
||||
icu::number::LocalizedNumberFormatter *JSNumberFormat::GetCachedIcuNumberFormatter(JSThread *thread,
|
||||
|
@ -52,6 +52,31 @@ static const std::set<std::string> SANCTIONED_UNIT({ "acre", "bit", "byte", "cel
|
||||
|
||||
class JSNumberFormat : public JSObject {
|
||||
public:
|
||||
static constexpr uint32_t DEFAULT_FRACTION_DIGITS = 2;
|
||||
static constexpr uint32_t PERUNIT_STRING = 5;
|
||||
static const std::vector<StyleOption> STYLE_OPTION;
|
||||
static const std::vector<std::string> STYLE_OPTION_NAME;
|
||||
|
||||
static const std::vector<CurrencyDisplayOption> CURRENCY_DISPLAY_OPTION;
|
||||
static const std::vector<std::string> CURRENCY_DISPLAY_OPTION_NAME;
|
||||
|
||||
static const std::vector<CurrencySignOption> CURRENCY_SIGN_OPTION;
|
||||
static const std::vector<std::string> CURRENCY_SIGN_OPTION_NAME;
|
||||
|
||||
static const std::vector<UnitDisplayOption> UNIT_DISPLAY_OPTION;
|
||||
static const std::vector<std::string> UNIT_DISPLAY_OPTION_NAME;
|
||||
|
||||
static const std::vector<LocaleMatcherOption> LOCALE_MATCHER_OPTION;
|
||||
static const std::vector<std::string> LOCALE_MATCHER_OPTION_NAME;
|
||||
|
||||
static const std::vector<NotationOption> NOTATION_OPTION;
|
||||
static const std::vector<std::string> NOTATION_OPTION_NAME;
|
||||
|
||||
static const std::vector<SignDisplayOption> SIGN_DISPLAY_OPTION;
|
||||
static const std::vector<std::string> SIGN_DISPLAY_OPTION_NAME;
|
||||
|
||||
static const std::vector<CompactDisplayOption> COMPACT_DISPLAY_OPTION;
|
||||
static const std::vector<std::string> COMPACT_DISPLAY_OPTION_NAME;
|
||||
CAST_CHECK(JSNumberFormat, IsJSNumberFormat);
|
||||
|
||||
static constexpr size_t LOCALE_OFFSET = JSObject::SIZE;
|
||||
|
Loading…
Reference in New Issue
Block a user