Added: trunk/JSTests/stress/intl-collator-co-extension.js (0 => 263833)
--- trunk/JSTests/stress/intl-collator-co-extension.js (rev 0)
+++ trunk/JSTests/stress/intl-collator-co-extension.js 2020-07-02 06:00:36 UTC (rev 263833)
@@ -0,0 +1,49 @@
+function shouldBe(actual, expected) {
+ if (actual !== expected)
+ throw new Error('bad value: ' + actual);
+}
+
+function shouldBeArray(actual, expected) {
+ shouldBe(actual.length, expected.length);
+ for (var i = 0; i < expected.length; ++i) {
+ try {
+ shouldBe(actual[i], expected[i]);
+ } catch(e) {
+ print(JSON.stringify(actual));
+ throw e;
+ }
+ }
+}
+
+function explicitTrueBeforeICU67() {
+ return $vm.icuVersion() < 67 ? '-true' : '';
+}
+
+shouldBeArray(["AE", "\u00C4"].sort(new Intl.Collator("de", {usage: "sort"}).compare), ["\u00C4", "AE"]);
+shouldBeArray(["AE", "\u00C4"].sort(new Intl.Collator("de", {usage: "search"}).compare), ["AE", "\u00C4"]);
+shouldBe(new Intl.Collator("de", {usage: "sort"}).resolvedOptions().locale, "de");
+shouldBe(new Intl.Collator("de", {usage: "search"}).resolvedOptions().locale, "de");
+shouldBeArray(["2", "10"].sort(new Intl.Collator("de", {usage: "sort"}).compare), ["10", "2"]);
+shouldBeArray(["2", "10"].sort(new Intl.Collator("de", {usage: "search"}).compare), ["10", "2"]);
+
+shouldBeArray(["AE", "\u00C4"].sort(new Intl.Collator("de-u-co-search", {usage: "sort"}).compare), ["\u00C4", "AE"]);
+shouldBeArray(["AE", "\u00C4"].sort(new Intl.Collator("de-u-co-sort", {usage: "search"}).compare), ["AE", "\u00C4"]);
+shouldBe(new Intl.Collator("de-u-co-search", {usage: "sort"}).resolvedOptions().locale, "de");
+shouldBe(new Intl.Collator("de-u-co-sort", {usage: "search"}).resolvedOptions().locale, "de");
+
+shouldBeArray(["AE", "\u00C4"].sort(new Intl.Collator("de-u-kn", {usage: "sort"}).compare), ["\u00C4", "AE"]);
+shouldBeArray(["AE", "\u00C4"].sort(new Intl.Collator("de-u-kn", {usage: "search"}).compare), ["AE", "\u00C4"]);
+shouldBeArray(["2", "10"].sort(new Intl.Collator("de-u-kn", {usage: "sort"}).compare), ["2", "10"]);
+shouldBeArray(["2", "10"].sort(new Intl.Collator("de-u-kn", {usage: "search"}).compare), ["2", "10"]);
+shouldBeArray(["2", "10"].sort(new Intl.Collator("de-U-kn", {usage: "sort"}).compare), ["2", "10"]);
+shouldBeArray(["2", "10"].sort(new Intl.Collator("de-U-kn-x-0", {usage: "search"}).compare), ["2", "10"]);
+
+shouldBe(new Intl.Collator("en-US-x-twain", {usage: "search"}).resolvedOptions().locale, "en-US");
+
+shouldBe(new Intl.Collator("de-u-kn", {usage: "sort"}).resolvedOptions().locale, "de-u-kn" + explicitTrueBeforeICU67());
+shouldBe(new Intl.Collator("de-u-kn", {usage: "search"}).resolvedOptions().locale, "de-u-kn" + explicitTrueBeforeICU67());
+
+shouldBeArray(["a", "ae", "ä", "æ"].sort(new Intl.Collator("de-u-co-phonebk").compare), ["a", "ae", "ä", "æ"]);
+shouldBeArray(["a", "ae", "ä", "æ"].sort(new Intl.Collator("de").compare), ["a", "ä", "ae", "æ"]);
+shouldBeArray(["a", "ae", "ä", "æ"].sort(new Intl.Collator("de-u-co-phonebk", { usage: 'search' }).compare), ["a", "ae", "ä", "æ"]);
+shouldBeArray(["a", "ae", "ä", "æ"].sort(new Intl.Collator("de", { usage: 'search' }).compare), ["a", "ae", "ä", "æ"]);
Modified: trunk/JSTests/test262/expectations.yaml (263832 => 263833)
--- trunk/JSTests/test262/expectations.yaml 2020-07-02 05:02:18 UTC (rev 263832)
+++ trunk/JSTests/test262/expectations.yaml 2020-07-02 06:00:36 UTC (rev 263833)
@@ -1605,9 +1605,6 @@
test/intl402/Collator/missing-unicode-ext-value-defaults-to-true.js:
default: "Test262Error: \"kn-true\" is returned in locale, but shouldn't be. Expected SameValue(«7», «-1») to be true"
strict mode: "Test262Error: \"kn-true\" is returned in locale, but shouldn't be. Expected SameValue(«7», «-1») to be true"
-test/intl402/Collator/usage-de.js:
- default: 'Test262Error: Expected [Ä, AE] and [AE, Ä] to have the same contents. search'
- strict mode: 'Test262Error: Expected [Ä, AE] and [AE, Ä] to have the same contents. search'
test/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-default.js:
default: 'Test262Error: Expected SameValue(«h24», «h23») to be true'
strict mode: 'Test262Error: Expected SameValue(«h24», «h23») to be true'
Modified: trunk/Source/_javascript_Core/runtime/IntlCollator.cpp (263832 => 263833)
--- trunk/Source/_javascript_Core/runtime/IntlCollator.cpp 2020-07-02 05:02:18 UTC (rev 263832)
+++ trunk/Source/_javascript_Core/runtime/IntlCollator.cpp 2020-07-02 06:00:36 UTC (rev 263833)
@@ -43,6 +43,7 @@
constexpr size_t collationIndex = 0;
constexpr size_t caseFirstIndex = 1;
constexpr size_t numericIndex = 2;
+constexpr bool verbose = false;
}
void IntlCollator::UCollatorDeleter::operator()(UCollator* collator) const
@@ -240,8 +241,23 @@
RETURN_IF_EXCEPTION(scope, void());
m_ignorePunctuation = (ignorePunctuation == TriState::True);
+ // UCollator does not offer an option to configure "usage" via ucol_setAttribute. So we need to pass this option via locale.
+ CString dataLocaleWithExtensions;
+ switch (m_usage) {
+ case Usage::Sort:
+ dataLocaleWithExtensions = m_locale.utf8();
+ break;
+ case Usage::Search:
+ // searchLocaleData filters out "co" unicode extension. However, we need to pass "co" to ICU when Usage::Search is specified.
+ // So we need to pass "co" unicode extension through locale. Since the other relevant extensions are handled via ucol_setAttribute,
+ // we can just use dataLocale
+ dataLocaleWithExtensions = makeString(result.get("dataLocale"_s), "-u-co-search").utf8();
+ break;
+ }
+ dataLogLnIf(IntlCollatorInternal::verbose, "dataLocaleWithExtensions:(", dataLocaleWithExtensions, ")");
+
UErrorCode status = U_ZERO_ERROR;
- m_collator = std::unique_ptr<UCollator, UCollatorDeleter>(ucol_open(m_locale.utf8().data(), &status));
+ m_collator = std::unique_ptr<UCollator, UCollatorDeleter>(ucol_open(dataLocaleWithExtensions.data(), &status));
if (U_FAILURE(status)) {
throwTypeError(globalObject, scope, "failed to initialize Collator"_s);
return;