Skip to content

Commit fb681bf

Browse files
jakebaileysnovader
authored andcommitted
Clean up helpers which are always present in ES2020 (microsoft#55515)
1 parent 5562915 commit fb681bf

File tree

13 files changed

+37
-199
lines changed

13 files changed

+37
-199
lines changed

src/compiler/commandLineParser.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@ import {
110110
toFileNameLowerCase,
111111
toPath,
112112
tracing,
113-
trimString,
114113
TsConfigOnlyOption,
115114
TsConfigSourceFile,
116115
TypeAcquisition,
@@ -1699,13 +1698,13 @@ function createDiagnosticForInvalidCustomType(opt: CommandLineOptionOfCustomType
16991698
}
17001699

17011700
/** @internal */
1702-
export function parseCustomTypeOption(opt: CommandLineOptionOfCustomType, value: string, errors: Diagnostic[]) {
1703-
return convertJsonOptionOfCustomType(opt, trimString(value || ""), errors);
1701+
export function parseCustomTypeOption(opt: CommandLineOptionOfCustomType, value: string | undefined, errors: Diagnostic[]) {
1702+
return convertJsonOptionOfCustomType(opt, (value ?? "").trim(), errors);
17041703
}
17051704

17061705
/** @internal */
17071706
export function parseListTypeOption(opt: CommandLineOptionOfListType, value = "", errors: Diagnostic[]): string | (string | number)[] | undefined {
1708-
value = trimString(value);
1707+
value = value.trim();
17091708
if (startsWith(value, "-")) {
17101709
return undefined;
17111710
}

src/compiler/core.ts

Lines changed: 1 addition & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {
55
Comparison,
66
Debug,
77
EqualityComparer,
8-
isWhiteSpaceLike,
98
MapLike,
109
Queue,
1110
SortedArray,
@@ -2241,11 +2240,7 @@ export function getStringComparer(ignoreCase?: boolean) {
22412240
* Creates a string comparer for use with string collation in the UI.
22422241
*/
22432242
const createUIStringComparer = (() => {
2244-
let defaultComparer: Comparer<string> | undefined;
2245-
let enUSComparer: Comparer<string> | undefined;
2246-
2247-
const stringComparerFactory = getStringComparerFactory();
2248-
return createStringComparer;
2243+
return createIntlCollatorStringComparer;
22492244

22502245
function compareWithCallback(a: string | undefined, b: string | undefined, comparer: (a: string, b: string) => number) {
22512246
if (a === b) return Comparison.EqualTo;
@@ -2261,70 +2256,6 @@ const createUIStringComparer = (() => {
22612256
const comparer = new Intl.Collator(locale, { usage: "sort", sensitivity: "variant" }).compare;
22622257
return (a, b) => compareWithCallback(a, b, comparer);
22632258
}
2264-
2265-
function createLocaleCompareStringComparer(locale: string | undefined): Comparer<string> {
2266-
// if the locale is not the default locale (`undefined`), use the fallback comparer.
2267-
if (locale !== undefined) return createFallbackStringComparer();
2268-
2269-
return (a, b) => compareWithCallback(a, b, compareStrings);
2270-
2271-
function compareStrings(a: string, b: string) {
2272-
return a.localeCompare(b);
2273-
}
2274-
}
2275-
2276-
function createFallbackStringComparer(): Comparer<string> {
2277-
// An ordinal comparison puts "A" after "b", but for the UI we want "A" before "b".
2278-
// We first sort case insensitively. So "Aaa" will come before "baa".
2279-
// Then we sort case sensitively, so "aaa" will come before "Aaa".
2280-
//
2281-
// For case insensitive comparisons we always map both strings to their
2282-
// upper-case form as some unicode characters do not properly round-trip to
2283-
// lowercase (such as `ẞ` (German sharp capital s)).
2284-
return (a, b) => compareWithCallback(a, b, compareDictionaryOrder);
2285-
2286-
function compareDictionaryOrder(a: string, b: string) {
2287-
return compareStrings(a.toUpperCase(), b.toUpperCase()) || compareStrings(a, b);
2288-
}
2289-
2290-
function compareStrings(a: string, b: string) {
2291-
return a < b ? Comparison.LessThan : a > b ? Comparison.GreaterThan : Comparison.EqualTo;
2292-
}
2293-
}
2294-
2295-
function getStringComparerFactory() {
2296-
// If the host supports Intl, we use it for comparisons using the default locale.
2297-
if (typeof Intl === "object" && typeof Intl.Collator === "function") {
2298-
return createIntlCollatorStringComparer;
2299-
}
2300-
2301-
// If the host does not support Intl, we fall back to localeCompare.
2302-
// localeCompare in Node v0.10 is just an ordinal comparison, so don't use it.
2303-
if (
2304-
typeof String.prototype.localeCompare === "function" &&
2305-
typeof String.prototype.toLocaleUpperCase === "function" &&
2306-
"a".localeCompare("B") < 0
2307-
) {
2308-
return createLocaleCompareStringComparer;
2309-
}
2310-
2311-
// Otherwise, fall back to ordinal comparison:
2312-
return createFallbackStringComparer;
2313-
}
2314-
2315-
function createStringComparer(locale: string | undefined) {
2316-
// Hold onto common string comparers. This avoids constantly reallocating comparers during
2317-
// tests.
2318-
if (locale === undefined) {
2319-
return defaultComparer || (defaultComparer = stringComparerFactory(locale));
2320-
}
2321-
else if (locale === "en-US") {
2322-
return enUSComparer || (enUSComparer = stringComparerFactory(locale));
2323-
}
2324-
else {
2325-
return stringComparerFactory(locale);
2326-
}
2327-
}
23282259
})();
23292260

23302261
let uiComparerCaseSensitive: Comparer<string> | undefined;
@@ -2772,32 +2703,6 @@ function cartesianProductWorker<T>(arrays: readonly (readonly T[])[], result: (r
27722703
}
27732704
}
27742705

2775-
/**
2776-
* Returns string left-padded with spaces or zeros until it reaches the given length.
2777-
*
2778-
* @param s String to pad.
2779-
* @param length Final padded length. If less than or equal to 's.length', returns 's' unchanged.
2780-
* @param padString Character to use as padding (default " ").
2781-
*
2782-
* @internal
2783-
*/
2784-
export function padLeft(s: string, length: number, padString: " " | "0" = " ") {
2785-
return length <= s.length ? s : padString.repeat(length - s.length) + s;
2786-
}
2787-
2788-
/**
2789-
* Returns string right-padded with spaces until it reaches the given length.
2790-
*
2791-
* @param s String to pad.
2792-
* @param length Final padded length. If less than or equal to 's.length', returns 's' unchanged.
2793-
* @param padString Character to use as padding (default " ").
2794-
*
2795-
* @internal
2796-
*/
2797-
export function padRight(s: string, length: number, padString: " " = " ") {
2798-
return length <= s.length ? s : s + padString.repeat(length - s.length);
2799-
}
2800-
28012706
/** @internal */
28022707
export function takeWhile<T, U extends T>(array: readonly T[], predicate: (element: T) => element is U): U[];
28032708
/** @internal */
@@ -2829,42 +2734,6 @@ export function skipWhile<T, U extends T>(array: readonly T[] | undefined, predi
28292734
}
28302735
}
28312736

2832-
/**
2833-
* Removes the leading and trailing white space and line terminator characters from a string.
2834-
*
2835-
* @internal
2836-
*/
2837-
export const trimString = !!String.prototype.trim ? ((s: string) => s.trim()) : (s: string) => trimStringEnd(trimStringStart(s));
2838-
2839-
/**
2840-
* Returns a copy with trailing whitespace removed.
2841-
*
2842-
* @internal
2843-
*/
2844-
export const trimStringEnd = !!String.prototype.trimEnd ? ((s: string) => s.trimEnd()) : trimEndImpl;
2845-
2846-
/**
2847-
* Returns a copy with leading whitespace removed.
2848-
*
2849-
* @internal
2850-
*/
2851-
export const trimStringStart = !!String.prototype.trimStart ? ((s: string) => s.trimStart()) : (s: string) => s.replace(/^\s+/g, "");
2852-
2853-
/**
2854-
* https://jsbench.me/gjkoxld4au/1
2855-
* The simple regex for this, /\s+$/g is O(n^2) in v8.
2856-
* The native .trimEnd method is by far best, but since that's technically ES2019,
2857-
* we provide a (still much faster than the simple regex) fallback.
2858-
*/
2859-
function trimEndImpl(s: string) {
2860-
let end = s.length - 1;
2861-
while (end >= 0) {
2862-
if (!isWhiteSpaceLike(s.charCodeAt(end))) break;
2863-
end--;
2864-
}
2865-
return s.slice(0, end + 1);
2866-
}
2867-
28682737
/** @internal */
28692738
export function isNodeLikeSystem(): boolean {
28702739
// This is defined here rather than in sys.ts to prevent a cycle from its

src/compiler/parser.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -368,8 +368,6 @@ import {
368368
tokenToString,
369369
tracing,
370370
TransformFlags,
371-
trimString,
372-
trimStringEnd,
373371
TryStatement,
374372
TupleTypeNode,
375373
TypeAliasDeclaration,
@@ -8895,7 +8893,7 @@ namespace Parser {
88958893
nextTokenJSDoc();
88968894
}
88978895
}
8898-
const trimmedComments = trimStringEnd(comments.join(""));
8896+
const trimmedComments = comments.join("").trimEnd();
88998897
if (parts.length && trimmedComments.length) {
89008898
parts.push(finishNode(factory.createJSDocText(trimmedComments), linkEnd ?? start, commentsPos));
89018899
}
@@ -8912,7 +8910,7 @@ namespace Parser {
89128910

89138911
function removeTrailingWhitespace(comments: string[]) {
89148912
while (comments.length) {
8915-
const trimmed = trimStringEnd(comments[comments.length - 1]);
8913+
const trimmed = comments[comments.length - 1].trimEnd();
89168914
if (trimmed === "") {
89178915
comments.pop();
89188916
}
@@ -9174,7 +9172,7 @@ namespace Parser {
91749172
}
91759173

91769174
removeLeadingNewlines(comments);
9177-
const trimmedComments = trimStringEnd(comments.join(""));
9175+
const trimmedComments = comments.join("").trimEnd();
91789176
if (parts.length) {
91799177
if (trimmedComments.length) {
91809178
parts.push(finishNode(factory.createJSDocText(trimmedComments), linkEnd ?? commentsPos));
@@ -10618,7 +10616,7 @@ function addPragmaForMatch(pragmas: PragmaPseudoMapEntry[], range: CommentRange,
1061810616
function getNamedPragmaArguments(pragma: PragmaDefinition, text: string | undefined): { [index: string]: string; } | "fail" {
1061910617
if (!text) return {};
1062010618
if (!pragma.args) return {};
10621-
const args = trimString(text).split(/\s+/);
10619+
const args = text.trim().split(/\s+/);
1062210620
const argMap: { [index: string]: string; } = {};
1062310621
for (let i = 0; i < pragma.args.length; i++) {
1062410622
const argument = pragma.args[i];

src/compiler/program.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,6 @@ import {
250250
packageIdToPackageName,
251251
packageIdToString,
252252
PackageJsonInfoCache,
253-
padLeft,
254253
ParameterDeclaration,
255254
ParseConfigFileHost,
256255
ParsedCommandLine,
@@ -318,7 +317,6 @@ import {
318317
toPath as ts_toPath,
319318
trace,
320319
tracing,
321-
trimStringEnd,
322320
TsConfigSourceFile,
323321
TypeChecker,
324322
typeDirectiveIsEqualTo,
@@ -722,22 +720,22 @@ function formatCodeSpan(file: SourceFile, start: number, length: number, indent:
722720
// If the error spans over 5 lines, we'll only show the first 2 and last 2 lines,
723721
// so we'll skip ahead to the second-to-last line.
724722
if (hasMoreThanFiveLines && firstLine + 1 < i && i < lastLine - 1) {
725-
context += indent + formatColorAndReset(padLeft(ellipsis, gutterWidth), gutterStyleSequence) + gutterSeparator + host.getNewLine();
723+
context += indent + formatColorAndReset(ellipsis.padStart(gutterWidth), gutterStyleSequence) + gutterSeparator + host.getNewLine();
726724
i = lastLine - 1;
727725
}
728726

729727
const lineStart = getPositionOfLineAndCharacter(file, i, 0);
730728
const lineEnd = i < lastLineInFile ? getPositionOfLineAndCharacter(file, i + 1, 0) : file.text.length;
731729
let lineContent = file.text.slice(lineStart, lineEnd);
732-
lineContent = trimStringEnd(lineContent); // trim from end
730+
lineContent = lineContent.trimEnd(); // trim from end
733731
lineContent = lineContent.replace(/\t/g, " "); // convert tabs to single spaces
734732

735733
// Output the gutter and the actual contents of the line.
736-
context += indent + formatColorAndReset(padLeft(i + 1 + "", gutterWidth), gutterStyleSequence) + gutterSeparator;
734+
context += indent + formatColorAndReset((i + 1 + "").padStart(gutterWidth), gutterStyleSequence) + gutterSeparator;
737735
context += lineContent + host.getNewLine();
738736

739737
// Output the gutter and the error span for the line using tildes.
740-
context += indent + formatColorAndReset(padLeft("", gutterWidth), gutterStyleSequence) + gutterSeparator;
738+
context += indent + formatColorAndReset("".padStart(gutterWidth), gutterStyleSequence) + gutterSeparator;
741739
context += squiggleColor;
742740
if (i === firstLine) {
743741
// If we're on the last line, then limit it to the last character of the last line.

src/compiler/scanner.ts

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,13 @@ import {
1818
LanguageVariant,
1919
LineAndCharacter,
2020
MapLike,
21-
padLeft,
2221
parsePseudoBigInt,
2322
positionIsSynthesized,
2423
PunctuationOrKeywordSyntaxKind,
2524
ScriptTarget,
2625
SourceFileLike,
2726
SyntaxKind,
2827
TokenFlags,
29-
trimStringStart,
3028
} from "./_namespaces/ts";
3129

3230
export type ErrorCallback = (message: DiagnosticMessage, length: number, arg0?: any) => void;
@@ -1490,7 +1488,7 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
14901488
tokenFlags |= TokenFlags.ContainsInvalidEscape;
14911489
if (shouldEmitInvalidEscapeError) {
14921490
const code = parseInt(text.substring(start + 1, pos), 8);
1493-
error(Diagnostics.Octal_escape_sequences_are_not_allowed_Use_the_syntax_0, start, pos - start, "\\x" + padLeft(code.toString(16), 2, "0"));
1491+
error(Diagnostics.Octal_escape_sequences_are_not_allowed_Use_the_syntax_0, start, pos - start, "\\x" + code.toString(16).padStart(2, "0"));
14941492
return String.fromCharCode(code);
14951493
}
14961494
return text.substring(start, pos);
@@ -2392,7 +2390,7 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
23922390
commentDirectiveRegEx: RegExp,
23932391
lineStart: number,
23942392
) {
2395-
const type = getDirectiveFromComment(trimStringStart(text), commentDirectiveRegEx);
2393+
const type = getDirectiveFromComment(text.trimStart(), commentDirectiveRegEx);
23962394
if (type === undefined) {
23972395
return commentDirectives;
23982396
}
@@ -2793,25 +2791,10 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
27932791
}
27942792

27952793
/** @internal */
2796-
const codePointAt: (s: string, i: number) => number = (String.prototype as any).codePointAt ? (s, i) => (s as any).codePointAt(i) : function codePointAt(str, i): number {
2797-
// from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt
2798-
const size = str.length;
2799-
// Account for out-of-bounds indices:
2800-
if (i < 0 || i >= size) {
2801-
return undefined!; // String.codePointAt returns `undefined` for OOB indexes
2802-
}
2803-
// Get the first code unit
2804-
const first = str.charCodeAt(i);
2805-
// check if it's the start of a surrogate pair
2806-
if (first >= 0xD800 && first <= 0xDBFF && size > i + 1) { // high surrogate and there is a next code unit
2807-
const second = str.charCodeAt(i + 1);
2808-
if (second >= 0xDC00 && second <= 0xDFFF) { // low surrogate
2809-
// https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
2810-
return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
2811-
}
2812-
}
2813-
return first;
2814-
};
2794+
function codePointAt(s: string, i: number): number {
2795+
// TODO(jakebailey): this is wrong and should have ?? 0; but all users are okay with it
2796+
return s.codePointAt(i)!;
2797+
}
28152798

28162799
/** @internal */
28172800
function charSize(ch: number) {

src/compiler/semver.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import {
88
isArray,
99
map,
1010
some,
11-
trimString,
1211
} from "./_namespaces/ts";
1312

1413
// https://semver.org/#spec-item-2
@@ -275,17 +274,17 @@ const rangeRegExp = /^(~|\^|<|<=|>|>=|=)?\s*([a-z0-9-+.*]+)$/i;
275274

276275
function parseRange(text: string) {
277276
const alternatives: Comparator[][] = [];
278-
for (let range of trimString(text).split(logicalOrRegExp)) {
277+
for (let range of text.trim().split(logicalOrRegExp)) {
279278
if (!range) continue;
280279
const comparators: Comparator[] = [];
281-
range = trimString(range);
280+
range = range.trim();
282281
const match = hyphenRegExp.exec(range);
283282
if (match) {
284283
if (!parseHyphen(match[1], match[2], comparators)) return undefined;
285284
}
286285
else {
287286
for (const simple of range.split(whitespaceRegExp)) {
288-
const match = rangeRegExp.exec(trimString(simple));
287+
const match = rangeRegExp.exec(simple.trim());
289288
if (!match || !parseComparator(match[1], match[2], comparators)) return undefined;
290289
}
291290
}

src/compiler/sourcemap.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import {
2424
sortAndDeduplicate,
2525
SortedReadonlyArray,
2626
SourceMapGenerator,
27-
trimStringEnd,
2827
} from "./_namespaces/ts";
2928
import * as performance from "./_namespaces/ts.performance";
3029

@@ -392,7 +391,7 @@ export function tryGetSourceMappingURL(lineInfo: LineInfo) {
392391
const line = lineInfo.getLineText(index);
393392
const comment = sourceMapCommentRegExp.exec(line);
394393
if (comment) {
395-
return trimStringEnd(comment[1]);
394+
return comment[1].trimEnd();
396395
}
397396
// If we see a non-whitespace/map comment-like line, break, to avoid scanning up the entire file
398397
else if (!line.match(whitespaceOrMapCommentRegExp)) {

0 commit comments

Comments
 (0)