mirror of
https://github.com/Samsung/escargot.git
synced 2026-06-22 10:01:50 +00:00
Implement more options to Intl.PluralRules
Signed-off-by: Seonghyun Kim <sh8281.kim@samsung.com>
This commit is contained in:
parent
a264ee2026
commit
b2ecf54887
9 changed files with 337 additions and 283 deletions
|
|
@ -540,7 +540,7 @@ static Value builtinIntlPluralRulesSelect(ExecutionState& state, Value thisValue
|
|||
// Let n be ? ToNumber(value).
|
||||
double n = argv[0].toNumber(state);
|
||||
// Return ? ResolvePlural(pr, n).
|
||||
return thisValue.asObject()->asIntlPluralRulesObject()->asIntlPluralRulesObject()->resolvePlural(n);
|
||||
return thisValue.asObject()->asIntlPluralRulesObject()->asIntlPluralRulesObject()->resolvePlural(state, n);
|
||||
}
|
||||
|
||||
static Value builtinIntlPluralRulesResolvedOptions(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
|
||||
|
|
@ -562,19 +562,19 @@ static Value builtinIntlPluralRulesResolvedOptions(ExecutionState& state, Value
|
|||
// If v is not undefined, then
|
||||
// Perform ! CreateDataPropertyOrThrow(options, p, v).
|
||||
|
||||
|
||||
options->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().lazySmallLetterLocale()), ObjectPropertyDescriptor(pr->locale(), ObjectPropertyDescriptor::AllPresent));
|
||||
options->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().lazyType()), ObjectPropertyDescriptor(pr->type(), ObjectPropertyDescriptor::AllPresent));
|
||||
options->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().lazyNotation()), ObjectPropertyDescriptor(pr->notation(), ObjectPropertyDescriptor::AllPresent));
|
||||
options->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().lazyMinimumIntegerDigits()), ObjectPropertyDescriptor(Value(Value::DoubleToIntConvertibleTestNeeds, pr->minimumIntegerDigits()), ObjectPropertyDescriptor::AllPresent));
|
||||
|
||||
if (pr->minimumSignificantDigits()) {
|
||||
options->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().lazyMinimumSignificantDigits()), ObjectPropertyDescriptor(Value(Value::DoubleToIntConvertibleTestNeeds, pr->minimumSignificantDigits().value()), ObjectPropertyDescriptor::AllPresent));
|
||||
options->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().lazyMaximumSignificantDigits()), ObjectPropertyDescriptor(Value(Value::DoubleToIntConvertibleTestNeeds, pr->maximumSignificantDigits().value()), ObjectPropertyDescriptor::AllPresent));
|
||||
} else {
|
||||
options->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().lazyMinimumFractionDigits()), ObjectPropertyDescriptor(Value(Value::DoubleToIntConvertibleTestNeeds, pr->minimumFractionDigits()), ObjectPropertyDescriptor::AllPresent));
|
||||
options->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().lazyMaximumFractionDigits()), ObjectPropertyDescriptor(Value(Value::DoubleToIntConvertibleTestNeeds, pr->maximumFractionDigits()), ObjectPropertyDescriptor::AllPresent));
|
||||
if (!pr->minimumSignificantDigits().isUndefined()) {
|
||||
options->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().lazyMinimumSignificantDigits()), ObjectPropertyDescriptor(pr->minimumSignificantDigits(), ObjectPropertyDescriptor::AllPresent));
|
||||
options->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().lazyMaximumSignificantDigits()), ObjectPropertyDescriptor(pr->maximumSignificantDigits(), ObjectPropertyDescriptor::AllPresent));
|
||||
}
|
||||
if (!pr->minimumFractionDigits().isUndefined()) {
|
||||
options->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().lazyMinimumFractionDigits()), ObjectPropertyDescriptor(pr->minimumFractionDigits(), ObjectPropertyDescriptor::AllPresent));
|
||||
options->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().lazyMaximumFractionDigits()), ObjectPropertyDescriptor(pr->maximumFractionDigits(), ObjectPropertyDescriptor::AllPresent));
|
||||
}
|
||||
|
||||
|
||||
// Let pluralCategories be a List of Strings representing the possible results of PluralRuleSelect for the selected locale pr.[[Locale]]. This List consists of unique string values, from the the list "zero", "one", "two", "few", "many" and "other", that are relevant for the locale whose localization is specified in LDML Language Plural Rules.
|
||||
// Perform ! CreateDataProperty(options, "pluralCategories", CreateArrayFromList(pluralCategories)).
|
||||
|
|
@ -583,8 +583,7 @@ static Value builtinIntlPluralRulesResolvedOptions(ExecutionState& state, Value
|
|||
UErrorCode status = U_ZERO_ERROR;
|
||||
UEnumeration* ue = uplrules_getKeywords(pr->icuPluralRules(), &status);
|
||||
ASSERT(U_SUCCESS(status));
|
||||
uint32_t i = 0;
|
||||
|
||||
Vector<String*, GCUtil::gc_malloc_allocator<String*>> v;
|
||||
do {
|
||||
int32_t size;
|
||||
const char* str = uenum_next(ue, &size, &status);
|
||||
|
|
@ -594,15 +593,49 @@ static Value builtinIntlPluralRulesResolvedOptions(ExecutionState& state, Value
|
|||
break;
|
||||
}
|
||||
|
||||
String* s = String::fromUTF8(str, size);
|
||||
pluralCategories->defineOwnPropertyThrowsException(state, ObjectPropertyName(state, (size_t)i), ObjectPropertyDescriptor(Value(s), ObjectPropertyDescriptor::AllPresent));
|
||||
i++;
|
||||
v.pushBack(String::fromUTF8(str, size));
|
||||
} while (true);
|
||||
|
||||
|
||||
constexpr std::array<const char*, 6> candidates = { { "zero", "one", "two", "few", "many", "other" } };
|
||||
|
||||
size_t i = 0;
|
||||
for (auto candidate : candidates) {
|
||||
for (auto s : v) {
|
||||
if (s->equals(candidate, strlen(candidate))) {
|
||||
pluralCategories->defineOwnPropertyThrowsException(state, ObjectPropertyName(state, i++), ObjectPropertyDescriptor(Value(s), ObjectPropertyDescriptor::AllPresent));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
options->defineOwnPropertyThrowsException(state, ObjectPropertyName(AtomicString(state.context()->atomicStringMap(), "pluralCategories", sizeof("pluralCategories") - 1, AtomicString::FromExternalMemory)),
|
||||
ObjectPropertyDescriptor(pluralCategories, ObjectPropertyDescriptor::AllPresent));
|
||||
|
||||
uenum_close(ue);
|
||||
|
||||
options->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().lazyRoundingIncrement()), ObjectPropertyDescriptor(Value(Value::DoubleToIntConvertibleTestNeeds, pr->roundingIncrement()), ObjectPropertyDescriptor::AllPresent));
|
||||
|
||||
options->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().lazyRoundingMode()), ObjectPropertyDescriptor(pr->roundingMode(), ObjectPropertyDescriptor::AllPresent));
|
||||
|
||||
Value roundingType;
|
||||
switch (pr->computedRoundingPriority()) {
|
||||
case Intl::RoundingPriority::Auto:
|
||||
roundingType = state.context()->staticStrings().lazyAuto().string();
|
||||
break;
|
||||
case Intl::RoundingPriority::MorePrecision:
|
||||
roundingType = state.context()->staticStrings().lazyMorePrecision().string();
|
||||
break;
|
||||
case Intl::RoundingPriority::LessPrecision:
|
||||
roundingType = state.context()->staticStrings().lazyLessPrecision().string();
|
||||
break;
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
options->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().lazyRoundingPriority()), ObjectPropertyDescriptor(roundingType, ObjectPropertyDescriptor::AllPresent));
|
||||
options->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().lazyTrailingZeroDisplay()), ObjectPropertyDescriptor(pr->trailingZeroDisplay(), ObjectPropertyDescriptor::AllPresent));
|
||||
|
||||
// Return options.
|
||||
return options;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2647,7 +2647,7 @@ Intl::SetNumberFormatDigitOptionsResult Intl::setNumberFormatDigitOptions(Execut
|
|||
}
|
||||
|
||||
// Set intlObj.[[MinimumIntegerDigits]] to mnid.
|
||||
result.minimumIntegerDigits = Value(Value::DoubleToIntConvertibleTestNeeds, mnid);
|
||||
result.minimumIntegerDigits = mnid;
|
||||
|
||||
// Let roundingIncrement be ? GetNumberOption(options, "roundingIncrement", 1, 5000, 1).
|
||||
double roundingIncrement = Intl::getNumberOption(state, options, state.context()->staticStrings().lazyRoundingIncrement().string(), 1, 5000, 1);
|
||||
|
|
@ -2678,9 +2678,9 @@ Intl::SetNumberFormatDigitOptionsResult Intl::setNumberFormatDigitOptions(Execut
|
|||
// Set intlObj.[[RoundingIncrement]] to roundingIncrement.
|
||||
result.roundingIncrement = roundingIncrement;
|
||||
// Set intlObj.[[RoundingMode]] to roundingMode.
|
||||
result.roundingMode = roundingMode;
|
||||
result.roundingMode = roundingMode.asString();
|
||||
// Set intlObj.[[TrailingZeroDisplay]] to trailingZeroDisplay.
|
||||
result.trailingZeroDisplay = trailingZeroDisplay;
|
||||
result.trailingZeroDisplay = trailingZeroDisplay.asString();
|
||||
// If mnsd is undefined and mxsd is undefined, let hasSd be false. Otherwise, let hasSd be true.
|
||||
bool hasSd;
|
||||
if (mnsd.isUndefined() && mxsd.isUndefined()) {
|
||||
|
|
@ -2814,6 +2814,186 @@ Intl::SetNumberFormatDigitOptionsResult Intl::setNumberFormatDigitOptions(Execut
|
|||
return result;
|
||||
}
|
||||
|
||||
void Intl::initNumberFormatSkeleton(ExecutionState& state, const Intl::SetNumberFormatDigitOptionsResult& formatResult, String* notation, String* compactDisplay, UTF16StringDataNonGCStd& skeleton)
|
||||
{
|
||||
#if defined(ENABLE_RUNTIME_ICU_BINDER)
|
||||
UVersionInfo versionArray;
|
||||
u_getVersion(versionArray);
|
||||
if (versionArray[0] < 68) {
|
||||
if (!formatResult.minimumSignificantDigits.isUndefined()) {
|
||||
double mnsd = formatResult.minimumSignificantDigits.asNumber();
|
||||
double mxsd = formatResult.maximumSignificantDigits.asNumber();
|
||||
|
||||
for (double i = 0; i < mnsd; i++) {
|
||||
skeleton += '@';
|
||||
}
|
||||
|
||||
for (double i = 0; i < mxsd - mnsd; i++) {
|
||||
skeleton += '#';
|
||||
}
|
||||
|
||||
skeleton += ' ';
|
||||
}
|
||||
|
||||
if (!formatResult.minimumFractionDigits.isUndefined()) {
|
||||
double mnfd = formatResult.minimumSignificantDigits.asNumber();
|
||||
double mxfd = formatResult.maximumSignificantDigits.asNumber();
|
||||
|
||||
skeleton += '.';
|
||||
|
||||
for (double i = 0; i < mnfd; i++) {
|
||||
skeleton += '0';
|
||||
}
|
||||
|
||||
for (double i = 0; i < mxfd - mnfd; i++) {
|
||||
skeleton += '#';
|
||||
}
|
||||
skeleton += ' ';
|
||||
}
|
||||
|
||||
{
|
||||
double mnid = formatResult.minimumIntegerDigits;
|
||||
skeleton += u"integer-width/+";
|
||||
for (double i = 0; i < mnid; i++) {
|
||||
skeleton += '0';
|
||||
}
|
||||
skeleton += ' ';
|
||||
}
|
||||
|
||||
if (notation->equals("standard")) {
|
||||
} else if (notation->equals("scientific")) {
|
||||
skeleton += u"scientific ";
|
||||
} else if (notation->equals("engineering")) {
|
||||
skeleton += u"engineering ";
|
||||
} else {
|
||||
if (compactDisplay->equals("short")) {
|
||||
skeleton += u"compact-short ";
|
||||
} else {
|
||||
skeleton += u"compact-long ";
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
String* rm = formatResult.roundingMode;
|
||||
if (rm->equals("ceil")) {
|
||||
skeleton += u"rounding-mode-ceiling ";
|
||||
} else if (rm->equals("floor")) {
|
||||
skeleton += u"rounding-mode-floor ";
|
||||
} else if (rm->equals("expand")) {
|
||||
skeleton += u"rounding-mode-up ";
|
||||
} else if (rm->equals("trunc")) {
|
||||
skeleton += u"rounding-mode-down ";
|
||||
} else if (rm->equals("halfCeil")) {
|
||||
skeleton += u"rounding-mode-half-ceiling ";
|
||||
} else if (rm->equals("halfFloor")) {
|
||||
skeleton += u"rounding-mode-half-floor ";
|
||||
} else if (rm->equals("halfExpand")) {
|
||||
skeleton += u"rounding-mode-half-up ";
|
||||
} else if (rm->equals("halfTrunc")) {
|
||||
skeleton += u"rounding-mode-half-down ";
|
||||
} else {
|
||||
ASSERT(rm->equals("halfEven"));
|
||||
skeleton += u"rounding-mode-half-even ";
|
||||
}
|
||||
|
||||
{
|
||||
double mnid = formatResult.minimumIntegerDigits;
|
||||
skeleton += u"integer-width/*";
|
||||
for (double i = 0; i < mnid; i++) {
|
||||
skeleton += '0';
|
||||
}
|
||||
skeleton += ' ';
|
||||
}
|
||||
|
||||
if (formatResult.roundingIncrement != 1) {
|
||||
skeleton += u"precision-increment/";
|
||||
auto string = dtoa(formatResult.roundingIncrement);
|
||||
if (formatResult.maximumFractionDigits.asNumber() >= string.size()) {
|
||||
skeleton += u"0.";
|
||||
for (size_t i = 0; i < (formatResult.maximumFractionDigits.asNumber() - string.size()); i++) {
|
||||
skeleton += u"0";
|
||||
}
|
||||
for (auto c : string) {
|
||||
skeleton += static_cast<char16_t>(c);
|
||||
}
|
||||
} else {
|
||||
auto nonFraction = string.size() - formatResult.maximumFractionDigits.asNumber();
|
||||
for (size_t i = 0; i < nonFraction; i++) {
|
||||
skeleton += static_cast<char16_t>(string[i]);
|
||||
}
|
||||
skeleton += u".";
|
||||
|
||||
for (size_t i = 0; i < nonFraction; i++) {
|
||||
skeleton += static_cast<char16_t>(string[i]);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < formatResult.maximumFractionDigits.asNumber(); i++) {
|
||||
skeleton += static_cast<char16_t>(string[i + nonFraction]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (formatResult.roundingType == Intl::RoundingType::FractionDigits) {
|
||||
skeleton += u".";
|
||||
for (size_t i = 0; i < formatResult.minimumFractionDigits.asNumber(); i++) {
|
||||
skeleton += u"0";
|
||||
}
|
||||
for (size_t i = 0; i < formatResult.maximumFractionDigits.asNumber() - formatResult.minimumFractionDigits.asNumber(); i++) {
|
||||
skeleton += u"#";
|
||||
}
|
||||
} else if (formatResult.roundingType == Intl::RoundingType::SignificantDigits) {
|
||||
for (size_t i = 0; i < formatResult.minimumSignificantDigits.asNumber(); i++) {
|
||||
skeleton += u"@";
|
||||
}
|
||||
for (size_t i = 0; i < formatResult.maximumSignificantDigits.asNumber() - formatResult.minimumSignificantDigits.asNumber(); i++) {
|
||||
skeleton += u"#";
|
||||
}
|
||||
} else {
|
||||
ASSERT(formatResult.roundingType == Intl::RoundingType::LessPrecision || formatResult.roundingType == Intl::RoundingType::MorePrecision);
|
||||
skeleton += u".";
|
||||
for (size_t i = 0; i < formatResult.minimumFractionDigits.asNumber(); i++) {
|
||||
skeleton += u"0";
|
||||
}
|
||||
for (size_t i = 0; i < formatResult.maximumFractionDigits.asNumber() - formatResult.minimumFractionDigits.asNumber(); i++) {
|
||||
skeleton += u"#";
|
||||
}
|
||||
skeleton += u"/";
|
||||
for (size_t i = 0; i < formatResult.minimumSignificantDigits.asNumber(); i++) {
|
||||
skeleton += u"@";
|
||||
}
|
||||
for (size_t i = 0; i < formatResult.maximumSignificantDigits.asNumber() - formatResult.minimumSignificantDigits.asNumber(); i++) {
|
||||
skeleton += u"#";
|
||||
}
|
||||
if (formatResult.roundingType == Intl::RoundingType::MorePrecision) {
|
||||
skeleton += u"r";
|
||||
} else {
|
||||
skeleton += u"s";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (formatResult.trailingZeroDisplay->equals("auto")) {
|
||||
skeleton += u" ";
|
||||
} else {
|
||||
ASSERT(formatResult.trailingZeroDisplay->equals("stripIfInteger"));
|
||||
skeleton += u"/w ";
|
||||
}
|
||||
|
||||
if (notation->equals("standard")) {
|
||||
} else if (notation->equals("scientific")) {
|
||||
skeleton += u"scientific ";
|
||||
} else if (notation->equals("engineering")) {
|
||||
skeleton += u"engineering ";
|
||||
} else {
|
||||
if (compactDisplay->equals("short")) {
|
||||
skeleton += u"compact-short ";
|
||||
} else {
|
||||
skeleton += u"compact-long ";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Escargot
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -100,10 +100,10 @@ public:
|
|||
MorePrecision
|
||||
};
|
||||
struct SetNumberFormatDigitOptionsResult {
|
||||
Value minimumIntegerDigits;
|
||||
double minimumIntegerDigits;
|
||||
double roundingIncrement;
|
||||
Value roundingMode;
|
||||
Value trailingZeroDisplay;
|
||||
String* roundingMode;
|
||||
String* trailingZeroDisplay;
|
||||
Value minimumSignificantDigits;
|
||||
Value maximumSignificantDigits;
|
||||
Value minimumFractionDigits;
|
||||
|
|
@ -114,6 +114,7 @@ public:
|
|||
// https://402.ecma-international.org/12.0/index.html#sec-setnumberformatdigitoptions
|
||||
static SetNumberFormatDigitOptionsResult setNumberFormatDigitOptions(ExecutionState& state, Object* options,
|
||||
double mnfdDefault, double mxfdDefault, String* notation);
|
||||
static void initNumberFormatSkeleton(ExecutionState& state, const Intl::SetNumberFormatDigitOptionsResult& formatResult, String* notation, String* compactDisplay, UTF16StringDataNonGCStd& skeleton);
|
||||
|
||||
// https://tc39.es/ecma402/#sec-defaultnumberoption
|
||||
static Value defaultNumberOption(ExecutionState& state, Value value, double minimum, double maximum, double fallback);
|
||||
|
|
|
|||
|
|
@ -490,16 +490,23 @@ void IntlNumberFormat::initialize(ExecutionState& state, Object* numberFormat, V
|
|||
// Perform ? SetNumberFormatDigitOptions(numberFormat, options, mnfdDefault, mxfdDefault, notation).
|
||||
auto setNumberFormatDigitOptionsResult = Intl::setNumberFormatDigitOptions(state, options.asObject(), mnfdDefault, mxfdDefault, notation.asString());
|
||||
|
||||
numberFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazyMinimumIntegerDigits()),
|
||||
Value(Value::DoubleToIntConvertibleTestNeeds, setNumberFormatDigitOptionsResult.minimumIntegerDigits),
|
||||
numberFormat->internalSlot());
|
||||
#define SET_PROPERTY(name, Name) \
|
||||
if (!setNumberFormatDigitOptionsResult.name.isUndefined()) { \
|
||||
numberFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazy##Name()), \
|
||||
setNumberFormatDigitOptionsResult.name, numberFormat->internalSlot()); \
|
||||
}
|
||||
SET_PROPERTY(minimumIntegerDigits, MinimumIntegerDigits);
|
||||
SET_PROPERTY(minimumFractionDigits, MinimumFractionDigits);
|
||||
SET_PROPERTY(maximumFractionDigits, MaximumFractionDigits);
|
||||
SET_PROPERTY(minimumSignificantDigits, MinimumSignificantDigits);
|
||||
SET_PROPERTY(maximumSignificantDigits, MaximumSignificantDigits);
|
||||
#undef SET_PROPERTY
|
||||
|
||||
#define SET_PROPERTY(name, Name) \
|
||||
numberFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazy##Name()), \
|
||||
setNumberFormatDigitOptionsResult.name, numberFormat->internalSlot());
|
||||
SET_PROPERTY(roundingMode, RoundingMode);
|
||||
SET_PROPERTY(trailingZeroDisplay, TrailingZeroDisplay);
|
||||
#undef SET_PROPERTY
|
||||
|
|
@ -707,64 +714,12 @@ void IntlNumberFormat::initNumberFormatSkeleton(ExecutionState& state, const Int
|
|||
}
|
||||
}
|
||||
|
||||
if (!formatResult.minimumSignificantDigits.isUndefined()) {
|
||||
double mnsd = formatResult.minimumSignificantDigits.asNumber();
|
||||
double mxsd = formatResult.maximumSignificantDigits.asNumber();
|
||||
|
||||
for (double i = 0; i < mnsd; i++) {
|
||||
skeleton += '@';
|
||||
}
|
||||
|
||||
for (double i = 0; i < mxsd - mnsd; i++) {
|
||||
skeleton += '#';
|
||||
}
|
||||
|
||||
skeleton += ' ';
|
||||
}
|
||||
|
||||
if (!formatResult.minimumFractionDigits.isUndefined()) {
|
||||
double mnfd = formatResult.minimumSignificantDigits.asNumber();
|
||||
double mxfd = formatResult.maximumSignificantDigits.asNumber();
|
||||
|
||||
skeleton += '.';
|
||||
|
||||
for (double i = 0; i < mnfd; i++) {
|
||||
skeleton += '0';
|
||||
}
|
||||
|
||||
for (double i = 0; i < mxfd - mnfd; i++) {
|
||||
skeleton += '#';
|
||||
}
|
||||
skeleton += ' ';
|
||||
}
|
||||
|
||||
{
|
||||
double mnid = formatResult.minimumIntegerDigits.asNumber();
|
||||
skeleton += u"integer-width/+";
|
||||
for (double i = 0; i < mnid; i++) {
|
||||
skeleton += '0';
|
||||
}
|
||||
skeleton += ' ';
|
||||
}
|
||||
Intl::initNumberFormatSkeleton(state, formatResult, notation.asString(), compactDisplay.asString(), skeleton);
|
||||
|
||||
if (!useGrouping.toBoolean()) {
|
||||
skeleton += u"group-off ";
|
||||
}
|
||||
|
||||
String* notationString = notation.asString();
|
||||
if (notationString->equals("standard")) {
|
||||
} else if (notationString->equals("scientific")) {
|
||||
skeleton += u"scientific ";
|
||||
} else if (notationString->equals("engineering")) {
|
||||
skeleton += u"engineering ";
|
||||
} else {
|
||||
if (compactDisplay.asString()->equals("short")) {
|
||||
skeleton += u"compact-short ";
|
||||
} else {
|
||||
skeleton += u"compact-long ";
|
||||
}
|
||||
}
|
||||
|
||||
String* signDisplayString = signDisplay.asString();
|
||||
bool accountingSign = currencySign.asString()->equals("accounting");
|
||||
if (signDisplayString->equals("auto")) {
|
||||
|
|
@ -791,110 +746,7 @@ void IntlNumberFormat::initNumberFormatSkeleton(ExecutionState& state, const Int
|
|||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
String* rm = formatResult.roundingMode.asString();
|
||||
if (rm->equals("ceil")) {
|
||||
skeleton += u"rounding-mode-ceiling ";
|
||||
} else if (rm->equals("floor")) {
|
||||
skeleton += u"rounding-mode-floor ";
|
||||
} else if (rm->equals("expand")) {
|
||||
skeleton += u"rounding-mode-up ";
|
||||
} else if (rm->equals("trunc")) {
|
||||
skeleton += u"rounding-mode-down ";
|
||||
} else if (rm->equals("halfCeil")) {
|
||||
skeleton += u"rounding-mode-half-ceiling ";
|
||||
} else if (rm->equals("halfFloor")) {
|
||||
skeleton += u"rounding-mode-half-floor ";
|
||||
} else if (rm->equals("halfExpand")) {
|
||||
skeleton += u"rounding-mode-half-up ";
|
||||
} else if (rm->equals("halfTrunc")) {
|
||||
skeleton += u"rounding-mode-half-down ";
|
||||
} else {
|
||||
ASSERT(rm->equals("halfEven"));
|
||||
skeleton += u"rounding-mode-half-even ";
|
||||
}
|
||||
|
||||
{
|
||||
double mnid = formatResult.minimumIntegerDigits.asNumber();
|
||||
skeleton += u"integer-width/*";
|
||||
for (double i = 0; i < mnid; i++) {
|
||||
skeleton += '0';
|
||||
}
|
||||
skeleton += ' ';
|
||||
}
|
||||
|
||||
if (formatResult.roundingIncrement != 1) {
|
||||
skeleton += u"precision-increment/";
|
||||
auto string = dtoa(formatResult.roundingIncrement);
|
||||
if (formatResult.maximumFractionDigits.asNumber() >= string.size()) {
|
||||
skeleton += u"0.";
|
||||
for (size_t i = 0; i < (formatResult.maximumFractionDigits.asNumber() - string.size()); i++) {
|
||||
skeleton += u"0";
|
||||
}
|
||||
for (auto c : string) {
|
||||
skeleton += static_cast<char16_t>(c);
|
||||
}
|
||||
} else {
|
||||
auto nonFraction = string.size() - formatResult.maximumFractionDigits.asNumber();
|
||||
for (size_t i = 0; i < nonFraction; i++) {
|
||||
skeleton += static_cast<char16_t>(string[i]);
|
||||
}
|
||||
skeleton += u".";
|
||||
|
||||
for (size_t i = 0; i < nonFraction; i++) {
|
||||
skeleton += static_cast<char16_t>(string[i]);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < formatResult.maximumFractionDigits.asNumber(); i++) {
|
||||
skeleton += static_cast<char16_t>(string[i + nonFraction]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (formatResult.roundingType == Intl::RoundingType::FractionDigits) {
|
||||
skeleton += u".";
|
||||
for (size_t i = 0; i < formatResult.minimumFractionDigits.asNumber(); i++) {
|
||||
skeleton += u"0";
|
||||
}
|
||||
for (size_t i = 0; i < formatResult.maximumFractionDigits.asNumber() - formatResult.minimumFractionDigits.asNumber(); i++) {
|
||||
skeleton += u"#";
|
||||
}
|
||||
} else if (formatResult.roundingType == Intl::RoundingType::SignificantDigits) {
|
||||
for (size_t i = 0; i < formatResult.minimumSignificantDigits.asNumber(); i++) {
|
||||
skeleton += u"@";
|
||||
}
|
||||
for (size_t i = 0; i < formatResult.maximumSignificantDigits.asNumber() - formatResult.minimumSignificantDigits.asNumber(); i++) {
|
||||
skeleton += u"#";
|
||||
}
|
||||
} else {
|
||||
ASSERT(formatResult.roundingType == Intl::RoundingType::LessPrecision || formatResult.roundingType == Intl::RoundingType::MorePrecision);
|
||||
skeleton += u".";
|
||||
for (size_t i = 0; i < formatResult.minimumFractionDigits.asNumber(); i++) {
|
||||
skeleton += u"0";
|
||||
}
|
||||
for (size_t i = 0; i < formatResult.maximumFractionDigits.asNumber() - formatResult.minimumFractionDigits.asNumber(); i++) {
|
||||
skeleton += u"#";
|
||||
}
|
||||
skeleton += u"/";
|
||||
for (size_t i = 0; i < formatResult.minimumSignificantDigits.asNumber(); i++) {
|
||||
skeleton += u"@";
|
||||
}
|
||||
for (size_t i = 0; i < formatResult.maximumSignificantDigits.asNumber() - formatResult.minimumSignificantDigits.asNumber(); i++) {
|
||||
skeleton += u"#";
|
||||
}
|
||||
if (formatResult.roundingType == Intl::RoundingType::MorePrecision) {
|
||||
skeleton += u"r";
|
||||
} else {
|
||||
skeleton += u"s";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (formatResult.trailingZeroDisplay.asString()->equals("auto")) {
|
||||
skeleton += u" ";
|
||||
} else {
|
||||
ASSERT(formatResult.trailingZeroDisplay.asString()->equals("stripIfInteger"));
|
||||
skeleton += u"/w ";
|
||||
}
|
||||
Intl::initNumberFormatSkeleton(state, formatResult, notation.asString(), compactDisplay.asString(), skeleton);
|
||||
|
||||
if (style.asString()->equals("currency")) {
|
||||
if (!currency.isUndefined()) {
|
||||
|
|
@ -976,20 +828,6 @@ void IntlNumberFormat::initNumberFormatSkeleton(ExecutionState& state, const Int
|
|||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
String* notationString = notation.asString();
|
||||
if (notationString->equals("standard")) {
|
||||
} else if (notationString->equals("scientific")) {
|
||||
skeleton += u"scientific ";
|
||||
} else if (notationString->equals("engineering")) {
|
||||
skeleton += u"engineering ";
|
||||
} else {
|
||||
if (compactDisplay.asString()->equals("short")) {
|
||||
skeleton += u"compact-short ";
|
||||
} else {
|
||||
skeleton += u"compact-long ";
|
||||
}
|
||||
}
|
||||
|
||||
String* signDisplayString = signDisplay.asString();
|
||||
bool accountingSign = style.asString()->equals("currency") && currencySign.asString()->equals("accounting");
|
||||
if (signDisplayString->equals("auto")) {
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@ void* IntlPluralRulesObject::operator new(size_t size)
|
|||
Object::fillGCDescriptor(desc);
|
||||
GC_set_bit(desc, GC_WORD_OFFSET(IntlPluralRulesObject, m_locale));
|
||||
GC_set_bit(desc, GC_WORD_OFFSET(IntlPluralRulesObject, m_type));
|
||||
GC_set_bit(desc, GC_WORD_OFFSET(IntlPluralRulesObject, m_notation));
|
||||
GC_set_bit(desc, GC_WORD_OFFSET(IntlPluralRulesObject, m_roundingMode));
|
||||
GC_set_bit(desc, GC_WORD_OFFSET(IntlPluralRulesObject, m_trailingZeroDisplay));
|
||||
descr = GC_make_descriptor(desc, GC_WORD_LEN(IntlPluralRulesObject));
|
||||
typeInited = true;
|
||||
}
|
||||
|
|
@ -61,10 +64,11 @@ IntlPluralRulesObject::IntlPluralRulesObject(ExecutionState& state, Object* prot
|
|||
// Let requestedLocales be ? CanonicalizeLocaleList(locales).
|
||||
ValueVector requestedLocales = Intl::canonicalizeLocaleList(state, locales);
|
||||
|
||||
Optional<Object*> optionObject;
|
||||
Object* optionObject;
|
||||
// If options is undefined, then
|
||||
if (options.isUndefined()) {
|
||||
// Let options be ObjectCreate(null).
|
||||
optionObject = new Object(state, Object::PrototypeIsNull);
|
||||
} else {
|
||||
// Let options be ? ToObject(options).
|
||||
optionObject = options.toObject(state);
|
||||
|
|
@ -75,58 +79,20 @@ IntlPluralRulesObject::IntlPluralRulesObject(ExecutionState& state, Object* prot
|
|||
// Let matcher be ? GetOption(options, "localeMatcher", "string", « "lookup", "best fit" », "best fit").
|
||||
// Set opt.[[localeMatcher]] to matcher.
|
||||
Value localeMatcherValues[2] = { state.context()->staticStrings().lazyLookup().string(), state.context()->staticStrings().lazyBestFit().string() };
|
||||
String* matcher = localeMatcherValues[1].asString();
|
||||
if (optionObject) {
|
||||
matcher = Intl::getOption(state, optionObject.value(), state.context()->staticStrings().lazyLocaleMatcher().string(), Intl::StringValue, localeMatcherValues, 2, localeMatcherValues[1]).asString();
|
||||
}
|
||||
String* matcher = Intl::getOption(state, optionObject, state.context()->staticStrings().lazyLocaleMatcher().string(), Intl::StringValue, localeMatcherValues, 2, localeMatcherValues[1]).asString();
|
||||
opt.insert(std::make_pair("matcher", matcher));
|
||||
|
||||
// Let t be ? GetOption(options, "type", "string", « "cardinal", "ordinal" », "cardinal").
|
||||
Value typeValues[2] = { state.context()->staticStrings().lazyCardinal().string(), state.context()->staticStrings().lazyOrdinal().string() };
|
||||
String* t = typeValues[0].asString();
|
||||
if (optionObject) {
|
||||
t = Intl::getOption(state, optionObject.value(), state.context()->staticStrings().lazyType().string(), Intl::StringValue, typeValues, 2, typeValues[0]).asString();
|
||||
}
|
||||
String* t = Intl::getOption(state, optionObject, state.context()->staticStrings().lazyType().string(), Intl::StringValue, typeValues, 2, typeValues[0]).asString();
|
||||
|
||||
// Let notation be ? GetOption(options, "notation", "string", « "standard", "scientific", "engineering", "compact" », "standard").
|
||||
Value notationValues[4] = { state.context()->staticStrings().lazyStandard().string(), state.context()->staticStrings().lazyScientific().string(), state.context()->staticStrings().lazyEngineering().string(), state.context()->staticStrings().lazyCompact().string() };
|
||||
Value notation = Intl::getOption(state, optionObject, state.context()->staticStrings().lazyNotation().string(), Intl::StringValue, notationValues, 4, notationValues[0]);
|
||||
m_notation = notation.asString();
|
||||
|
||||
// Perform ? SetNumberFormatDigitOptions(pluralRules, options, 0, 3).
|
||||
// Let mnid be the result of calling the GetNumberOption abstract operation (defined in 9.2.10) with arguments options, "minimumIntegerDigits", 1, 21, and 1.
|
||||
double mnid = Intl::getNumberOption(state, optionObject, state.context()->staticStrings().lazyMinimumIntegerDigits().string(), 1, 21, 1);
|
||||
// Set the [[minimumIntegerDigits]] internal property of numberFormat to mnid.
|
||||
m_minimumIntegerDigits = mnid;
|
||||
|
||||
double mnfdDefault = 0;
|
||||
// Let mnfd be the result of calling the GetNumberOption abstract operation with arguments options, "minimumFractionDigits", 0, 20, and mnfdDefault.
|
||||
double mnfd = Intl::getNumberOption(state, optionObject, state.context()->staticStrings().lazyMinimumFractionDigits().string(), 0, 20, mnfdDefault);
|
||||
|
||||
// Set the [[minimumFractionDigits]] internal property of numberFormat to mnfd.
|
||||
m_minimumFractionDigits = mnfd;
|
||||
|
||||
double mxfdDefault = 3;
|
||||
|
||||
// Let mxfd be the result of calling the GetNumberOption abstract operation with arguments options, "maximumFractionDigits", mnfd, 20, and mxfdDefault.
|
||||
double mxfd = Intl::getNumberOption(state, optionObject, state.context()->staticStrings().lazyMaximumFractionDigits().string(), mnfd, 20, mxfdDefault);
|
||||
|
||||
// Set the [[maximumFractionDigits]] internal property of numberFormat to mxfd.
|
||||
m_maximumFractionDigits = mxfd;
|
||||
|
||||
if (optionObject) {
|
||||
// Let mnsd be the result of calling the [[Get]] internal method of options with argument "minimumSignificantDigits".
|
||||
Value mnsd = optionObject.value()->get(state, ObjectPropertyName(state.context()->staticStrings().lazyMinimumSignificantDigits())).value(state, optionObject.value());
|
||||
// Let mxsd be the result of calling the [[Get]] internal method of options with argument "maximumSignificantDigits".
|
||||
Value mxsd = optionObject.value()->get(state, ObjectPropertyName(state.context()->staticStrings().lazyMaximumSignificantDigits())).value(state, optionObject.value());
|
||||
|
||||
// If mnsd is not undefined or mxsd is not undefined, then:
|
||||
if (!mnsd.isUndefined() || !mxsd.isUndefined()) {
|
||||
// Let mnsd be the result of calling the GetNumberOption abstract operation with arguments options, "minimumSignificantDigits", 1, 21, and 1.
|
||||
mnsd = Value(Value::DoubleToIntConvertibleTestNeeds, Intl::getNumberOption(state, optionObject, state.context()->staticStrings().lazyMinimumSignificantDigits().string(), 1, 21, 1));
|
||||
// Let mxsd be the result of calling the GetNumberOption abstract operation with arguments options, "maximumSignificantDigits", mnsd, 21, and 21.
|
||||
mxsd = Value(Value::DoubleToIntConvertibleTestNeeds, Intl::getNumberOption(state, optionObject, state.context()->staticStrings().lazyMaximumSignificantDigits().string(), mnsd.asNumber(), 21, 21));
|
||||
// Set the [[minimumSignificantDigits]] internal property of numberFormat to mnsd,
|
||||
// and the [[maximumSignificantDigits]] internal property of numberFormat to mxsd.
|
||||
m_minimumSignificantDigits = mnsd.asNumber();
|
||||
m_maximumSignificantDigits = mxsd.asNumber();
|
||||
}
|
||||
}
|
||||
auto optionsResult = Intl::setNumberFormatDigitOptions(state, optionObject, 0, 3, m_notation);
|
||||
|
||||
// Let localeData be %PluralRules%.[[LocaleData]].
|
||||
// Let r be ResolveLocale(%PluralRules%.[[AvailableLocales]], requestedLocales, opt, %PluralRules%.[[RelevantExtensionKeys]], localeData).
|
||||
|
|
@ -134,24 +100,23 @@ IntlPluralRulesObject::IntlPluralRulesObject(ExecutionState& state, Object* prot
|
|||
auto r = Intl::resolveLocale(state, state.context()->vmInstance()->intlPluralRulesAvailableLocales(), requestedLocales, opt, nullptr, 0, nullptr);
|
||||
String* foundLocale = r.at("locale");
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
m_icuNumberFormat = unum_open(UNUM_DEFAULT, nullptr, 0, foundLocale->toNonGCUTF8StringData().data(), nullptr, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Failed to init PluralRule");
|
||||
}
|
||||
m_minimumIntegerDigits = optionsResult.minimumIntegerDigits;
|
||||
m_roundingIncrement = optionsResult.roundingIncrement;
|
||||
m_trailingZeroDisplay = optionsResult.trailingZeroDisplay;
|
||||
m_minimumSignificantDigits = optionsResult.minimumSignificantDigits;
|
||||
m_maximumSignificantDigits = optionsResult.maximumSignificantDigits;
|
||||
m_minimumFractionDigits = optionsResult.minimumFractionDigits;
|
||||
m_maximumFractionDigits = optionsResult.maximumFractionDigits;
|
||||
m_roundingType = optionsResult.roundingType;
|
||||
m_roundingMode = optionsResult.roundingMode;
|
||||
m_computedRoundingPriority = optionsResult.computedRoundingPriority;
|
||||
|
||||
if (!m_minimumSignificantDigits.hasValue()) {
|
||||
unum_setAttribute(m_icuNumberFormat, UNUM_MIN_INTEGER_DIGITS, m_minimumIntegerDigits);
|
||||
unum_setAttribute(m_icuNumberFormat, UNUM_MIN_FRACTION_DIGITS, m_minimumFractionDigits);
|
||||
unum_setAttribute(m_icuNumberFormat, UNUM_MAX_FRACTION_DIGITS, m_maximumFractionDigits);
|
||||
} else {
|
||||
unum_setAttribute(m_icuNumberFormat, UNUM_SIGNIFICANT_DIGITS_USED, true);
|
||||
unum_setAttribute(m_icuNumberFormat, UNUM_MIN_SIGNIFICANT_DIGITS, m_minimumSignificantDigits);
|
||||
unum_setAttribute(m_icuNumberFormat, UNUM_MAX_SIGNIFICANT_DIGITS, m_maximumSignificantDigits);
|
||||
}
|
||||
unum_setAttribute(m_icuNumberFormat, UNUM_ROUNDING_MODE, UNUM_ROUND_HALFUP);
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UTF16StringDataNonGCStd skeleton;
|
||||
Intl::initNumberFormatSkeleton(state, optionsResult, m_notation, state.context()->staticStrings().lazyCompact().string(), skeleton);
|
||||
m_icuNumberFormat = unumf_openForSkeletonAndLocale((UChar*)skeleton.data(), skeleton.length(), foundLocale->toNonGCUTF8StringData().data(), &status);
|
||||
if (U_FAILURE(status)) {
|
||||
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Failed to init NumberFormat");
|
||||
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Failed to init PluralRules");
|
||||
}
|
||||
|
||||
ASSERT(U_SUCCESS(status));
|
||||
|
|
@ -175,14 +140,14 @@ IntlPluralRulesObject::IntlPluralRulesObject(ExecutionState& state, Object* prot
|
|||
addFinalizer([](PointerValue* obj, void* data) {
|
||||
IntlPluralRulesObject* self = (IntlPluralRulesObject*)obj;
|
||||
uplrules_close(self->m_icuPluralRules);
|
||||
unum_close(self->m_icuNumberFormat);
|
||||
unumf_close(self->m_icuNumberFormat);
|
||||
},
|
||||
nullptr);
|
||||
|
||||
// Return pluralRules.
|
||||
}
|
||||
|
||||
String* IntlPluralRulesObject::resolvePlural(double number)
|
||||
String* IntlPluralRulesObject::resolvePlural(ExecutionState& state, double number)
|
||||
{
|
||||
// https://www.ecma-international.org/ecma-402/6.0/index.html#sec-resolveplural
|
||||
// If n is not a finite Number, then
|
||||
|
|
@ -190,13 +155,25 @@ String* IntlPluralRulesObject::resolvePlural(double number)
|
|||
// Return "other".
|
||||
return String::fromASCII("other");
|
||||
}
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
int32_t len = uplrules_selectWithFormat(m_icuPluralRules, number, m_icuNumberFormat, nullptr, 0, &status);
|
||||
UChar* buf = (UChar*)alloca((len + 1) * sizeof(UChar));
|
||||
|
||||
LocalResourcePointer<UFormattedNumber> formattedNumber(unumf_openResult(&status), [](UFormattedNumber* f) { unumf_closeResult(f); });
|
||||
if (U_FAILURE(status)) {
|
||||
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Failed to resolve Plural");
|
||||
}
|
||||
unumf_formatDouble(m_icuNumberFormat, number, formattedNumber.get(), &status);
|
||||
if (U_FAILURE(status)) {
|
||||
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Failed to resolve Plural");
|
||||
}
|
||||
|
||||
int32_t len = uplrules_selectFormatted(m_icuPluralRules, formattedNumber.get(), nullptr, 0, &status);
|
||||
UChar* buf = ALLOCA((len + 1) * sizeof(UChar), UChar);
|
||||
status = U_ZERO_ERROR;
|
||||
uplrules_selectWithFormat(m_icuPluralRules, number, m_icuNumberFormat, buf, len + 1, &status);
|
||||
uplrules_selectFormatted(m_icuPluralRules, formattedNumber.get(), buf, len + 1, &status);
|
||||
ASSERT(U_SUCCESS(status));
|
||||
if (U_FAILURE(status)) {
|
||||
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Failed to resolve Plural");
|
||||
}
|
||||
|
||||
return new UTF16String(buf, len);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
String* resolvePlural(double number);
|
||||
String* resolvePlural(ExecutionState& state, double number);
|
||||
|
||||
String* locale() const
|
||||
{
|
||||
|
|
@ -48,55 +48,86 @@ public:
|
|||
return m_type;
|
||||
}
|
||||
|
||||
String* notation() const
|
||||
{
|
||||
return m_notation;
|
||||
}
|
||||
|
||||
double minimumIntegerDigits() const
|
||||
{
|
||||
return m_minimumIntegerDigits;
|
||||
}
|
||||
|
||||
double minimumFractionDigits() const
|
||||
double roundingIncrement() const
|
||||
{
|
||||
return m_roundingIncrement;
|
||||
}
|
||||
|
||||
Value minimumFractionDigits() const
|
||||
{
|
||||
return m_minimumFractionDigits;
|
||||
}
|
||||
|
||||
double maximumFractionDigits() const
|
||||
Value maximumFractionDigits() const
|
||||
{
|
||||
return m_maximumFractionDigits;
|
||||
}
|
||||
|
||||
Optional<double> minimumSignificantDigits() const
|
||||
Value minimumSignificantDigits() const
|
||||
{
|
||||
return m_minimumSignificantDigits;
|
||||
}
|
||||
|
||||
Optional<double> maximumSignificantDigits() const
|
||||
Value maximumSignificantDigits() const
|
||||
{
|
||||
return m_maximumSignificantDigits;
|
||||
}
|
||||
|
||||
String* roundingMode() const
|
||||
{
|
||||
return m_roundingMode;
|
||||
}
|
||||
|
||||
String* trailingZeroDisplay() const
|
||||
{
|
||||
return m_trailingZeroDisplay;
|
||||
}
|
||||
|
||||
Intl::RoundingType roundingType() const
|
||||
{
|
||||
return m_roundingType;
|
||||
}
|
||||
|
||||
Intl::RoundingPriority computedRoundingPriority() const
|
||||
{
|
||||
return m_computedRoundingPriority;
|
||||
}
|
||||
|
||||
UPluralRules* icuPluralRules() const
|
||||
{
|
||||
return m_icuPluralRules;
|
||||
}
|
||||
|
||||
UNumberFormat* icuNumberFormat() const
|
||||
{
|
||||
return m_icuNumberFormat;
|
||||
}
|
||||
|
||||
void* operator new(size_t size);
|
||||
void* operator new[](size_t size) = delete;
|
||||
|
||||
protected:
|
||||
String* m_locale;
|
||||
String* m_type;
|
||||
String* m_notation;
|
||||
double m_minimumIntegerDigits;
|
||||
double m_minimumFractionDigits;
|
||||
double m_maximumFractionDigits;
|
||||
Optional<double> m_minimumSignificantDigits;
|
||||
Optional<double> m_maximumSignificantDigits;
|
||||
double m_roundingIncrement;
|
||||
Value m_minimumFractionDigits; // double or undefined
|
||||
Value m_maximumFractionDigits; // double or undefined
|
||||
Value m_minimumSignificantDigits; // double or undefined
|
||||
Value m_maximumSignificantDigits; // double or undefined
|
||||
String* m_roundingMode;
|
||||
String* m_trailingZeroDisplay;
|
||||
Intl::RoundingType m_roundingType;
|
||||
Intl::RoundingPriority m_computedRoundingPriority;
|
||||
|
||||
UPluralRules* m_icuPluralRules;
|
||||
UNumberFormat* m_icuNumberFormat;
|
||||
UNumberFormatter* m_icuNumberFormat;
|
||||
};
|
||||
|
||||
} // namespace Escargot
|
||||
|
|
|
|||
1
third_party/runtime_icu_binder/ICUPolyfill.h
vendored
1
third_party/runtime_icu_binder/ICUPolyfill.h
vendored
|
|
@ -179,6 +179,7 @@
|
|||
#define uplrules_select RuntimeICUBinder::ICU::instance().uplrules_select
|
||||
#define uplrules_getKeywords RuntimeICUBinder::ICU::instance().uplrules_getKeywords
|
||||
#define uplrules_selectWithFormat RuntimeICUBinder::ICU::instance().uplrules_selectWithFormat
|
||||
#define uplrules_selectFormatted RuntimeICUBinder::ICU::instance().uplrules_selectFormatted
|
||||
|
||||
#define ures_open RuntimeICUBinder::ICU::instance().ures_open
|
||||
#define ures_openDirect RuntimeICUBinder::ICU::instance().ures_openDirect
|
||||
|
|
|
|||
|
|
@ -169,6 +169,7 @@ namespace RuntimeICUBinder {
|
|||
F(uplrules_open, UPluralRules* (*)(const char* locale, UErrorCode* status), UPluralRules*) \
|
||||
F(uplrules_openForType, UPluralRules* (*)(const char* locale, UPluralType type, UErrorCode* status), UPluralRules*) \
|
||||
F(uplrules_selectWithFormat, int32_t (*)(const UPluralRules* uplrules, double number, const UNumberFormat* fmt, UChar* keyword, int32_t capacity, UErrorCode* status), int32_t) \
|
||||
F(uplrules_selectFormatted, int32_t (*)(const UPluralRules *uplrules, const struct UFormattedNumber* , UChar *, int32_t , UErrorCode *), int32_t) \
|
||||
F(unumf_openForSkeletonAndLocale, UNumberFormatter* (*)(const UChar* skeleton, int32_t skeletonLen, const char* locale, UErrorCode* ec), UNumberFormatter*) \
|
||||
F(unumf_openForSkeletonAndLocaleWithError, UNumberFormatter* (*)(const UChar* skeleton, int32_t skeletonLen, const char* locale, UParseError* perror, UErrorCode* ec), UNumberFormatter*) \
|
||||
F(unumf_openResult, UFormattedNumber* (*)(UErrorCode * ec), UFormattedNumber*) \
|
||||
|
|
|
|||
|
|
@ -4946,14 +4946,6 @@
|
|||
<test id="intl402/Locale/prototype/variants/name"><reason>TODO</reason></test>
|
||||
<test id="intl402/Locale/prototype/variants/prop-desc"><reason>TODO</reason></test>
|
||||
<test id="intl402/Locale/reject-duplicate-variants-in-tlang"><reason>TODO</reason></test>
|
||||
<test id="intl402/PluralRules/constructor-option-read-order"><reason>TODO</reason></test>
|
||||
<test id="intl402/PluralRules/constructor-options-throwing-getters"><reason>TODO</reason></test>
|
||||
<test id="intl402/PluralRules/default-options-object-prototype"><reason>TODO</reason></test>
|
||||
<test id="intl402/PluralRules/notation"><reason>TODO</reason></test>
|
||||
<test id="intl402/PluralRules/prototype/resolvedOptions/order"><reason>TODO</reason></test>
|
||||
<test id="intl402/PluralRules/prototype/resolvedOptions/plural-categories-order"><reason>TODO</reason></test>
|
||||
<test id="intl402/PluralRules/prototype/resolvedOptions/properties"><reason>TODO</reason></test>
|
||||
<test id="intl402/PluralRules/prototype/select/notation"><reason>TODO</reason></test>
|
||||
<test id="intl402/PluralRules/prototype/selectRange/default-en-us"><reason>TODO</reason></test>
|
||||
<test id="intl402/PluralRules/prototype/selectRange/invoked-as-func"><reason>TODO</reason></test>
|
||||
<test id="intl402/PluralRules/prototype/selectRange/length"><reason>TODO</reason></test>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue