Skip to content

Commit 5cc1df9

Browse files
committed
Project BuiltInFunctionIDs to Intl.js and correctly respect the usage setting for Intl.Collator
1 parent b987205 commit 5cc1df9

File tree

4 files changed

+107
-74
lines changed

4 files changed

+107
-74
lines changed

lib/Runtime/Base/JnDirectFields.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,12 @@ ENTRY(NumberFormatCurrencyDisplay)
539539
ENTRY(CollatorSensitivity)
540540
ENTRY(CollatorCaseFirst)
541541
ENTRY(LocaleDataKind)
542+
ENTRY(DateToLocaleString)
543+
ENTRY(DateToLocaleDateString)
544+
ENTRY(DateToLocaleTimeString)
545+
ENTRY(NumberToLocaleString)
546+
ENTRY(StringLocaleCompare)
547+
ENTRY(BuiltInFunctionID)
542548

543549
// This symbol is not part of the regular Symbol API and is only used in rare circumstances in Intl.js for backwards compatibility
544550
// with the Intl v1 spec. It is visible to the user only using Object.getOwnPropertySymbols(Intl.NumberFormat.call(new Intl.NumberFormat())).
@@ -581,6 +587,7 @@ ENTRY(numeric)
581587
ENTRY(sensitivity)
582588
ENTRY(sensitivityEnum)
583589
ENTRY(caseFirstEnum)
590+
ENTRY(usage)
584591

585592
ENTRY(DateTimeFormat)
586593
ENTRY(__boundFormat)

lib/Runtime/Library/InJavascript/Intl.js

Lines changed: 29 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -102,17 +102,6 @@
102102
var isFinite = platform.builtInGlobalObjectEntryIsFinite;
103103
var isNaN = platform.builtInGlobalObjectEntryIsNaN;
104104

105-
// Keep this "enum" in sync with IntlEngineInterfaceExtensionObject::EntryIntl_RegisterBuiltInFunction
106-
const IntlBuiltInFunctionID = setPrototype({
107-
MIN: 0,
108-
DateToLocaleString: 0,
109-
DateToLocaleDateString: 1,
110-
DateToLocaleTimeString: 2,
111-
NumberToLocaleString: 3,
112-
StringLocaleCompare: 4,
113-
MAX: 5
114-
}, null);
115-
116105
const _ = {
117106
toUpperCase(str) { return callInstanceFunc(StringInstanceToUpperCase, str); },
118107
toLowerCase(str) { return callInstanceFunc(StringInstanceToLowerCase, str); },
@@ -879,19 +868,28 @@
879868
const requestedLocales = CanonicalizeLocaleList(locales);
880869
options = options === undefined ? _.create() : Internal.ToObject(options);
881870

871+
// The spec says that usage dictates whether to use "[[SearchLocaleData]]" or "[[SortLocaleData]]"
872+
// ICU has no concept of a difference between the two, and instead sort/search corresponds to
873+
// collation = "standard" or collation = "search", respectively. Standard/sort is the default.
874+
// Thus, when the usage is sort, we can accept and honor -u-co in the locale, while if usage is search,
875+
// we are going to overwrite any -u-co value provided before giving the locale to ICU anyways.
876+
// To make the logic simpler, we can simply pretend like we don't accept a -u-co value if the usage is search.
877+
// See the lazy UCollator initialization in EntryIntl_LocaleCompare for where the collation value
878+
// gets overwritten by "search".
882879
collator.usage = GetOption(options, "usage", "string", ["sort", "search"], "sort");
883-
// TODO: determine the difference between sort and search locale data
884-
// const collatorLocaleData = collator.usage === "sort" ? localeData : localeData;
880+
const relevantExtensionKeys = collator.usage === "sort" ? ["co", "kn", "kf"] : ["kn", "kf"];
885881

886882
const opt = _.create();
887883
opt.matcher = GetOption(options, "localeMatcher", "string", ["lookup", "best fit"], "best fit");
888884
let kn = GetOption(options, "numeric", "boolean", undefined, undefined);
889885
opt.kn = kn === undefined ? kn : Internal.ToString(kn);
890886
opt.kf = GetOption(options, "caseFirst", "string", ["upper", "lower", "false"], undefined);
891887

892-
const r = ResolveLocale(platform.isCollatorLocaleAvailable, requestedLocales, opt, ["co", "kn", "kf"]);
888+
const r = ResolveLocale(platform.isCollatorLocaleAvailable, requestedLocales, opt, relevantExtensionKeys);
893889
collator.locale = r.locale;
894-
collator.collation = r.co === null ? "default" : r.co;
890+
// r.co is null when usage === "sort" and no -u-co is provided
891+
// r.co is undefined when usage === "search", since relevantExtensionKeys doesn't even look for -co
892+
collator.collation = r.co === null || r.co === undefined ? "default" : r.co;
895893
collator.numeric = r.kn === "true";
896894
collator.caseFirst = r.kf;
897895
collator.caseFirstEnum = platform.CollatorCaseFirst[collator.caseFirst];
@@ -932,7 +930,7 @@
932930
}
933931

