Skip to content

Commit 2bb4abc

Browse files
author
Yui T
committed
Use collator when making comparison as it is more performance than String.prototype.localeCompare
1 parent 65b1cf6 commit 2bb4abc

File tree

2 files changed

+10
-25
lines changed

2 files changed

+10
-25
lines changed

src/compiler/core.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ namespace ts {
2121
const createObject = Object.create;
2222

2323
// More efficient to create a collator once and use its `compare` than to call `a.localeCompare(b)` many times.
24-
export const collator: { compare(a: string, b: string): number } = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator() : undefined;
24+
export const collator: { compare(a: string, b: string): number } = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator(/*locales*/ undefined, { usage: "sort", sensitivity: "accent" }) : undefined;
25+
// Intl is missing in Safari, and node 0.10 treats "a" as greater than "B".
26+
export const localeCompareIsCorrect = ts.collator && ts.collator.compare("a", "B") < 0;
2527

2628
export function createMap<T>(template?: MapLike<T>): Map<T> {
2729
const map: Map<T> = createObject(null); // tslint:disable-line:no-null-keyword
@@ -1050,9 +1052,12 @@ namespace ts {
10501052
if (a === undefined) return Comparison.LessThan;
10511053
if (b === undefined) return Comparison.GreaterThan;
10521054
if (ignoreCase) {
1053-
if (collator && String.prototype.localeCompare) {
1054-
// accent means a ≠ b, a ≠ á, a = A
1055-
const result = a.localeCompare(b, /*locales*/ undefined, { usage: "sort", sensitivity: "accent" });
1055+
// Checking if "collator exists indicates that Intl is available.
1056+
// We still have to check if "collator.compare" is correct. If it is not, use "String.localeComapre"
1057+
if (collator) {
1058+
const result = localeCompareIsCorrect ?
1059+
collator.compare(a, b) :
1060+
a.localeCompare(b, /*locales*/ undefined, { usage: "sort", sensitivity: "accent" }); // accent means a ≠ b, a ≠ á, a = A
10561061
return result < 0 ? Comparison.LessThan : result > 0 ? Comparison.GreaterThan : Comparison.EqualTo;
10571062
}
10581063

src/services/navigationBar.ts

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -322,34 +322,14 @@ namespace ts.NavigationBar {
322322
function compareChildren(child1: NavigationBarNode, child2: NavigationBarNode): number {
323323
const name1 = tryGetName(child1.node), name2 = tryGetName(child2.node);
324324
if (name1 && name2) {
325-
const cmp = localeCompareFix(name1, name2);
325+
const cmp = ts.compareStringsCaseInsensitive(name1, name2);
326326
return cmp !== 0 ? cmp : navigationBarNodeKind(child1) - navigationBarNodeKind(child2);
327327
}
328328
else {
329329
return name1 ? 1 : name2 ? -1 : navigationBarNodeKind(child1) - navigationBarNodeKind(child2);
330330
}
331331
}
332332

333-
// Intl is missing in Safari, and node 0.10 treats "a" as greater than "B".
334-
const localeCompareIsCorrect = ts.collator && ts.collator.compare("a", "B") < 0;
335-
const localeCompareFix: (a: string, b: string) => number = localeCompareIsCorrect ? collator.compare : function(a, b) {
336-
// This isn't perfect, but it passes all of our tests.
337-
for (let i = 0; i < Math.min(a.length, b.length); i++) {
338-
const chA = a.charAt(i), chB = b.charAt(i);
339-
if (chA === "\"" && chB === "'") {
340-
return 1;
341-
}
342-
if (chA === "'" && chB === "\"") {
343-
return -1;
344-
}
345-
const cmp = ts.compareStrings(chA.toLocaleLowerCase(), chB.toLocaleLowerCase());
346-
if (cmp !== 0) {
347-
return cmp;
348-
}
349-
}
350-
return a.length - b.length;
351-
};
352-
353333
/**
354334
* This differs from getItemName because this is just used for sorting.
355335
* We only sort nodes by name that have a more-or-less "direct" name, as opposed to `new()` and the like.

0 commit comments

Comments
 (0)