Skip to content

Commit

Permalink
[JSC] Canonicalize "true" unicode extension type value to ""
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=216224

Reviewed by Ross Kirsling.

JSTests:

* stress/intl-collator-co-extension.js:
(explicitTrueBeforeICU67): Deleted.
* stress/intl-collator.js:
(shouldBe.testCollator.Intl.Collator):
(explicitTrueBeforeICU67): Deleted.
* stress/intl-datetimeformat.js:
* stress/intl-locale.js:
* stress/intl-numberformat.js:
* stress/intl-object.js:
* stress/intl-pluralrules.js:
* stress/intl-relativetimeformat.js:
* test262/expectations.yaml:

Source/JavaScriptCore:

Unicode Technical Standard #35 defines that unicode extension type's "true" should be converged to "".
This patch implements it by extracting unicode extension subtags and replacing "true" to "".

* runtime/IntlLocale.cpp:
(JSC::LocaleIDBuilder::toCanonical):
(JSC::IntlLocale::keywordValue const):
(JSC::IntlLocale::calendar):
(JSC::IntlLocale::caseFirst):
(JSC::IntlLocale::collation):
(JSC::IntlLocale::hourCycle):
(JSC::IntlLocale::numberingSystem):
(JSC::IntlLocale::numeric):
* runtime/IntlLocale.h:
* runtime/IntlLocalePrototype.cpp:
(JSC::IntlLocalePrototypeGetterCalendar):
(JSC::IntlLocalePrototypeGetterCaseFirst):
(JSC::IntlLocalePrototypeGetterCollation):
(JSC::IntlLocalePrototypeGetterHourCycle):
(JSC::IntlLocalePrototypeGetterNumberingSystem):
* runtime/IntlObject.cpp:
(JSC::unicodeExtensionSubTags):
(JSC::canonicalizeUnicodeExtensionsAfterICULocaleCanonicalization):
(JSC::languageTagForLocaleID):
(JSC::resolveLocale):
* runtime/IntlObject.h:
* runtime/IntlObjectInlines.h:
(JSC::computeTwoCharacters16Code):
* runtime/StringPrototype.cpp:
(JSC::computeTwoCharacters16Code): Deleted.

Source/WTF:

* wtf/text/StringView.h:
(WTF::StringView::characterAt const):
(WTF::StringView::operator[] const):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@266973 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
[email protected] committed Sep 12, 2020
1 parent d7ade5b commit 3efeab1
Show file tree
Hide file tree
Showing 20 changed files with 249 additions and 117 deletions.
20 changes: 20 additions & 0 deletions JSTests/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
2020-09-11 Yusuke Suzuki <[email protected]>

[JSC] Canonicalize "true" unicode extension type value to ""
https://bugs.webkit.org/show_bug.cgi?id=216224

Reviewed by Ross Kirsling.

* stress/intl-collator-co-extension.js:
(explicitTrueBeforeICU67): Deleted.
* stress/intl-collator.js:
(shouldBe.testCollator.Intl.Collator):
(explicitTrueBeforeICU67): Deleted.
* stress/intl-datetimeformat.js:
* stress/intl-locale.js:
* stress/intl-numberformat.js:
* stress/intl-object.js:
* stress/intl-pluralrules.js:
* stress/intl-relativetimeformat.js:
* test262/expectations.yaml:

2020-09-11 Yusuke Suzuki <[email protected]>

