[JSC] Intl.Collator should set usage:"search" option through ICU locale
https://bugs.webkit.org/show_bug.cgi?id=213869
Reviewed by Ross Kirsling.
JSTests:
* stress/intl-collator-co-extension.js: Added.
(shouldBe):
(shouldBeArray):
(explicitTrueBeforeICU67):
* test262/expectations.yaml:
Source/JavaScriptCore:
Intl.Collator has usage:"search" option, and it affects on collation. However, UCollator does not have an interface to set this collation option,
and only way to configure UCollator is setting "-u-co-search" unicode extension to passed locale string. This patch adds "-u-co-search" unicode
extension if Usage::Search is specified.
* runtime/IntlCollator.cpp:
(JSC::IntlCollator::initializeCollator):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@263833 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JSTests/ChangeLog b/JSTests/ChangeLog
index a63597f..1d9481d 100644
--- a/JSTests/ChangeLog
+++ b/JSTests/ChangeLog
@@ -1,3 +1,16 @@
+2020-07-01 Yusuke Suzuki <ysuzuki@apple.com>
+
+ [JSC] Intl.Collator should set usage:"search" option through ICU locale
+ https://bugs.webkit.org/show_bug.cgi?id=213869
+
+ Reviewed by Ross Kirsling.
+
+ * stress/intl-collator-co-extension.js: Added.
+ (shouldBe):
+ (shouldBeArray):
+ (explicitTrueBeforeICU67):
+ * test262/expectations.yaml:
+
2020-06-26 Yusuke Suzuki <ysuzuki@apple.com>
Update test262
diff --git a/JSTests/stress/intl-collator-co-extension.js b/JSTests/stress/intl-collator-co-extension.js
new file mode 100644
index 0000000..c148784
--- /dev/null
+++ b/JSTests/stress/intl-collator-co-extension.js
@@ -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", "ä", "æ"]);
diff --git a/JSTests/test262/expectations.yaml b/JSTests/test262/expectations.yaml
index f8b9dd9..dd77a7c 100644
--- a/JSTests/test262/expectations.yaml
+++ b/JSTests/test262/expectations.yaml
@@ -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'
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index c5db482..517bc8b 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,17 @@
+2020-07-01 Yusuke Suzuki <ysuzuki@apple.com>
+
+ [JSC] Intl.Collator should set usage:"search" option through ICU locale
+ https://bugs.webkit.org/show_bug.cgi?id=213869
+
+ Reviewed by Ross Kirsling.
+
+ Intl.Collator has usage:"search" option, and it affects on collation. However, UCollator does not have an interface to set this collation option,
+ and only way to configure UCollator is setting "-u-co-search" unicode extension to passed locale string. This patch adds "-u-co-search" unicode
+ extension if Usage::Search is specified.
+
+ * runtime/IntlCollator.cpp:
+ (JSC::IntlCollator::initializeCollator):
+
2020-07-01 Keith Miller <keith_miller@apple.com>
Rename zeroExtend32ToPtr to zeroExtend32ToWord
diff --git a/Source/JavaScriptCore/runtime/IntlCollator.cpp b/Source/JavaScriptCore/runtime/IntlCollator.cpp
index f00a66b..bc74977 100644
--- a/Source/JavaScriptCore/runtime/IntlCollator.cpp
+++ b/Source/JavaScriptCore/runtime/IntlCollator.cpp
@@ -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;