diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ab76950ec4a..abae979a25d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5336,7 +5336,7 @@ namespace ts { while (i > 0) { i--; if (isSubtypeOfAny(types[i], types)) { - types.splice(i, 1); + removeItemAt(types, i); } } } diff --git a/src/compiler/core.ts b/src/compiler/core.ts index cd378a889d2..dd4ba822243 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1394,15 +1394,25 @@ namespace ts { } } + /** Remove an item from an array, moving everything to its right one space left. */ + export function removeItemAt(array: T[], index: number): void { + // This seems to be faster than either `array.splice(i, 1)` or `array.copyWithin(i, i+ 1)`. + for (let i = index; i < array.length - 1; i++) { + array[i] = array[i + 1]; + } + array.pop(); + } + + /** Remove the *first* occurrence of `item` from the array. */ export function removeItem(item: T, array: T[]): void { + removeFirstItemWhere(array, element => element === item); + } + + /** Remove the *first* element satisfying `predicate`. */ + export function removeFirstItemWhere(array: T[], predicate: (element: T) => boolean): void { for (let i = 0; i < array.length; i++) { - if (array[i] === item) { - // Move everything over to the left. - // This seems to be faster than either `array.splice(i, 1)` or `array.copyWithin(i, i+ 1)`. - for (; i < array.length - 1; i++) { - array[i] = array[i + 1]; - } - array.pop(); + if (predicate(array[i])) { + removeItemAt(array, i); break; } } diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index 3b588edd101..02a97c01132 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -490,10 +490,7 @@ namespace ts { sourceFile.fileWatcher.close(); sourceFile.fileWatcher = undefined; if (removed) { - const index = rootFileNames.indexOf(sourceFile.fileName); - if (index >= 0) { - rootFileNames.splice(index, 1); - } + removeItem(sourceFile.fileName, rootFileNames); } startTimerForRecompilation(); } diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 5ae33303d55..3b36381146f 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1558,7 +1558,7 @@ namespace Harness { tsConfig.options.configFilePath = data.name; // delete entry from the list - testUnitData.splice(i, 1); + ts.removeItemAt(testUnitData, i); break; } diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 74b9e303cf7..cd87164245a 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -214,12 +214,7 @@ namespace ts { referenceCount: 0, directoryName, close: () => { - for (let i = 0; i < callbacks.length; i++) { - if (callbacks[i].cb === callback) { - callbacks.splice(i, 1); - break; - } - } + removeFirstItemWhere(callbacks, cb => cb.cb === callback); if (!callbacks.length) { delete this.watchedDirectories[path]; } @@ -253,8 +248,7 @@ namespace ts { callbacks.push(callback); return { close: () => { - const i = callbacks.indexOf(callback); - callbacks.splice(i, 1); + removeItem(callback, callbacks); if (!callbacks.length) { delete this.watchedFiles[path]; } @@ -269,7 +263,7 @@ namespace ts { }; readonly clearTimeout = (timeoutId: any): void => { if (typeof timeoutId === "number") { - this.callbackQueue.splice(timeoutId, 1); + removeItemAt(this.callbackQueue, timeoutId); } }; @@ -594,7 +588,7 @@ namespace ts { content: `{ "compilerOptions": { "target": "es6" - }, + }, "files": [ "main.ts" ] }` }; @@ -621,7 +615,7 @@ namespace ts { content: `{ "compilerOptions": { "target": "es6" - }, + }, "files": [ "main.ts" ] }` };