934932
return platform.localeCompare(thisStr, thatStr, stateObject, /* forStringPrototypeLocaleCompare */ true);
935-
}), IntlBuiltInFunctionID.StringLocaleCompare);
933+
}), platform.BuiltInFunctionID.StringLocaleCompare);
936934

937935
// If we were only initializing Intl for String.prototype, don't initialize Intl.Collator
938936
if (InitType === "String") {
@@ -1128,7 +1126,7 @@
11281126

11291127
const n = Internal.ToNumber(this);
11301128
return platform.formatNumber(n, stateObject, /* toParts */ false, /* forNumberPrototypeToLocaleString */ true);
1131-
}), IntlBuiltInFunctionID.NumberToLocaleString);
1129+
}), platform.BuiltInFunctionID.NumberToLocaleString);
11321130

11331131
if (InitType === "Number") {
11341132
return;
@@ -1665,19 +1663,19 @@
16651663
platform.registerBuiltInFunction(createPublicMethod(name, function date_toLocaleString_entryPoint(locales = undefined, options = undefined) {
16661664
return DateInstanceToLocaleStringImplementation.call(this, name, option1, option2, cacheSlot, locales, options);
16671665
}), platformFunctionID);
1668-
})("Date.prototype.toLocaleString", "any", "all", __DateInstanceToLocaleStringDefaultCacheSlot.toLocaleString, IntlBuiltInFunctionID.DateToLocaleString);
1666+
})("Date.prototype.toLocaleString", "any", "all", __DateInstanceToLocaleStringDefaultCacheSlot.toLocaleString, platform.BuiltInFunctionID.DateToLocaleString);
16691667

16701668
(function (name, option1, option2, cacheSlot, platformFunctionID) {
16711669
platform.registerBuiltInFunction(createPublicMethod(name, function date_toLocaleDateString_entryPoint(locales = undefined, options = undefined) {
16721670
return DateInstanceToLocaleStringImplementation.call(this, name, option1, option2, cacheSlot, locales, options);
16731671
}), platformFunctionID);
1674-
})("Date.prototype.toLocaleDateString", "date", "date", __DateInstanceToLocaleStringDefaultCacheSlot.toLocaleDateString, IntlBuiltInFunctionID.DateToLocaleDateString);
1672+
})("Date.prototype.toLocaleDateString", "date", "date", __DateInstanceToLocaleStringDefaultCacheSlot.toLocaleDateString, platform.BuiltInFunctionID.DateToLocaleDateString);
16751673

16761674
(function (name, option1, option2, cacheSlot, platformFunctionID) {
16771675
platform.registerBuiltInFunction(createPublicMethod(name, function date_toLocaleTimeString_entryPoint(locales = undefined, options = undefined) {
16781676
return DateInstanceToLocaleStringImplementation.call(this, name, option1, option2, cacheSlot, locales, options);
16791677
}), platformFunctionID);
1680-
})("Date.prototype.toLocaleTimeString", "time", "time", __DateInstanceToLocaleStringDefaultCacheSlot.toLocaleTimeString, IntlBuiltInFunctionID.DateToLocaleTimeString);
1678+
})("Date.prototype.toLocaleTimeString", "time", "time", __DateInstanceToLocaleStringDefaultCacheSlot.toLocaleTimeString, platform.BuiltInFunctionID.DateToLocaleTimeString);
16811679

16821680
// if we were only initializing Date, dont bother initializing Intl.DateTimeFormat
16831681
if (InitType !== "Intl") {
@@ -2837,12 +2835,12 @@
28372835
thisArg,
28382836
that,
28392837
stateObject.__localeForCompare,
2840-
toEnum(CollatorSensitivity, stateObject.__sensitivity),
2838+
platform.CollatorSensitivity[stateObject.__sensitivity],
28412839
stateObject.__ignorePunctuation,
28422840
stateObject.__numeric,
2843-
toEnum(CollatorCaseFirst, stateObject.__caseFirst)
2841+
platform.CollatorCaseFirst[stateObject.__caseFirst]
28442842
));
2845-
}), IntlBuiltInFunctionID.StringLocaleCompare);
2843+
}), platform.BuiltInFunctionID.StringLocaleCompare);
28462844

28472845
if (InitType === 'Intl') {
28482846

@@ -2890,10 +2888,10 @@
28902888
a,
28912889
b,
28922890
hiddenObject.__localeForCompare,
2893-
toEnum(CollatorSensitivity, hiddenObject.__sensitivity),
2891+
platform.CollatorSensitivity[hiddenObject.__sensitivity],
28942892
hiddenObject.__ignorePunctuation,
28952893
hiddenObject.__numeric,
2896-
toEnum(CollatorCaseFirst, hiddenObject.__caseFirst)
2894+
platform.CollatorCaseFirst[hiddenObject.__caseFirst]
28972895
));
28982896
}
28992897
tagPublicFunction("Intl.Collator.prototype.compare", compare);
@@ -2973,12 +2971,7 @@
29732971
var matcher = GetOption(options, "localeMatcher", "string", ["lookup", "best fit"], "best fit");
29742972
var style = GetOption(options, "style", "string", ["decimal", "percent", "currency"], "decimal");
29752973

