Skip to content

Commit 130c407

Browse files
committed
More control over which collator to use in each situation
1 parent 4d7923a commit 130c407

10 files changed

Lines changed: 288 additions & 135 deletions

File tree

src/compiler/core.ts

Lines changed: 264 additions & 114 deletions
Large diffs are not rendered by default.

src/compiler/parser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6069,7 +6069,7 @@ namespace ts {
60696069
const checkJsDirectiveMatchResult = checkJsDirectiveRegEx.exec(comment);
60706070
if (checkJsDirectiveMatchResult) {
60716071
checkJsDirective = {
6072-
enabled: equateStrings(checkJsDirectiveMatchResult[1], "@ts-check", /*ignoreCase*/ true),
6072+
enabled: StringCollator.ordinalCaseInsensitive.equate(checkJsDirectiveMatchResult[1], "@ts-check"),
60736073
end: range.end,
60746074
pos: range.pos
60756075
};

src/compiler/program.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,12 +1101,14 @@ namespace ts {
11011101

11021102
// If '--lib' is not specified, include default library file according to '--target'
11031103
// otherwise, using options specified in '--lib' instead of '--target' default library file
1104+
1105+
// File-system ordering should use a predictable order
1106+
const collator = StringCollator.getPathCollator(!host.useCaseSensitiveFileNames());
11041107
if (!options.lib) {
1105-
return equateStrings(file.fileName, getDefaultLibraryFileName(), /*ignoreCase*/ !host.useCaseSensitiveFileNames());
1108+
return collator.equate(file.fileName, getDefaultLibraryFileName());
11061109
}
11071110
else {
1108-
const equalityComparer = host.useCaseSensitiveFileNames() ? equateStringsCaseSensitive : equateStringsCaseInsensitive;
1109-
return forEach(options.lib, libFileName => equalityComparer(file.fileName, combinePaths(defaultLibraryPath, libFileName)));
1111+
return forEach(options.lib, libFileName => collator.equate(file.fileName, combinePaths(defaultLibraryPath, libFileName)));
11101112
}
11111113
}
11121114

src/compiler/utilities.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3949,6 +3949,9 @@ namespace ts {
39493949
trySetLanguageAndTerritory(language, /*territory*/ undefined, errors);
39503950
}
39513951

3952+
// Set the locale for UI collation
3953+
StringCollator.uiLocale = locale;
3954+
39523955
function trySetLanguageAndTerritory(language: string, territory: string, errors?: Push<Diagnostic>): boolean {
39533956
const compilerFilePath = normalizePath(sys.getExecutingFilePath());
39543957
const containingDirectoryPath = getDirectoryPath(compilerFilePath);

src/harness/harness.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1698,7 +1698,9 @@ namespace Harness {
16981698

16991699
export function *iterateOutputs(outputFiles: Harness.Compiler.GeneratedFile[]): IterableIterator<[string, string]> {
17001700
// Collect, test, and sort the fileNames
1701-
outputFiles.sort((a, b) => ts.compareStrings(cleanName(a.fileName), cleanName(b.fileName)));
1701+
// As this uses the file system, use a predictable order
1702+
const collator = ts.StringCollator.getPathCollator(/*ignoreCase*/ false);
1703+
outputFiles.sort((a, b) => collator.compare(cleanName(a.fileName), cleanName(b.fileName)));
17021704
const dupeCase = ts.createMap<number>();
17031705
// Yield them
17041706
for (const outputFile of outputFiles) {

src/harness/unittests/compileOnSave.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ namespace ts.projectSystem {
1313
describe("CompileOnSave affected list", () => {
1414
function sendAffectedFileRequestAndCheckResult(session: server.Session, request: server.protocol.Request, expectedFileList: { projectFileName: string, files: FileOrFolder[] }[]) {
1515
const response = session.executeCommand(request).response as server.protocol.CompileOnSaveAffectedFileListSingleProject[];
16-
const actualResult = response.sort((list1, list2) => compareStrings(list1.projectFileName, list2.projectFileName));
17-
expectedFileList = expectedFileList.sort((list1, list2) => compareStrings(list1.projectFileName, list2.projectFileName));
16+
// File-system ordering should use a predictable order
17+
const collator = StringCollator.getPathCollator(/*ignoreCase*/ false);
18+
const actualResult = response.sort((list1, list2) => collator.compare(list1.projectFileName, list2.projectFileName));
19+
expectedFileList = expectedFileList.sort((list1, list2) => collator.compare(list1.projectFileName, list2.projectFileName));
1820

1921
assert.equal(actualResult.length, expectedFileList.length, `Actual result project number is different from the expected project number`);
2022

src/server/session.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1186,14 +1186,15 @@ namespace ts.server {
11861186

11871187
const completions = project.getLanguageService().getCompletionsAtPosition(file, position);
11881188
if (simplifiedResult) {
1189+
const comparer = StringCollator.uiCaseSensitive.compare;
11891190
return mapDefined<CompletionEntry, protocol.CompletionEntry>(completions && completions.entries, entry => {
11901191
if (completions.isMemberCompletion || (entry.name.toLowerCase().indexOf(prefix.toLowerCase()) === 0)) {
11911192
const { name, kind, kindModifiers, sortText, replacementSpan, hasAction } = entry;
11921193
const convertedSpan = replacementSpan ? this.decorateSpan(replacementSpan, scriptInfo) : undefined;
11931194
// Use `hasAction || undefined` to avoid serializing `false`.
11941195
return { name, kind, kindModifiers, sortText, replacementSpan: convertedSpan, hasAction: hasAction || undefined };
11951196
}
1196-
}).sort((a, b) => compareStrings(a.name, b.name));
1197+
}).sort((a, b) => comparer(a.name, b.name));
11971198
}
11981199
else {
11991200
return completions;

src/services/navigateTo.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -175,12 +175,8 @@ namespace ts.NavigateTo {
175175

176176
function compareNavigateToItems(i1: RawNavigateToItem, i2: RawNavigateToItem): number {
177177
// TODO(cyrusn): get the gamut of comparisons that VS already uses here.
178-
// Right now we just sort by kind first, and then by name of the item.
179-
// We first sort case insensitively. So "Aaa" will come before "bar".
180-
// Then we sort case sensitively, so "aaa" will come before "Aaa".
181178
return i1.matchKind - i2.matchKind ||
182-
compareStringsCaseInsensitive(i1.name, i2.name) ||
183-
compareStringsCaseSensitive(i1.name, i2.name);
179+
StringCollator.uiCaseSensitive.compare(i1.name, i2.name);
184180
}
185181

186182
function createNavigateToItem(rawItem: RawNavigateToItem): NavigateToItem {

src/services/navigationBar.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -368,13 +368,8 @@ namespace ts.NavigationBar {
368368

369369
function compareChildren(child1: NavigationBarNode, child2: NavigationBarNode): number {
370370
const name1 = tryGetName(child1.node), name2 = tryGetName(child2.node);
371-
if (name1 && name2) {
372-
const cmp = ts.compareStringsCaseInsensitive(name1, name2);
373-
return cmp !== 0 ? cmp : navigationBarNodeKind(child1) - navigationBarNodeKind(child2);
374-
}
375-
else {
376-
return name1 ? 1 : name2 ? -1 : navigationBarNodeKind(child1) - navigationBarNodeKind(child2);
377-
}
371+
return StringCollator.uiCaseInsensitive.compare(name1, name2)
372+
|| navigationBarNodeKind(child1) - navigationBarNodeKind(child2);
378373
}
379374

380375
/**

src/services/refactors/extractSymbol.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1154,7 +1154,9 @@ namespace ts.refactor.extractSymbol {
11541154

11551155
const name1 = type1.symbol ? type1.symbol.getName() : "";
11561156
const name2 = type2.symbol ? type2.symbol.getName() : "";
1157-
const nameDiff = compareStrings(name1, name2);
1157+
1158+
// This is for code generation, use a predictable comparer.
1159+
const nameDiff = StringCollator.invariantCaseSensitive.compare(name1, name2);
11581160
if (nameDiff !== 0) {
11591161
return nameDiff;
11601162
}

0 commit comments

Comments
 (0)