[JSC] attribute-change transition should not pin Structure
Expand Down
8 changes: 2 additions & 6 deletions JSTests/stress/intl-collator-co-extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@ function shouldBeArray(actual, expected) {
}
}

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");
Expand All @@ -40,8 +36,8 @@ shouldBeArray(["2", "10"].sort(new Intl.Collator("de-U-kn-x-0", {usage: "search"

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());
shouldBe(new Intl.Collator("de-u-kn", {usage: "sort"}).resolvedOptions().locale, "de-u-kn");
shouldBe(new Intl.Collator("de-u-kn", {usage: "search"}).resolvedOptions().locale, "de-u-kn");

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", "æ"]);
Expand Down
12 changes: 4 additions & 8 deletions JSTests/stress/intl-collator.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@ function shouldThrow(func, errorType) {
throw new Error(`Expected ${errorType.name}!`);
}

function explicitTrueBeforeICU67() {
return $vm.icuVersion() < 67 ? '-true' : '';
}

// 10.1 The Intl.Collator Constructor

// The Intl.Collator constructor is a standard built-in property of the Intl object.
Expand Down Expand Up @@ -85,8 +81,8 @@ shouldBe(testCollator(Intl.Collator('en-u-co-abcd'), [{locale: 'en'}]), true);
shouldBe(testCollator(Intl.Collator('de-u-co-phonebk'), [{locale: 'de-u-co-phonebk', collation: 'phonebk'}, {locale: 'de'}]), true);

// The 'kn' key is processed correctly.
shouldBe(testCollator(Intl.Collator('en-u-kn'), [{locale: 'en-u-kn' + explicitTrueBeforeICU67(), numeric: true}]), true);
shouldBe(testCollator(Intl.Collator('en-u-kn-true'), [{locale: 'en-u-kn' + explicitTrueBeforeICU67(), numeric: true}]), true);
shouldBe(testCollator(Intl.Collator('en-u-kn'), [{locale: 'en-u-kn', numeric: true}]), true);
shouldBe(testCollator(Intl.Collator('en-u-kn-true'), [{locale: 'en-u-kn', numeric: true}]), true);
shouldBe(testCollator(Intl.Collator('en-u-kn-false'), [{locale: 'en-u-kn-false', numeric: false}]), true);
shouldBe(testCollator(Intl.Collator('en-u-kn-abcd'), [{locale: 'en'}]), true);

Expand Down Expand Up @@ -150,7 +146,7 @@ shouldThrow(() => Intl.Collator('en', { get ignorePunctuation() { throw new Erro
// Options override the language tag.
shouldBe(testCollator(Intl.Collator('en-u-kn-true', {numeric: false}), [{locale: 'en', numeric: false}]), true);
shouldBe(testCollator(Intl.Collator('en-u-kn-false', {numeric: true}), [{locale: 'en', numeric: true}]), true);
shouldBe(testCollator(Intl.Collator('en-u-kn-true', {numeric: true}), [{locale: 'en-u-kn' + explicitTrueBeforeICU67(), numeric: true}]), true);
shouldBe(testCollator(Intl.Collator('en-u-kn-true', {numeric: true}), [{locale: 'en-u-kn', numeric: true}]), true);
shouldBe(testCollator(Intl.Collator('en-u-kn-false', {numeric: false}), [{locale: 'en-u-kn-false', numeric: false}]), true);

// Options and extension keys are processed correctly.
Expand Down Expand Up @@ -192,7 +188,7 @@ shouldBe(
JSON.stringify(Intl.Collator.supportedLocalesOf('En-laTn-us-variAnt-fOObar-1abc-U-kn-tRue-A-aa-aaa-x-RESERVED')),
$vm.icuVersion() >= 67
? '["en-Latn-US-1abc-foobar-variant-a-aa-aaa-u-kn-x-reserved"]'
: '["en-Latn-US-variant-foobar-1abc-a-aa-aaa-u-kn-true-x-reserved"]'
: '["en-Latn-US-variant-foobar-1abc-a-aa-aaa-u-kn-x-reserved"]'
);
// Throws on problems with length, get, or toString.
shouldThrow(() => Intl.Collator.supportedLocalesOf(Object.create(null, { length: { get() { throw Error() } } })), Error);
Expand Down
2 changes: 1 addition & 1 deletion JSTests/stress/intl-datetimeformat.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ shouldBe(
JSON.stringify(Intl.DateTimeFormat.supportedLocalesOf('En-laTn-us-variAnt-fOObar-1abc-U-kn-tRue-A-aa-aaa-x-RESERVED')),
$vm.icuVersion() >= 67
? '["en-Latn-US-1abc-foobar-variant-a-aa-aaa-u-kn-x-reserved"]'
: '["en-Latn-US-variant-foobar-1abc-a-aa-aaa-u-kn-true-x-reserved"]'
: '["en-Latn-US-variant-foobar-1abc-a-aa-aaa-u-kn-x-reserved"]'
);
// Throws on problems with length, get, or toString.
shouldThrow(() => Intl.DateTimeFormat.supportedLocalesOf(Object.create(null, { length: { get() { throw new Error(); } } })), Error);
Expand Down
2 changes: 1 addition & 1 deletion JSTests/stress/intl-locale.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ shouldBe(
new Intl.Locale('En-laTn-us-variAnt-fOObar-1abc-U-kn-tRue-A-aa-aaa-x-RESERVED').toString(),
$vm.icuVersion() >= 67
? 'en-Latn-US-1abc-foobar-variant-a-aa-aaa-u-kn-x-reserved'
: 'en-Latn-US-variant-foobar-1abc-a-aa-aaa-u-kn-true-x-reserved'
: 'en-Latn-US-variant-foobar-1abc-a-aa-aaa-u-kn-x-reserved'
);
shouldBe(new Intl.Locale('cel-gaulish', { script: 'Arab', numberingSystem: 'gujr' }).toString(), 'xtg-Arab-u-nu-gujr-x-cel-gaulish');
shouldBe(new Intl.Locale('en-Latn-US-u-ca-gregory-co-phonebk-hc-h12-kf-upper-kn-false-nu-latn').toString(), 'en-Latn-US-u-ca-gregory-co-phonebk-hc-h12-kf-upper-kn-false-nu-latn');
Expand Down
2 changes: 1 addition & 1 deletion JSTests/stress/intl-numberformat.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ shouldBe(
JSON.stringify(Intl.NumberFormat.supportedLocalesOf('En-laTn-us-variAnt-fOObar-1abc-U-kn-tRue-A-aa-aaa-x-RESERVED')),
$vm.icuVersion() >= 67
? '["en-Latn-US-1abc-foobar-variant-a-aa-aaa-u-kn-x-reserved"]'
: '["en-Latn-US-variant-foobar-1abc-a-aa-aaa-u-kn-true-x-reserved"]'
: '["en-Latn-US-variant-foobar-1abc-a-aa-aaa-u-kn-x-reserved"]'
);
// Throws on problems with length, get, or toString.
shouldThrow(() => Intl.NumberFormat.supportedLocalesOf(Object.create(null, { length: { get() { throw new Error(); } } })), Error);
Expand Down
2 changes: 1 addition & 1 deletion JSTests/stress/intl-object.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ shouldBe(
JSON.stringify(Intl.getCanonicalLocales('En-laTn-us-variAnt-fOObar-1abc-U-kn-tRue-A-aa-aaa-x-RESERVED')),
$vm.icuVersion() >= 67
? '["en-Latn-US-1abc-foobar-variant-a-aa-aaa-u-kn-x-reserved"]'
: '["en-Latn-US-variant-foobar-1abc-a-aa-aaa-u-kn-true-x-reserved"]'
: '["en-Latn-US-variant-foobar-1abc-a-aa-aaa-u-kn-x-reserved"]'
);
// Throws on problems with length, get, or toString.
shouldThrow(() => Intl.getCanonicalLocales(Object.create(null, { length: { get() { throw new Error(); } } })), Error);
Expand Down
2 changes: 1 addition & 1 deletion JSTests/stress/intl-pluralrules.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ shouldBe(
JSON.stringify(Intl.PluralRules.supportedLocalesOf('En-laTn-us-variAnt-fOObar-1abc-U-kn-tRue-A-aa-aaa-x-RESERVED')),
$vm.icuVersion() >= 67
? '["en-Latn-US-1abc-foobar-variant-a-aa-aaa-u-kn-x-reserved"]'
: '["en-Latn-US-variant-foobar-1abc-a-aa-aaa-u-kn-true-x-reserved"]'
: '["en-Latn-US-variant-foobar-1abc-a-aa-aaa-u-kn-x-reserved"]'
);
// Throws on problems with length, get, or toString.
shouldThrow(() => Intl.PluralRules.supportedLocalesOf(Object.create(null, { length: { get() { throw new Error(); } } })), Error);
Expand Down
2 changes: 1 addition & 1 deletion JSTests/stress/intl-relativetimeformat.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ shouldBe(
JSON.stringify(Intl.RelativeTimeFormat.supportedLocalesOf('En-laTn-us-variAnt-fOObar-1abc-U-kn-tRue-A-aa-aaa-x-RESERVED')),
$vm.icuVersion() >= 67
? '["en-Latn-US-1abc-foobar-variant-a-aa-aaa-u-kn-x-reserved"]'
: '["en-Latn-US-variant-foobar-1abc-a-aa-aaa-u-kn-true-x-reserved"]'
: '["en-Latn-US-variant-foobar-1abc-a-aa-aaa-u-kn-x-reserved"]'
);

shouldThrow(() => Intl.RelativeTimeFormat.supportedLocalesOf('no-bok'), RangeError);
Expand Down
15 changes: 0 additions & 15 deletions JSTests/test262/expectations.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1452,9 +1452,6 @@ test/built-ins/TypedArrayConstructors/of/custom-ctor.js:
test/built-ins/TypedArrayConstructors/of/new-instance-using-custom-ctor.js:
default: 'TypeError: TypedArray.of requires its this argument to subclass a TypedArray constructor (Testing with Float64Array.)'
strict mode: 'TypeError: TypedArray.of requires its this argument to subclass a TypedArray constructor (Testing with Float64Array.)'
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/DateTimeFormat/prototype/format/timedatestyle-en.js:
default: 'Test262Error: Result for full with {} Expected SameValue(«14:12:47 PM Coordinated Universal Time», «14:12:47 Coordinated Universal Time») to be true'
strict mode: 'Test262Error: Result for full with {} Expected SameValue(«14:12:47 PM Coordinated Universal Time», «14:12:47 Coordinated Universal Time») to be true'
Expand Down Expand Up @@ -1497,9 +1494,6 @@ test/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-region.js:
test/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-subdivision.js:
default: 'Test262Error: Expected SameValue(«und-NO-u-sd-no23», «und-NO-u-sd-no50») to be true'
strict mode: 'Test262Error: Expected SameValue(«und-NO-u-sd-no23», «und-NO-u-sd-no50») to be true'
test/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-yes-to-true.js:
default: 'Test262Error: Expected SameValue(«und-u-kb-true», «und-u-kb») to be true'
strict mode: 'Test262Error: Expected SameValue(«und-u-kb-true», «und-u-kb») to be true'
test/intl402/Intl/getCanonicalLocales/unicode-ext-key-with-digit.js:
default: 'Test262Error: Expected SameValue(«en-u-0c-yes», «en-u-0c») to be true'
strict mode: 'Test262Error: Expected SameValue(«en-u-0c-yes», «en-u-0c») to be true'
Expand All @@ -1509,21 +1503,12 @@ test/intl402/Locale/constructor-apply-options-canonicalizes-twice.js:
test/intl402/Locale/constructor-non-iana-canon.js:
default: 'Test262Error: new Intl.Locale("mo").maximize().toString() returns "ro-Latn-RO" Expected SameValue(«ro», «ro-Latn-RO») to be true'
strict mode: 'Test262Error: new Intl.Locale("mo").maximize().toString() returns "ro-Latn-RO" Expected SameValue(«ro», «ro-Latn-RO») to be true'
test/intl402/Locale/constructor-options-numeric-undefined.js:
default: 'Test262Error: new Intl.Locale("en-u-kn-true", {numeric: undefined}).toString() returns "en-u-kn" Expected SameValue(«en-u-kn-true», «en-u-kn») to be true'
strict mode: 'Test262Error: new Intl.Locale("en-u-kn-true", {numeric: undefined}).toString() returns "en-u-kn" Expected SameValue(«en-u-kn-true», «en-u-kn») to be true'
test/intl402/Locale/constructor-options-numeric-valid.js:
default: 'Test262Error: new Intl.Locale("en", {numeric: true}).toString() returns "true" Expected SameValue(«en-u-kn-true», «en-u-kn») to be true'
strict mode: 'Test262Error: new Intl.Locale("en", {numeric: true}).toString() returns "true" Expected SameValue(«en-u-kn-true», «en-u-kn») to be true'
test/intl402/Locale/constructor-options-region-valid.js:
default: "Test262Error: new Intl.Locale('en', {region: \"554\"}).toString() returns \"en-NZ\" Expected SameValue(«en-554», «en-NZ») to be true"
strict mode: "Test262Error: new Intl.Locale('en', {region: \"554\"}).toString() returns \"en-NZ\" Expected SameValue(«en-554», «en-NZ») to be true"
test/intl402/Locale/constructor-tag.js:
default: 'Test262Error: new Intl.Locale("sl-ROZAJ-BISKE-1994").toString() returns "sl-1994-biske-rozaj" Expected SameValue(«sl-rozaj-biske-1994», «sl-1994-biske-rozaj») to be true'
strict mode: 'Test262Error: new Intl.Locale("sl-ROZAJ-BISKE-1994").toString() returns "sl-1994-biske-rozaj" Expected SameValue(«sl-rozaj-biske-1994», «sl-1994-biske-rozaj») to be true'
test/intl402/Locale/getters.js:
default: 'Test262Error: Expected SameValue(«de-Latn-DE-u-ca-gregory-co-phonebk-hc-h23-kf-true-kn-false-nu-latn», «de-Latn-DE-u-ca-gregory-co-phonebk-hc-h23-kf-kn-false-nu-latn») to be true'
strict mode: 'Test262Error: Expected SameValue(«de-Latn-DE-u-ca-gregory-co-phonebk-hc-h23-kf-true-kn-false-nu-latn», «de-Latn-DE-u-ca-gregory-co-phonebk-hc-h23-kf-kn-false-nu-latn») to be true'
test/intl402/Locale/likely-subtags-grandfathered.js:
default: 'Test262Error: Expected SameValue(«cmn», «zh») to be true'
strict mode: 'Test262Error: Expected SameValue(«cmn», «zh») to be true'
Expand Down
37 changes: 37 additions & 0 deletions Source/JavaScriptCore/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,40 @@
2020-09-11 Yusuke Suzuki <[email protected]>

[JSC] Canonicalize "true" unicode extension type value to ""
https://bugs.webkit.org/show_bug.cgi?id=216224

Reviewed by Ross Kirsling.

Unicode Technical Standard #35 defines that unicode extension type's "true" should be converged to "".
This patch implements it by extracting unicode extension subtags and replacing "true" to "".

* runtime/IntlLocale.cpp:
(JSC::LocaleIDBuilder::toCanonical):
(JSC::IntlLocale::keywordValue const):
(JSC::IntlLocale::calendar):
(JSC::IntlLocale::caseFirst):
(JSC::IntlLocale::collation):
(JSC::IntlLocale::hourCycle):
(JSC::IntlLocale::numberingSystem):
(JSC::IntlLocale::numeric):
* runtime/IntlLocale.h:
* runtime/IntlLocalePrototype.cpp:
(JSC::IntlLocalePrototypeGetterCalendar):
(JSC::IntlLocalePrototypeGetterCaseFirst):
(JSC::IntlLocalePrototypeGetterCollation):
(JSC::IntlLocalePrototypeGetterHourCycle):
(JSC::IntlLocalePrototypeGetterNumberingSystem):
* runtime/IntlObject.cpp:
(JSC::unicodeExtensionSubTags):
(JSC::canonicalizeUnicodeExtensionsAfterICULocaleCanonicalization):
(JSC::languageTagForLocaleID):
(JSC::resolveLocale):
* runtime/IntlObject.h:
* runtime/IntlObjectInlines.h:
(JSC::computeTwoCharacters16Code):
* runtime/StringPrototype.cpp:
(JSC::computeTwoCharacters16Code): Deleted.

2020-09-11 Yusuke Suzuki <[email protected]>

[JSC] attribute-change transition should not pin Structure
Expand Down
39 changes: 23 additions & 16 deletions Source/JavaScriptCore/runtime/IntlLocale.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,12 @@ CString LocaleIDBuilder::toCanonical()
{
ASSERT(m_buffer.size());

Vector<char, 32> result;
auto status = callBufferProducingFunction(uloc_canonicalize, m_buffer.data(), result);
Vector<char, 32> buffer;
auto status = callBufferProducingFunction(uloc_canonicalize, m_buffer.data(), buffer);
if (U_FAILURE(status))
return CString();

auto result = canonicalizeUnicodeExtensionsAfterICULocaleCanonicalization(WTFMove(buffer));
return CString(result.data(), result.size());
}

Expand Down Expand Up @@ -189,9 +190,15 @@ String IntlLocale::keywordValue(ASCIILiteral key, bool isBoolean) const
uloc_getKeywordValue(m_localeID.data(), key.characters(), buffer.data(), bufferLength + 1, &status);
}
ASSERT(U_SUCCESS(status));

const char* value = !isBoolean ? uloc_toUnicodeLocaleType(key.characters(), buffer.data()) : buffer.data();
return value ? String(value) : emptyString();
if (isBoolean)
return String(buffer.data());
const char* value = uloc_toUnicodeLocaleType(key.characters(), buffer.data());
if (!value)
return nullString();
String result(value);
if (result == "true"_s)
return emptyString();
return result;
}

// https://tc39.es/ecma402/#sec-Intl.Locale
Expand Down Expand Up @@ -404,49 +411,49 @@ const String& IntlLocale::region()
// https://tc39.es/ecma402/#sec-Intl.Locale.prototype.calendar
const String& IntlLocale::calendar()
{
if (m_calendar.isNull())
if (!m_calendar)
m_calendar = keywordValue("calendar"_s);
return m_calendar;
return m_calendar.value();
}

// https://tc39.es/ecma402/#sec-Intl.Locale.prototype.caseFirst
const String& IntlLocale::caseFirst()
{
if (m_caseFirst.isNull())
if (!m_caseFirst)
m_caseFirst = keywordValue("colcasefirst"_s);
return m_caseFirst;
return m_caseFirst.value();
}

// https://tc39.es/ecma402/#sec-Intl.Locale.prototype.collation
const String& IntlLocale::collation()
{
if (m_collation.isNull())
if (!m_collation)
m_collation = keywordValue("collation"_s);
return m_collation;
return m_collation.value();
}

// https://tc39.es/ecma402/#sec-Intl.Locale.prototype.hourCycle
const String& IntlLocale::hourCycle()
{
if (m_hourCycle.isNull())
if (!m_hourCycle)
m_hourCycle = keywordValue("hours"_s);
return m_hourCycle;
return m_hourCycle.value();
}

// https://tc39.es/ecma402/#sec-Intl.Locale.prototype.numberingSystem
const String& IntlLocale::numberingSystem()
{
if (m_numberingSystem.isNull())
if (!m_numberingSystem)
m_numberingSystem = keywordValue("numbers"_s);
return m_numberingSystem;
return m_numberingSystem.value();
}

// https://tc39.es/ecma402/#sec-Intl.Locale.prototype.numeric
TriState IntlLocale::numeric()
{
constexpr bool isBoolean = true;
if (m_numeric == TriState::Indeterminate)
m_numeric = triState(keywordValue("colnumeric"_s, isBoolean) == "yes");
m_numeric = triState(keywordValue("colnumeric"_s, isBoolean) == "yes"_s);
return m_numeric;
}

Expand Down
11 changes: 6 additions & 5 deletions Source/JavaScriptCore/runtime/IntlLocale.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class IntlLocale final : public JSNonFinalObject {
const String& language();
const String& script();
const String& region();

const String& calendar();
const String& caseFirst();
const String& collation();
Expand All @@ -83,11 +84,11 @@ class IntlLocale final : public JSNonFinalObject {
String m_language;
String m_script;
String m_region;
String m_calendar;
String m_caseFirst;
String m_collation;
String m_hourCycle;
String m_numberingSystem;
Optional<String> m_calendar;
Optional<String> m_caseFirst;
Optional<String> m_collation;
Optional<String> m_hourCycle;
Optional<String> m_numberingSystem;
TriState m_numeric { TriState::Indeterminate };
};

Expand Down
Loading

0 comments on commit 3efeab1

Please sign in to comment.