Use collation and ignorePunctuation option correctly in Intl.Collator

Signed-off-by: Seonghyun Kim <sh8281.kim@samsung.com>
This commit is contained in:
Seonghyun Kim 2025-07-18 17:16:38 +09:00 committed by Patrick Kim
commit 8d890f97ec
4 changed files with 22 additions and 10 deletions

View file

@ -203,6 +203,14 @@ void IntlCollator::initialize(ExecutionState& state, Object* collator, Context*
// Set opt.[[localeMatcher]] to matcher.
opt.insert(std::make_pair("localeMatcher", matcher.toString(state)));
Value collation = Intl::getOption(state, options.asObject(), state.context()->staticStrings().collation.string(), Intl::StringValue, nullptr, 0, Value());
if (!collation.isUndefined()) {
if (!Intl::isValidUnicodeLocaleIdentifierTypeNonterminalOrTypeSequence(collation.asString())) {
ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "collation is not a well-formed");
}
opt.insert(std::make_pair("co", collation.asString()));
}
// Table 1 Collator options settable through both extension keys and options properties
// Key Property Type Values
// kn numeric "boolean"
@ -317,13 +325,12 @@ void IntlCollator::initialize(ExecutionState& state, Object* collator, Context*
}
// Let ip be the result of calling the GetOption abstract operation with arguments options, "ignorePunctuation", "boolean", undefined, and false.
Value ip = Intl::getOption(state, options.asObject(), state.context()->staticStrings().lazyIgnorePunctuation().string(), Intl::BooleanValue, nullptr, 0, Value(false));
Value ip = Intl::getOption(state, options.asObject(), state.context()->staticStrings().lazyIgnorePunctuation().string(), Intl::BooleanValue, nullptr, 0, Value());
// Set the [[ignorePunctuation]] internal property of collator to ip.
collator->ensureInternalSlot(state)->defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().lazyIgnorePunctuation()), ObjectPropertyDescriptor(ip));
collator->ensureInternalSlot(state)->defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().lazyIgnorePunctuation()), ObjectPropertyDescriptor(ip.isUndefined() ? Value(false) : ip, ObjectPropertyDescriptor::WritablePresent));
// Set the [[boundCompare]] internal property of collator to undefined.
// Set the [[initializedCollator]] internal property of collator to true.
collator->ensureInternalSlot(state)->defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().lazyInitializedCollator()), ObjectPropertyDescriptor(Value(true)));
// Return collator.
{
Object* internalSlot = collator->internalSlot();
@ -332,7 +339,7 @@ void IntlCollator::initialize(ExecutionState& state, Object* collator, Context*
String* locale = opt.locale;
UColAttributeValue strength = UCOL_DEFAULT;
UColAttributeValue caseLevel = UCOL_OFF;
UColAttributeValue alternate = UCOL_DEFAULT;
UColAttributeValue alternate = ip.isUndefined() ? UCOL_DEFAULT : UCOL_NON_IGNORABLE;
UColAttributeValue numeric = UCOL_OFF;
UColAttributeValue normalization = UCOL_ON; // normalization is always on. ecma-402 needs this
UColAttributeValue caseFirst = UCOL_DEFAULT;
@ -413,6 +420,15 @@ void IntlCollator::initialize(ExecutionState& state, Object* collator, Context*
},
nullptr);
}
if (ip.isUndefined()) {
UErrorCode status = U_ZERO_ERROR;
auto result = ucol_getAttribute((UCollator*)collator->internalSlot()->extraData(), UCOL_ALTERNATE_HANDLING, &status);
ASSERT(U_SUCCESS(status));
ip = Value(result == UCOL_SHIFTED);
collator->ensureInternalSlot(state)->defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().lazyIgnorePunctuation()), ObjectPropertyDescriptor(ip));
}
// Return collator.
}
int IntlCollator::compare(ExecutionState& state, Object* collator, String* a, String* b)

View file

