Further simplification

This commit is contained in:
Ron Buckton 2017-10-26 11:56:29 -07:00
parent e08f8d263f
commit 24437774a8
7 changed files with 77 additions and 66 deletions

View File

@ -1483,23 +1483,18 @@ namespace ts {
return headChain;
}
/**
* Compare two values for their equality.
*/
export function equateValues<T>(a: T, b: T) {
function equateValues<T>(a: T, b: T) {
return a === b;
}
/**
* Compare equality between two strings using an ordinal comparison.
* Compare the equality of two strings using a case-sensitive ordinal comparison.
*
* Case-insensitive comparisons compare both strings after applying `toUpperCase` to
* each string.
* Case-sensitive comparisons compare both strings one code-point at a time using the integer
* value of each code-point after applying `toUpperCase` to each string. We always map both
* strings to their upper-case form as some unicode characters do not properly round-trip to
* lowercase (such as `` (German sharp capital s)).
*/
export function equateStrings(a: string, b: string, ignoreCase: boolean) {
return ignoreCase ? equateStringsCaseInsensitive(a, b) : equateStringsCaseSensitive(a, b);
}
export function equateStringsCaseInsensitive(a: string, b: string) {
return a === b
|| a !== undefined
@ -1507,14 +1502,16 @@ namespace ts {
&& a.toUpperCase() === b.toUpperCase();
}
/**
* Compare the equality of two strings using a case-sensitive ordinal comparison.
*
* Case-sensitive comparisons compare both strings one code-point at a time using the
* integer value of each code-point.
*/
export function equateStringsCaseSensitive(a: string, b: string) {
return equateValues(a, b);
}
export function getStringEqualityComparer(ignoreCase: boolean) {
return ignoreCase ? equateStringsCaseInsensitive : equateStringsCaseSensitive;
}
/**
* Compare two values for their order relative to each other.
*/
@ -1527,19 +1524,17 @@ namespace ts {
}
/**
* Compare two strings using an ordinal comparison.
* Compare two strings using a case-insensitive ordinal comparison.
*
* Ordinal comparisons are based on the difference between the unicode code points of
* both strings. Characters with multiple unicode representations are considered
* unequal. Ordinal comparisons provide predictable ordering, but place "a" after "B".
* Ordinal comparisons are based on the difference between the unicode code points of both
* strings. Characters with multiple unicode representations are considered unequal. Ordinal
* comparisons provide predictable ordering, but place "a" after "B".
*
* Case-insensitive comparisons compare both strings after applying `toUpperCase` to
* each string.
* Case-insensitive comparisons compare both strings one code-point at a time using the integer
* value of each code-point after applying `toUpperCase` to each string. We always map both
* strings to their upper-case form as some unicode characters do not properly round-trip to
* lowercase (such as `` (German sharp capital s)).
*/
export function compareStrings(a: string, b: string, ignoreCase: boolean) {
return ignoreCase ? compareStringsCaseInsensitive(a, b) : compareStringsCaseSensitive(a, b);
}
export function compareStringsCaseInsensitive(a: string, b: string) {
if (a === b) return Comparison.EqualTo;
if (a === undefined) return Comparison.LessThan;
@ -1549,28 +1544,20 @@ namespace ts {
return a < b ? Comparison.LessThan : a > b ? Comparison.GreaterThan : Comparison.EqualTo;
}
/**
* Compare two strings using a case-sensitive ordinal comparison.
*
* Ordinal comparisons are based on the difference between the unicode code points of both
* strings. Characters with multiple unicode representations are considered unequal. Ordinal
* comparisons provide predictable ordering, but place "a" after "B".
*
* Case-sensitive comparisons compare both strings one code-point at a time using the integer
* value of each code-point.
*/
export function compareStringsCaseSensitive(a: string, b: string) {
return compareValues(a, b);
}
export function getStringComparer(ignoreCase: boolean) {
return ignoreCase ? compareStringsCaseInsensitive : compareStringsCaseSensitive;
}
/**
* Compare two strings using the sort behavior of the UI locale.
*
* Ordering is not predictable between different host locales, but is best for displaying
* ordered data for UI presentation. Characters with multiple unicode representations may
* be considered equal.
*
* Case-insensitive comparisons compare strings that differ in only base characters or
* accents/diacritic marks as unequal.
*/
export function compareStringsUI(a: string, b: string, ignoreCase: boolean) {
return ignoreCase ? compareStringsCaseInsensitiveUI(a, b) : compareStringsCaseSensitiveUI(a, b);
}
/**
* Creates a string comparer for use with string collation in the UI.
*/
@ -1656,6 +1643,10 @@ namespace ts {
let uiCI: Comparer<string> | undefined;
let uiLocale: string | undefined;
export function getUILocale() {
return uiLocale;
}
export function setUILocale(value: string) {
if (uiLocale !== value) {
uiLocale = value;
@ -1664,25 +1655,41 @@ namespace ts {
}
}
/**
* Compare two strings using the case-insensitive sort behavior of the UI locale.
*
* Ordering is not predictable between different host locales, but is best for displaying
* ordered data for UI presentation. Characters with multiple unicode representations may
* be considered equal.
*
* Case-insensitive comparisons compare strings that differ in only base characters or
* accents/diacritic marks as unequal.
*/
export function compareStringsCaseInsensitiveUI(a: string, b: string) {
const comparer = uiCS || (uiCS = createStringComparer(uiLocale, /*caseInsensitive*/ false));
return comparer(a, b);
}
export function compareStringsCaseSensitiveUI(a: string, b: string) {
const comparer = uiCI || (uiCI = createStringComparer(uiLocale, /*caseInsensitive*/ true));
return comparer(a, b);
}
export function getStringComparerUI(ignoreCase: boolean) {
return ignoreCase ? compareStringsCaseInsensitiveUI : compareStringsCaseSensitiveUI;
/**
* Compare two strings in a using the case-sensitive sort behavior of the UI locale.
*
* Ordering is not predictable between different host locales, but is best for displaying
* ordered data for UI presentation. Characters with multiple unicode representations may
* be considered equal.
*
* Case-sensitive comparisons compare strings that differ in base characters, or
* accents/diacritic marks, or case as unequal.
*/
export function compareStringsCaseSensitiveUI(a: string, b: string) {
const comparer = uiCS || (uiCS = createStringComparer(uiLocale, /*caseInsensitive*/ false));
return comparer(a, b);
}
export function compareProperties<T>(a: T, b: T, key: keyof T) {
export function compareProperties<T, K extends keyof T>(a: T, b: T, key: K, comparer: Comparer<T[K]>) {
return a === b ? Comparison.EqualTo :
a === undefined ? Comparison.LessThan :
b === undefined ? Comparison.GreaterThan :
compareValues(a[key], b[key]);
comparer(a[key], b[key]);
}
function getDiagnosticFileName(diagnostic: Diagnostic): string {
@ -1690,7 +1697,7 @@ namespace ts {
}
export function compareDiagnostics(d1: Diagnostic, d2: Diagnostic): Comparison {
return compareValues(getDiagnosticFileName(d1), getDiagnosticFileName(d2)) ||
return compareStringsCaseSensitive(getDiagnosticFileName(d1), getDiagnosticFileName(d2)) ||
compareValues(d1.start, d2.start) ||
compareValues(d1.length, d2.length) ||
compareValues(d1.code, d2.code) ||
@ -1704,7 +1711,7 @@ namespace ts {
const string1 = isString(text1) ? text1 : text1.messageText;
const string2 = isString(text2) ? text2 : text2.messageText;
const res = compareValues(string1, string2);
const res = compareStringsCaseSensitive(string1, string2);
if (res) {
return res;
}
@ -2067,7 +2074,7 @@ namespace ts {
const aComponents = getNormalizedPathComponents(a, currentDirectory);
const bComponents = getNormalizedPathComponents(b, currentDirectory);
const sharedLength = Math.min(aComponents.length, bComponents.length);
const comparer = getStringComparer(ignoreCase);
const comparer = ignoreCase ? compareStringsCaseInsensitive : compareStringsCaseSensitive;
for (let i = 0; i < sharedLength; i++) {
const result = comparer(aComponents[i], bComponents[i]);
if (result !== Comparison.EqualTo) {
@ -2091,7 +2098,7 @@ namespace ts {
}
// File-system comparisons should use predictable ordering
const equalityComparer = getStringEqualityComparer(ignoreCase);
const equalityComparer = ignoreCase ? equateStringsCaseInsensitive : equateStringsCaseSensitive;
for (let i = 0; i < parentComponents.length; i++) {
if (!equalityComparer(parentComponents[i], childComponents[i])) {
return false;
@ -2338,6 +2345,7 @@ namespace ts {
path = normalizePath(path);
currentDirectory = normalizePath(currentDirectory);
const comparer = useCaseSensitiveFileNames ? compareStringsCaseSensitive : compareStringsCaseInsensitive;
const patterns = getFileMatcherPatterns(path, excludes, includes, useCaseSensitiveFileNames, currentDirectory);
const regexFlag = useCaseSensitiveFileNames ? "" : "i";
@ -2349,7 +2357,6 @@ namespace ts {
// If there are no "includes", then just put everything in results[0].
const results: string[][] = includeFileRegexes ? includeFileRegexes.map(() => []) : [[]];
const comparer = getStringComparer(!useCaseSensitiveFileNames);
for (const basePath of patterns.basePaths) {
visitDirectory(basePath, combinePaths(currentDirectory, basePath), depth);
}
@ -2414,7 +2421,7 @@ namespace ts {
}
// Sort the offsets array using either the literal or canonical path representations.
includeBasePaths.sort(getStringComparer(!useCaseSensitiveFileNames));
includeBasePaths.sort(useCaseSensitiveFileNames ? compareStringsCaseSensitive : compareStringsCaseInsensitive);
// Iterate over each include base path and include unique base paths that are not a
// subpath of an existing base path

View File

@ -1101,7 +1101,7 @@ namespace ts {
// If '--lib' is not specified, include default library file according to '--target'
// otherwise, using options specified in '--lib' instead of '--target' default library file
const equalityComparer = getStringEqualityComparer(!host.useCaseSensitiveFileNames());
const equalityComparer = host.useCaseSensitiveFileNames() ? equateStringsCaseSensitive : equateStringsCaseInsensitive;
if (!options.lib) {
return equalityComparer(file.fileName, getDefaultLibraryFileName());
}

View File

@ -306,7 +306,7 @@ namespace ts {
// Sort our options by their names, (e.g. "--noImplicitAny" comes before "--watch")
const optsList = showAllOptions ?
optionDeclarations.slice().sort((a, b) => compareValues<string>(a.name.toLowerCase(), b.name.toLowerCase())) :
optionDeclarations.slice().sort((a, b) => compareStringsCaseInsensitive(a.name, b.name)) :
filter(optionDeclarations.slice(), v => v.showInSimplifiedHelpView);
// We want our descriptions to align at the same column in our output,

View File

@ -3128,7 +3128,10 @@ Actual: ${stringify(fullActual)}`);
`(function(test, goTo, verify, edit, debug, format, cancellation, classification, verifyOperationIsCancelled) {
${code}
})`;
const savedUILocale = ts.getUILocale();
ts.setUILocale("en-US"); // run tests in en-US by default.
try {
const test = new FourSlashInterface.Test(state);
const goTo = new FourSlashInterface.GoTo(state);
const verify = new FourSlashInterface.Verify(state);
@ -3142,6 +3145,9 @@ ${code}
catch (err) {
throw err;
}
finally {
ts.setUILocale(savedUILocale);
}
}
function chompLeadingSpace(content: string) {

View File

@ -1698,8 +1698,7 @@ namespace Harness {
export function *iterateOutputs(outputFiles: Harness.Compiler.GeneratedFile[]): IterableIterator<[string, string]> {
// Collect, test, and sort the fileNames
const comparer = ts.getStringComparer(/*ignoreCase*/ false);
outputFiles.sort((a, b) => comparer(cleanName(a.fileName), cleanName(b.fileName)));
outputFiles.sort((a, b) => ts.compareStringsCaseSensitive(cleanName(a.fileName), cleanName(b.fileName)));
const dupeCase = ts.createMap<number>();
// Yield them
for (const outputFile of outputFiles) {

View File

@ -13,9 +13,8 @@ namespace ts.projectSystem {
describe("CompileOnSave affected list", () => {
function sendAffectedFileRequestAndCheckResult(session: server.Session, request: server.protocol.Request, expectedFileList: { projectFileName: string, files: FileOrFolder[] }[]) {
const response = session.executeCommand(request).response as server.protocol.CompileOnSaveAffectedFileListSingleProject[];
const comparer = getStringComparer(/*ignoreCase*/ false);
const actualResult = response.sort((list1, list2) => comparer(list1.projectFileName, list2.projectFileName));
expectedFileList = expectedFileList.sort((list1, list2) => comparer(list1.projectFileName, list2.projectFileName));
const actualResult = response.sort((list1, list2) => ts.compareStringsCaseSensitive(list1.projectFileName, list2.projectFileName));
expectedFileList = expectedFileList.sort((list1, list2) => ts.compareStringsCaseSensitive(list1.projectFileName, list2.projectFileName));
assert.equal(actualResult.length, expectedFileList.length, `Actual result project number is different from the expected project number`);

View File

@ -1137,7 +1137,7 @@ namespace ts.refactor.extractSymbol {
{type: type1, declaration: declaration1}: {type: Type, declaration?: Declaration},
{type: type2, declaration: declaration2}: {type: Type, declaration?: Declaration}) {
return compareProperties(declaration1, declaration2, "pos")
return compareProperties(declaration1, declaration2, "pos", compareValues)
|| compareStringsCaseSensitive(
type1.symbol ? type1.symbol.getName() : "",
type2.symbol ? type2.symbol.getName() : "")