2976-
var formatterToUse = NumberFormatStyle.DECIMAL; // DEFAULT
2977-
if (style === 'percent') {
2978-
formatterToUse = NumberFormatStyle.PERCENT;
2979-
} else if (style === 'currency') {
2980-
formatterToUse = NumberFormatStyle.CURRENCY;
2981-
}
2974+
var formatterToUse = platform.NumberFormatStyle[style];
29822975

29832976
var currency = GetOption(options, "currency", "string", undefined, undefined);
29842977
var currencyDisplay = GetOption(options, 'currencyDisplay', 'string', ['code', 'symbol', 'name'], 'symbol');
@@ -3045,14 +3038,7 @@
30453038

30463039
if (currencyDisplay !== undefined) {
30473040
numberFormat.__currencyDisplay = currencyDisplay;
3048-
numberFormat.__currencyDisplayToUse = NumberFormatCurrencyDisplay.DEFAULT;
3049-
if (currencyDisplay === "symbol") {
3050-
numberFormat.__currencyDisplayToUse = NumberFormatCurrencyDisplay.SYMBOL;
3051-
} else if (currencyDisplay === "code") {
3052-
numberFormat.__currencyDisplayToUse = NumberFormatCurrencyDisplay.CODE;
3053-
} else if (currencyDisplay === "name") {
3054-
numberFormat.__currencyDisplayToUse = NumberFormatCurrencyDisplay.NAME;
3055-
}
3041+
numberFormat.__currencyDisplayToUse = platform.NumberFormatCurrencyDisplay[currencyDisplay];
30563042
}
30573043

30583044
numberFormat.__minimumIntegerDigits = minimumIntegerDigits;
@@ -3096,7 +3082,7 @@
30963082

30973083
var n = Internal.ToNumber(this);
30983084
return String(platform.formatNumber(n, stateObject));
3099-
}), IntlBuiltInFunctionID.NumberToLocaleString);
3085+
}), platform.BuiltInFunctionID.NumberToLocaleString);
31003086

31013087
if (InitType === 'Intl') {
31023088
function NumberFormat(locales = undefined, options = undefined) {
@@ -3618,19 +3604,19 @@
36183604
platform.registerBuiltInFunction(tagPublicFunction(name, function date_toLocaleString_entryPoint(locales = undefined, options = undefined) {
36193605
return DateInstanceToLocaleStringImplementation.call(this, name, option1, option2, cacheSlot, locales, options);
36203606
}), platformFunctionID);
3621-
})("Date.prototype.toLocaleString", "any", "all", __DateInstanceToLocaleStringDefaultCacheSlot.toLocaleString, IntlBuiltInFunctionID.DateToLocaleString);
3607+
})("Date.prototype.toLocaleString", "any", "all", __DateInstanceToLocaleStringDefaultCacheSlot.toLocaleString, platform.BuiltInFunctionID.DateToLocaleString);
36223608

36233609
(function (name, option1, option2, cacheSlot, platformFunctionID) {
36243610
platform.registerBuiltInFunction(tagPublicFunction(name, function date_toLocaleDateString_entryPoint(locales = undefined, options = undefined) {
36253611
return DateInstanceToLocaleStringImplementation.call(this, name, option1, option2, cacheSlot, locales, options);
36263612
}), platformFunctionID);
3627-
})("Date.prototype.toLocaleDateString", "date", "date", __DateInstanceToLocaleStringDefaultCacheSlot.toLocaleDateString, IntlBuiltInFunctionID.DateToLocaleDateString);
3613+
})("Date.prototype.toLocaleDateString", "date", "date", __DateInstanceToLocaleStringDefaultCacheSlot.toLocaleDateString, platform.BuiltInFunctionID.DateToLocaleDateString);
36283614

36293615
(function (name, option1, option2, cacheSlot, platformFunctionID) {
36303616
platform.registerBuiltInFunction(tagPublicFunction(name, function date_toLocaleTimeString_entryPoint(locales = undefined, options = undefined) {
36313617
return DateInstanceToLocaleStringImplementation.call(this, name, option1, option2, cacheSlot, locales, options);
36323618
}), platformFunctionID);
3633-
})("Date.prototype.toLocaleTimeString", "time", "time", __DateInstanceToLocaleStringDefaultCacheSlot.toLocaleTimeString, IntlBuiltInFunctionID.DateToLocaleTimeString);
3619+
})("Date.prototype.toLocaleTimeString", "time", "time", __DateInstanceToLocaleStringDefaultCacheSlot.toLocaleTimeString, platform.BuiltInFunctionID.DateToLocaleTimeString);
36343620

36353621
if (InitType === 'Intl') {
36363622
function DateTimeFormat(locales = undefined, options = undefined) {

0 commit comments

Comments
 (0)