Merge pull request #11683 from Microsoft/useCollator_toImprovcePerformance

Remove localeFix function and use collator object when we can
This commit is contained in:
Yui 2017-01-18 14:03:57 -08:00 committed by GitHub
commit d36cd9b51b
2 changed files with 10 additions and 25 deletions

View File

@ -24,7 +24,9 @@ namespace ts {
}
// More efficient to create a collator once and use its `compare` than to call `a.localeCompare(b)` many times.
export const collator: { compare(a: string, b: string): number } = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator() : undefined;
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;
// Intl is missing in Safari, and node 0.10 treats "a" as greater than "B".
export const localeCompareIsCorrect = ts.collator && ts.collator.compare("a", "B") < 0;
/** Create a MapLike with good performance. */
function createDictionaryObject<T>(): MapLike<T> {
@ -1247,9 +1249,12 @@ namespace ts {
if (a === undefined) return Comparison.LessThan;
if (b === undefined) return Comparison.GreaterThan;
if (ignoreCase) {
if (collator && String.prototype.localeCompare) {
// accent means a ≠ b, a ≠ á, a = A
const result = a.localeCompare(b, /*locales*/ undefined, { usage: "sort", sensitivity: "accent" });
// Checking if "collator exists indicates that Intl is available.
// We still have to check if "collator.compare" is correct. If it is not, use "String.localeComapre"
if (collator) {
const result = localeCompareIsCorrect ?
collator.compare(a, b) :
a.localeCompare(b, /*locales*/ undefined, { usage: "sort", sensitivity: "accent" }); // accent means a ≠ b, a ≠ á, a = A
return result < 0 ? Comparison.LessThan : result > 0 ? Comparison.GreaterThan : Comparison.EqualTo;
}

View File

@ -322,7 +322,7 @@ namespace ts.NavigationBar {
function compareChildren(child1: NavigationBarNode, child2: NavigationBarNode): number {
const name1 = tryGetName(child1.node), name2 = tryGetName(child2.node);
if (name1 && name2) {
const cmp = localeCompareFix(name1, name2);
const cmp = ts.compareStringsCaseInsensitive(name1, name2);
return cmp !== 0 ? cmp : navigationBarNodeKind(child1) - navigationBarNodeKind(child2);
}
else {
@ -330,26 +330,6 @@ namespace ts.NavigationBar {
}
}
// Intl is missing in Safari, and node 0.10 treats "a" as greater than "B".
const localeCompareIsCorrect = ts.collator && ts.collator.compare("a", "B") < 0;
const localeCompareFix: (a: string, b: string) => number = localeCompareIsCorrect ? collator.compare : function(a, b) {
// This isn't perfect, but it passes all of our tests.
for (let i = 0; i < Math.min(a.length, b.length); i++) {
const chA = a.charAt(i), chB = b.charAt(i);
if (chA === "\"" && chB === "'") {
return 1;
}
if (chA === "'" && chB === "\"") {
return -1;
}
const cmp = ts.compareStrings(chA.toLocaleLowerCase(), chB.toLocaleLowerCase());
if (cmp !== 0) {
return cmp;
}
}
return a.length - b.length;
};
/**
* This differs from getItemName because this is just used for sorting.
* We only sort nodes by name that have a more-or-less "direct" name, as opposed to `new()` and the like.