@ -77,6 +77,7 @@
#define ucol_close RuntimeICUBinder::ICU::instance().ucol_close
#define ucol_getKeywordValues RuntimeICUBinder::ICU::instance().ucol_getKeywordValues
#define ucol_getKeywordValuesForLocale RuntimeICUBinder::ICU::instance().ucol_getKeywordValuesForLocale
#define ucol_getAttribute RuntimeICUBinder::ICU::instance().ucol_getAttribute
#define ucol_open RuntimeICUBinder::ICU::instance().ucol_open
#define ucol_strcollIter RuntimeICUBinder::ICU::instance().ucol_strcollIter
#define ucol_strcoll RuntimeICUBinder::ICU::instance().ucol_strcoll

View file

@ -109,6 +109,7 @@ namespace RuntimeICUBinder {
F(ucol_getAvailable, const char* (*)(int32_t), const char*) \
F(ucol_getKeywordValues, UEnumeration* (*)(const char* key, UErrorCode* status), UEnumeration*) \
F(ucol_getKeywordValuesForLocale, UEnumeration* (*)(const char* key, const char* locale, UBool commonlyUsed, UErrorCode* status), UEnumeration*) \
F(ucol_getAttribute, UColAttributeValue (*)(const UCollator *coll, UColAttribute attr, UErrorCode *status), UColAttributeValue) \
F(ucol_open, UCollator* (*)(const char* loc, UErrorCode* status), UCollator*) \
F(ucol_strcollIter, UCollationResult (*)(const UCollator* coll, UCharIterator* sIter, UCharIterator* tIter, UErrorCode* status), UCollationResult) \
F(ucol_strcoll, UCollationResult (*)(const UCollator* coll, const UChar* source, int32_t sourceLength, const UChar* target, int32_t targetLength), UCollationResult) \

View file

@ -4635,10 +4635,6 @@
<test id="harness/asyncHelpers-asyncTest-return-not-thenable"><reason>TODO</reason></test>
<test id="harness/asyncHelpers-asyncTest-without-async-flag"><reason>TODO</reason></test>
<test id="harness/asyncHelpers-throwsAsync-func-never-settles"><reason>TODO</reason></test>
<test id="intl402/Collator/constructor-options-throwing-getters"><reason>TODO</reason></test>
<test id="intl402/Collator/prototype/compare/ignorePunctuation"><reason>TODO</reason></test>
<test id="intl402/Collator/prototype/resolvedOptions/ignorePunctuation-default"><reason>TODO</reason></test>
<test id="intl402/Collator/prototype/resolvedOptions/resolved-collation-unicode-extensions-and-options"><reason>TODO</reason></test>
<test id="intl402/DateTimeFormat/canonicalize-calendar"><reason>TODO</reason></test>
<test id="intl402/DateTimeFormat/canonicalize-timezone"><reason>TODO</reason></test>
<test id="intl402/DateTimeFormat/canonicalize-utc-timezone"><reason>TODO</reason></test>
@ -4840,7 +4836,6 @@
<test id="intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-timezone"><reason>TODO</reason></test>
<test id="intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-yes-to-true"><reason>TODO</reason></test>
<test id="intl402/Intl/getCanonicalLocales/unicode-ext-key-with-digit"><reason>TODO</reason></test>
<test id="intl402/Intl/supportedValuesOf/collations-accepted-by-Collator"><reason>TODO</reason></test>
<test id="intl402/Locale/constructor-apply-options-canonicalizes-twice"><reason>TODO</reason></test>
<test id="intl402/Locale/constructor-getter-order"><reason>TODO</reason></test>
<test id="intl402/Locale/constructor-options-canonicalized"><reason>TODO</reason></test>
@ -6173,7 +6168,6 @@
<test id="staging/sm/TypedArray/element-setting-converts-using-ToNumber"><reason>TODO</reason></test>
<test id="staging/sm/TypedArray/find-and-findIndex"><reason>TODO</reason></test>
<test id="staging/sm/TypedArray/findLast-and-findLastIndex"><reason>TODO</reason></test>
<test id="staging/sm/TypedArray/indexOf-and-lastIndexOf"><reason>TODO</reason></test>
<test id="staging/sm/TypedArray/prototype-constructor-identity"><reason>TODO</reason></test>
<test id="staging/sm/TypedArray/set-with-receiver"><reason>TODO</reason></test>
<test id="staging/sm/TypedArray/sort-negative-nan"><reason>TODO</reason></test>