From af1150640cf046fa8aef1cb404010c78c54a553f Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 25 Jul 2022 17:00:07 -0700 Subject: [PATCH] Remove shims project --- Gulpfile.js | 10 +- src/compiler/corePublic.ts | 39 +-- src/compiler/tsconfig.json | 1 - src/compiler/tsconfig.release.json | 1 - src/services/tsconfig.json | 1 - src/shims/collectionShims.ts | 267 ------------------ src/shims/tsconfig.json | 9 - src/testRunner/tsconfig.json | 3 - src/testRunner/unittests/createMapShim.ts | 326 ---------------------- src/testRunner/unittests/createSetShim.ts | 309 -------------------- src/tsconfig.json | 3 +- src/tsserverlibrary/tsconfig.json | 1 - src/typescriptServices/tsconfig.json | 1 - 13 files changed, 17 insertions(+), 954 deletions(-) delete mode 100644 src/shims/collectionShims.ts delete mode 100644 src/shims/tsconfig.json delete mode 100644 src/testRunner/unittests/createMapShim.ts delete mode 100644 src/testRunner/unittests/createSetShim.ts diff --git a/Gulpfile.js b/Gulpfile.js index a59894996e65a..91d7b8c95dbae 100644 --- a/Gulpfile.js +++ b/Gulpfile.js @@ -92,18 +92,12 @@ const localize = async () => { } }; -const buildShims = () => buildProject("src/shims"); -const cleanShims = () => cleanProject("src/shims"); -cleanTasks.push(cleanShims); - const buildDebugTools = () => buildProject("src/debug"); const cleanDebugTools = () => cleanProject("src/debug"); cleanTasks.push(cleanDebugTools); -const buildShimsAndTools = parallel(buildShims, buildDebugTools); - // Pre-build steps when targeting the LKG compiler -const lkgPreBuild = parallel(generateLibs, series(buildScripts, generateDiagnostics, buildShimsAndTools)); +const lkgPreBuild = parallel(generateLibs, series(buildScripts, generateDiagnostics, buildDebugTools)); const buildTsc = () => buildProject("src/tsc"); task("tsc", series(lkgPreBuild, buildTsc)); @@ -119,7 +113,7 @@ task("watch-tsc", series(lkgPreBuild, parallel(watchLib, watchDiagnostics, watch task("watch-tsc").description = "Watch for changes and rebuild the command-line compiler only."; // Pre-build steps when targeting the built/local compiler. -const localPreBuild = parallel(generateLibs, series(buildScripts, generateDiagnostics, buildShimsAndTools, buildTsc)); +const localPreBuild = parallel(generateLibs, series(buildScripts, generateDiagnostics, buildDebugTools, buildTsc)); // Pre-build steps to use based on supplied options. const preBuild = cmdLineOptions.lkg ? lkgPreBuild : localPreBuild; diff --git a/src/compiler/corePublic.ts b/src/compiler/corePublic.ts index aabd9ac8333a5..652cbcd39c604 100644 --- a/src/compiler/corePublic.ts +++ b/src/compiler/corePublic.ts @@ -124,45 +124,34 @@ namespace ts { /** * Returns the native Map implementation if it is available and compatible (i.e. supports iteration). */ - export function tryGetNativeMap(): MapConstructor | undefined { + export function tryGetNativeMap(): MapConstructor { // Internet Explorer's Map doesn't support iteration, so don't use it. const gMap = globals?.Map; // eslint-disable-next-line no-in-operator - return typeof gMap !== "undefined" && "entries" in gMap.prototype && new gMap([[0, 0]]).size === 1 ? gMap : undefined; + const constructor = typeof gMap !== "undefined" && "entries" in gMap.prototype && new gMap([[0, 0]]).size === 1 ? gMap : undefined; + if (!constructor) { + throw new Error("No compatible Map implementation found."); + } + return constructor; } /** * Returns the native Set implementation if it is available and compatible (i.e. supports iteration). */ - export function tryGetNativeSet(): SetConstructor | undefined { + export function tryGetNativeSet(): SetConstructor { // Internet Explorer's Set doesn't support iteration, so don't use it. const gSet = globals?.Set; // eslint-disable-next-line no-in-operator - return typeof gSet !== "undefined" && "entries" in gSet.prototype && new gSet([0]).size === 1 ? gSet : undefined; + const constructor = typeof gSet !== "undefined" && "entries" in gSet.prototype && new gSet([0]).size === 1 ? gSet : undefined; + if (!constructor) { + throw new Error("No compatible Set implementation found."); + } + return constructor; } } /* @internal */ - export const Map = getCollectionImplementation("Map", "tryGetNativeMap", "createMapShim"); + export const Map = NativeCollections.tryGetNativeMap(); /* @internal */ - export const Set = getCollectionImplementation("Set", "tryGetNativeSet", "createSetShim"); - - /* @internal */ - type GetIteratorCallback = | ReadonlyESMap | undefined>(iterable: I) => Iterator< - I extends ReadonlyESMap ? [K, V] : - I extends ReadonlySet ? T : - I extends readonly (infer T)[] ? T : - I extends undefined ? undefined : - never>; - - /* @internal */ - function getCollectionImplementation< - K1 extends MatchingKeys any>, - K2 extends MatchingKeys ReturnType<(typeof NativeCollections)[K1]>> - >(name: string, nativeFactory: K1, shimFactory: K2): NonNullable> { - // NOTE: ts.ShimCollections will be defined for typescriptServices.js but not for tsc.js, so we must test for it. - const constructor = NativeCollections[nativeFactory]() ?? ShimCollections?.[shimFactory](getIterator); - if (constructor) return constructor as NonNullable>; - throw new Error(`TypeScript requires an environment that provides a compatible native ${name} implementation.`); - } + export const Set = NativeCollections.tryGetNativeSet(); } diff --git a/src/compiler/tsconfig.json b/src/compiler/tsconfig.json index fccbe06558a23..cc5b4749835fd 100644 --- a/src/compiler/tsconfig.json +++ b/src/compiler/tsconfig.json @@ -6,7 +6,6 @@ }, "references": [ - { "path": "../shims" } ], "files": [ diff --git a/src/compiler/tsconfig.release.json b/src/compiler/tsconfig.release.json index 5ddd6d8e3a366..570c9fd875727 100644 --- a/src/compiler/tsconfig.release.json +++ b/src/compiler/tsconfig.release.json @@ -6,6 +6,5 @@ "preserveConstEnums": false }, "references": [ - { "path": "../shims" } ] } diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index 080c81ef6e602..949d5c8a964a7 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -4,7 +4,6 @@ "outFile": "../../built/local/services.js" }, "references": [ - { "path": "../shims" }, { "path": "../compiler" }, { "path": "../jsTyping" } ], diff --git a/src/shims/collectionShims.ts b/src/shims/collectionShims.ts deleted file mode 100644 index 6b868e8714e08..0000000000000 --- a/src/shims/collectionShims.ts +++ /dev/null @@ -1,267 +0,0 @@ -/* @internal */ -namespace ts { - type GetIteratorCallback = | ReadonlyMapShim | undefined>(iterable: I) => IteratorShim< - I extends ReadonlyMapShim ? [K, V] : - I extends ReadonlySetShim ? T : - I extends readonly (infer T)[] ? T : - I extends undefined ? undefined : - never>; - - type IteratorResultShim = - | { value: T, done?: false } - | { value: void, done: true }; - - interface IteratorShim { - next(): IteratorResultShim; - } - - interface ReadonlyMapShim { - readonly size: number; - get(key: K): V | undefined; - has(key: K): boolean; - keys(): IteratorShim; - values(): IteratorShim; - entries(): IteratorShim<[K, V]>; - forEach(action: (value: V, key: K) => void): void; - } - - interface MapShim extends ReadonlyMapShim { - set(key: K, value: V): this; - delete(key: K): boolean; - clear(): void; - } - - type MapShimConstructor = new (iterable?: readonly (readonly [K, V])[] | ReadonlyMapShim) => MapShim; - - interface ReadonlySetShim { - readonly size: number; - has(value: T): boolean; - keys(): IteratorShim; - values(): IteratorShim; - entries(): IteratorShim<[T, T]>; - forEach(action: (value: T, key: T) => void): void; - } - - interface SetShim extends ReadonlySetShim { - add(value: T): this; - delete(value: T): boolean; - clear(): void; - } - - type SetShimConstructor = new (iterable?: readonly T[] | ReadonlySetShim) => SetShim; - - interface MapData { - size: number; - readonly head: MapEntry; - tail: MapEntry; - } - - interface MapEntry { - readonly key?: K; - value?: V; - /** - * Specifies the next entry in the linked list. - */ - next?: MapEntry; - /** - * Specifies the previous entry in the linked list. - * Must be set when the entry is part of a Map/Set. - * When 'undefined', iterators should skip the next entry. - * This will be set to 'undefined' when an entry is deleted. - * See https://github.com/Microsoft/TypeScript/pull/27292 for more information. - */ - prev?: MapEntry; - } - - interface IteratorData { - current?: MapEntry; - selector: (key: K, value: V) => U; - } - - function createMapData(): MapData { - const sentinel: MapEntry = {}; - sentinel.prev = sentinel; - return { head: sentinel, tail: sentinel, size: 0 }; - } - - function createMapEntry(key: K, value: V): MapEntry { - return { key, value, next: undefined, prev: undefined }; - } - - function sameValueZero(x: unknown, y: unknown) { - // Treats -0 === 0 and NaN === NaN - return x === y || x !== x && y !== y; - } - - function getPrev(entry: MapEntry) { - const prev = entry.prev; - // Entries without a 'prev' have been removed from the map. - // An entry whose 'prev' points to itself is the head of the list and is invalid here. - if (!prev || prev === entry) throw new Error("Illegal state"); - return prev; - } - - function getNext(entry: MapEntry | undefined) { - while (entry) { - // Entries without a 'prev' have been removed from the map. Their 'next' - // pointer should point to the previous entry prior to deletion and - // that entry should be skipped to resume iteration. - const skipNext = !entry.prev; - entry = entry.next; - if (skipNext) { - continue; - } - return entry; - } - } - - function getEntry(data: MapData, key: K): MapEntry | undefined { - // We walk backwards from 'tail' to prioritize recently added entries. - // We skip 'head' because it is an empty entry used to track iteration start. - for (let entry = data.tail; entry !== data.head; entry = getPrev(entry)) { - if (sameValueZero(entry.key, key)) { - return entry; - } - } - } - - function addOrUpdateEntry(data: MapData, key: K, value: V): MapEntry | undefined { - const existing = getEntry(data, key); - if (existing) { - existing.value = value; - return; - } - - const entry = createMapEntry(key, value); - entry.prev = data.tail; - data.tail.next = entry; - data.tail = entry; - data.size++; - return entry; - } - - function deleteEntry(data: MapData, key: K): MapEntry | undefined { - // We walk backwards from 'tail' to prioritize recently added entries. - // We skip 'head' because it is an empty entry used to track iteration start. - for (let entry = data.tail; entry !== data.head; entry = getPrev(entry)) { - // all entries in the map should have a 'prev' pointer. - if (entry.prev === undefined) throw new Error("Illegal state"); - if (sameValueZero(entry.key, key)) { - if (entry.next) { - entry.next.prev = entry.prev; - } - else { - // an entry in the map without a 'next' pointer must be the 'tail'. - if (data.tail !== entry) throw new Error("Illegal state"); - data.tail = entry.prev; - } - - entry.prev.next = entry.next; - entry.next = entry.prev; - entry.prev = undefined; - data.size--; - return entry; - } - } - } - - function clearEntries(data: MapData) { - let node = data.tail; - while (node !== data.head) { - const prev = getPrev(node); - node.next = data.head; - node.prev = undefined; - node = prev; - } - data.head.next = undefined; - data.tail = data.head; - data.size = 0; - } - - function forEachEntry(data: MapData, action: (value: V, key: K) => void) { - let entry: MapEntry | undefined = data.head; - while (entry) { - entry = getNext(entry); - if (entry) { - action(entry.value!, entry.key!); - } - } - } - - function forEachIteration(iterator: IteratorShim | undefined, action: (value: any) => void) { - if (iterator) { - for (let step = iterator.next(); !step.done; step = iterator.next()) { - action(step.value); - } - } - } - - function createIteratorData(data: MapData, selector: (key: K, value: V) => U): IteratorData { - return { current: data.head, selector }; - } - - function iteratorNext(data: IteratorData): IteratorResultShim { - // Navigate to the next entry. - data.current = getNext(data.current); - if (data.current) { - return { value: data.selector(data.current.key!, data.current.value!), done: false }; - } - else { - return { value: undefined as never, done: true }; - } - } - - /* @internal */ - export namespace ShimCollections { - export function createMapShim(getIterator: GetIteratorCallback): MapShimConstructor { - class MapIterator { - private _data: IteratorData; - constructor(data: MapData, selector: (key: K, value: V) => U) { - this._data = createIteratorData(data, selector); - } - next() { return iteratorNext(this._data); } - } - return class Map implements MapShim { - private _mapData = createMapData(); - constructor(iterable?: readonly (readonly [K, V])[] | ReadonlyMapShim) { - forEachIteration(getIterator(iterable), ([key, value]) => this.set(key, value)); - } - get size() { return this._mapData.size; } - get(key: K): V | undefined { return getEntry(this._mapData, key)?.value; } - set(key: K, value: V): this { return addOrUpdateEntry(this._mapData, key, value), this; } - has(key: K): boolean { return !!getEntry(this._mapData, key); } - delete(key: K): boolean { return !!deleteEntry(this._mapData, key); } - clear(): void { clearEntries(this._mapData); } - keys(): IteratorShim { return new MapIterator(this._mapData, (key, _value) => key); } - values(): IteratorShim { return new MapIterator(this._mapData, (_key, value) => value); } - entries(): IteratorShim<[K, V]> { return new MapIterator(this._mapData, (key, value) => [key, value]); } - forEach(action: (value: V, key: K) => void): void { forEachEntry(this._mapData, action); } - }; - } - - export function createSetShim(getIterator: GetIteratorCallback): SetShimConstructor { - class SetIterator { - private _data: IteratorData; - constructor(data: MapData, selector: (key: K, value: V) => U) { - this._data = createIteratorData(data, selector); - } - next() { return iteratorNext(this._data); } - } - return class Set implements SetShim { - private _mapData = createMapData(); - constructor(iterable?: readonly T[] | ReadonlySetShim) { - forEachIteration(getIterator(iterable), value => this.add(value)); - } - get size() { return this._mapData.size; } - add(value: T): this { return addOrUpdateEntry(this._mapData, value, value), this; } - has(value: T): boolean { return !!getEntry(this._mapData, value); } - delete(value: T): boolean { return !!deleteEntry(this._mapData, value); } - clear(): void { clearEntries(this._mapData); } - keys(): IteratorShim { return new SetIterator(this._mapData, (key, _value) => key); } - values(): IteratorShim { return new SetIterator(this._mapData, (_key, value) => value); } - entries(): IteratorShim<[T, T]> { return new SetIterator(this._mapData, (key, value) => [key, value]); } - forEach(action: (value: T, key: T) => void): void { forEachEntry(this._mapData, action); } - }; - } - } -} diff --git a/src/shims/tsconfig.json b/src/shims/tsconfig.json deleted file mode 100644 index ebea929016ac0..0000000000000 --- a/src/shims/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../tsconfig-base", - "compilerOptions": { - "outFile": "../../built/local/shims.js" - }, - "files": [ - "collectionShims.ts", - ] -} diff --git a/src/testRunner/tsconfig.json b/src/testRunner/tsconfig.json index 80cde07e7c751..19380bc8ca685 100644 --- a/src/testRunner/tsconfig.json +++ b/src/testRunner/tsconfig.json @@ -14,7 +14,6 @@ ] }, "references": [ - { "path": "../shims", "prepend": true }, { "path": "../compiler", "prepend": true }, { "path": "../executeCommandLine", "prepend": true }, { "path": "../services", "prepend": true }, @@ -76,8 +75,6 @@ "unittests/publicApi.ts", "unittests/reuseProgramStructure.ts", "unittests/semver.ts", - "unittests/createMapShim.ts", - "unittests/createSetShim.ts", "unittests/transform.ts", "unittests/config/commandLineParsing.ts", "unittests/config/configurationExtension.ts", diff --git a/src/testRunner/unittests/createMapShim.ts b/src/testRunner/unittests/createMapShim.ts deleted file mode 100644 index e76718e1f244b..0000000000000 --- a/src/testRunner/unittests/createMapShim.ts +++ /dev/null @@ -1,326 +0,0 @@ -namespace ts { - describe("unittests:: createMapShim", () => { - - const stringKeys = [ - "1", - "3", - "2", - "4", - "0", - "999", - "A", - "B", - "C", - "Z", - "X", - "X1", - "X2", - "Y" - ]; - - const mixedKeys = [ - true, - 3, - { toString() { return "2"; } }, - "4", - false, - null, // eslint-disable-line no-null/no-null - undefined, - "B", - { toString() { return "C"; } }, - "Z", - "X", - { toString() { return "X1"; } }, - "X2", - "Y" - ]; - - function testMapIterationAddedValues(keys: K[], map: ESMap, useForEach: boolean): string { - let resultString = ""; - - map.set(keys[0], "1"); - map.set(keys[1], "3"); - map.set(keys[2], "2"); - map.set(keys[3], "4"); - - let addedThree = false; - const doForEach = (value: string, key: K) => { - resultString += `${key}:${value};`; - - // Add a new key ("0") - the map should provide this - // one in the next iteration. - if (key === keys[0]) { - map.set(keys[0], "X1"); - map.set(keys[4], "X0"); - map.set(keys[3], "X4"); - } - else if (key === keys[1]) { - if (!addedThree) { - addedThree = true; - - // Remove and re-add key "3"; the map should - // visit it after "0". - map.delete(keys[1]); - map.set(keys[1], "Y3"); - - // Change the value of "2"; the map should provide - // it when visiting the key. - map.set(keys[2], "Y2"); - } - else { - // Check that an entry added when we visit the - // currently last entry will still be visited. - map.set(keys[5], "999"); - } - } - else if (key === keys[5]) { - // Ensure that clear() behaves correctly same as removing all keys. - map.set(keys[6], "A"); - map.set(keys[7], "B"); - map.set(keys[8], "C"); - } - else if (key === keys[6]) { - map.clear(); - map.set(keys[9], "Z"); - } - else if (key === keys[9]) { - // Check that the map behaves correctly when two items are - // added and removed immediately. - map.set(keys[10], "X"); - map.set(keys[11], "X1"); - map.set(keys[12], "X2"); - map.delete(keys[11]); - map.delete(keys[12]); - map.set(keys[13], "Y"); - } - }; - - if (useForEach) { - map.forEach(doForEach); - } - else { - // Use an iterator. - const iterator = map.entries(); - while (true) { - const iterResult = iterator.next(); - if (iterResult.done) { - break; - } - - const [key, value] = iterResult.value; - doForEach(value, key); - } - } - - return resultString; - } - - let MapShim!: MapConstructor; - beforeEach(() => { - function getIterator | ReadonlyESMap | undefined>(iterable: I): Iterator< - I extends ReadonlyESMap ? [K, V] : - I extends ReadonlySet ? T : - I extends readonly (infer T)[] ? T : - I extends undefined ? undefined : - never>; - function getIterator(iterable: readonly any[] | ReadonlySet | ReadonlyESMap | undefined): Iterator | undefined { - // override `ts.getIterator` with a version that allows us to iterate over a `MapShim` in an environment with a native `Map`. - if (iterable instanceof MapShim) return iterable.entries(); - return ts.getIterator(iterable); - } - - MapShim = ShimCollections.createMapShim(getIterator); - }); - afterEach(() => { - MapShim = undefined!; - }); - - it("iterates values in insertion order and handles changes with string keys", () => { - const expectedResult = "1:1;3:3;2:Y2;4:X4;0:X0;3:Y3;999:999;A:A;Z:Z;X:X;Y:Y;"; - - // First, ensure the test actually has the same behavior as a native Map. - let nativeMap = new Map(); - const nativeMapForEachResult = testMapIterationAddedValues(stringKeys, nativeMap, /* useForEach */ true); - assert.equal(nativeMapForEachResult, expectedResult, "nativeMap-forEach"); - - nativeMap = new Map(); - const nativeMapIteratorResult = testMapIterationAddedValues(stringKeys, nativeMap, /* useForEach */ false); - assert.equal(nativeMapIteratorResult, expectedResult, "nativeMap-iterator"); - - // Then, test the map shim. - let localShimMap = new MapShim(); - const shimMapForEachResult = testMapIterationAddedValues(stringKeys, localShimMap, /* useForEach */ true); - assert.equal(shimMapForEachResult, expectedResult, "shimMap-forEach"); - - localShimMap = new MapShim(); - const shimMapIteratorResult = testMapIterationAddedValues(stringKeys, localShimMap, /* useForEach */ false); - assert.equal(shimMapIteratorResult, expectedResult, "shimMap-iterator"); - }); - - it("iterates values in insertion order and handles changes with mixed-type keys", () => { - const expectedResult = "true:1;3:3;2:Y2;4:X4;false:X0;3:Y3;null:999;undefined:A;Z:Z;X:X;Y:Y;"; - - // First, ensure the test actually has the same behavior as a native Map. - let nativeMap = new Map(); - const nativeMapForEachResult = testMapIterationAddedValues(mixedKeys, nativeMap, /* useForEach */ true); - assert.equal(nativeMapForEachResult, expectedResult, "nativeMap-forEach"); - - nativeMap = new Map(); - const nativeMapIteratorResult = testMapIterationAddedValues(mixedKeys, nativeMap, /* useForEach */ false); - assert.equal(nativeMapIteratorResult, expectedResult, "nativeMap-iterator"); - - // Then, test the map shim. - let localShimMap = new MapShim(); - const shimMapForEachResult = testMapIterationAddedValues(mixedKeys, localShimMap, /* useForEach */ true); - assert.equal(shimMapForEachResult, expectedResult, "shimMap-forEach"); - - localShimMap = new MapShim(); - const shimMapIteratorResult = testMapIterationAddedValues(mixedKeys, localShimMap, /* useForEach */ false); - assert.equal(shimMapIteratorResult, expectedResult, "shimMap-iterator"); - }); - - it("create from Array", () => { - const map = new MapShim([["a", "b"]]); - assert.equal(map.size, 1); - assert.isTrue(map.has("a")); - assert.equal(map.get("a"), "b"); - }); - - it("create from Map", () => { - const map1 = new MapShim([["a", "b"]]); - const map2 = new MapShim(map1); - assert.equal(map1.size, 1); - assert.equal(map2.size, 1); - assert.isTrue(map2.has("a")); - assert.equal(map2.get("a"), "b"); - }); - - it("set when not present", () => { - const map = new MapShim(); - const result = map.set("a", "b"); - assert.equal(map.size, 1); - assert.strictEqual(result, map); - assert.isTrue(map.has("a")); - assert.equal(map.get("a"), "b"); - }); - - it("set when present", () => { - const map = new MapShim(); - map.set("a", "z"); - const result = map.set("a", "b"); - assert.equal(map.size, 1); - assert.strictEqual(result, map); - assert.isTrue(map.has("a")); - assert.equal(map.get("a"), "b"); - }); - - it("has when not present", () => { - const map = new MapShim(); - assert.isFalse(map.has("a")); - }); - - it("has when present", () => { - const map = new MapShim(); - map.set("a", "b"); - assert.isTrue(map.has("a")); - }); - - it("get when not present", () => { - const map = new MapShim(); - assert.isUndefined(map.get("a")); - }); - - it("get when present", () => { - const map = new MapShim(); - map.set("a", "b"); - assert.equal(map.get("a"), "b"); - }); - - it("delete when not present", () => { - const map = new MapShim(); - assert.isFalse(map.delete("a")); - }); - - it("delete when present", () => { - const map = new MapShim(); - map.set("a", "b"); - assert.isTrue(map.delete("a")); - }); - - it("delete twice when present", () => { - const map = new MapShim(); - map.set("a", "b"); - assert.isTrue(map.delete("a")); - assert.isFalse(map.delete("a")); - }); - - it("remove only item and iterate", () => { - const map = new MapShim(); - map.set("a", "b"); - map.delete("a"); - const actual = arrayFrom(map.keys()); - assert.deepEqual(actual, []); - }); - - it("remove first item and iterate", () => { - const map = new MapShim(); - map.set("a", "b"); - map.set("c", "d"); - map.delete("a"); - assert.deepEqual(arrayFrom(map.keys()), ["c"]); - assert.deepEqual(arrayFrom(map.values()), ["d"]); - assert.deepEqual(arrayFrom(map.entries()), [["c", "d"]]); - }); - - it("remove last item and iterate", () => { - const map = new MapShim(); - map.set("a", "b"); - map.set("c", "d"); - map.delete("c"); - assert.deepEqual(arrayFrom(map.keys()), ["a"]); - assert.deepEqual(arrayFrom(map.values()), ["b"]); - assert.deepEqual(arrayFrom(map.entries()), [["a", "b"]]); - }); - - it("remove middle item and iterate", () => { - const map = new MapShim(); - map.set("a", "b"); - map.set("c", "d"); - map.set("e", "f"); - map.delete("c"); - assert.deepEqual(arrayFrom(map.keys()), ["a", "e"]); - assert.deepEqual(arrayFrom(map.values()), ["b", "f"]); - assert.deepEqual(arrayFrom(map.entries()), [["a", "b"], ["e", "f"]]); - }); - - it("keys", () => { - const map = new MapShim(); - map.set("c", "d"); - map.set("a", "b"); - assert.deepEqual(arrayFrom(map.keys()), ["c", "a"]); - }); - - it("values", () => { - const map = new MapShim(); - map.set("c", "d"); - map.set("a", "b"); - assert.deepEqual(arrayFrom(map.values()), ["d", "b"]); - }); - - it("entries", () => { - const map = new MapShim(); - map.set("c", "d"); - map.set("a", "b"); - assert.deepEqual(arrayFrom(map.entries()), [["c", "d"], ["a", "b"]]); - }); - - it("forEach", () => { - const map = new MapShim(); - map.set("c", "d"); - map.set("a", "b"); - const actual: [string, string][] = []; - map.forEach((value, key) => actual.push([key, value])); - assert.deepEqual(actual, [["c", "d"], ["a", "b"]]); - }); - }); -} diff --git a/src/testRunner/unittests/createSetShim.ts b/src/testRunner/unittests/createSetShim.ts deleted file mode 100644 index bef82d78e2b61..0000000000000 --- a/src/testRunner/unittests/createSetShim.ts +++ /dev/null @@ -1,309 +0,0 @@ -namespace ts { - describe("unittests:: createSetShim", () => { - const stringKeys = [ - "1", - "3", - "2", - "4", - "0", - "999", - "A", - "B", - "C", - "Z", - "X", - "X1", - "X2", - "Y" - ]; - - const mixedKeys = [ - true, - 3, - { toString() { return "2"; } }, - "4", - false, - null, // eslint-disable-line no-null/no-null - undefined, - "B", - { toString() { return "C"; } }, - "Z", - "X", - { toString() { return "X1"; } }, - "X2", - "Y" - ]; - - function testSetIterationAddedValues(keys: K[], set: Set, useForEach: boolean): string { - let resultString = ""; - - set.add(keys[0]); - set.add(keys[1]); - set.add(keys[2]); - set.add(keys[3]); - - let addedThree = false; - const doForEach = (key: K) => { - resultString += `${key};`; - - // Add a new key ("0") - the set should provide this - // one in the next iteration. - if (key === keys[0]) { - set.add(keys[0]); - set.add(keys[4]); - set.add(keys[3]); - } - else if (key === keys[1]) { - if (!addedThree) { - addedThree = true; - - // Remove and re-add key "3"; the set should - // visit it after "0". - set.delete(keys[1]); - set.add(keys[1]); - - // Change the value of "2"; the set should provide - // it when visiting the key. - set.add(keys[2]); - } - else { - // Check that an entry added when we visit the - // currently last entry will still be visited. - set.add(keys[5]); - } - } - else if (key === keys[5]) { - // Ensure that clear() behaves correctly same as removing all keys. - set.add(keys[6]); - set.add(keys[7]); - set.add(keys[8]); - } - else if (key === keys[6]) { - set.clear(); - set.add(keys[9]); - } - else if (key === keys[9]) { - // Check that the set behaves correctly when two items are - // added and removed immediately. - set.add(keys[10]); - set.add(keys[11]); - set.add(keys[12]); - set.delete(keys[11]); - set.delete(keys[12]); - set.add(keys[13]); - } - }; - - if (useForEach) { - set.forEach(doForEach); - } - else { - // Use an iterator. - const iterator = set.values(); - while (true) { - const iterResult = iterator.next(); - if (iterResult.done) { - break; - } - - doForEach(iterResult.value); - } - } - - return resultString; - } - - let SetShim!: SetConstructor; - beforeEach(() => { - function getIterator | ReadonlyESMap | undefined>(iterable: I): Iterator< - I extends ReadonlyESMap ? [K, V] : - I extends ReadonlySet ? T : - I extends readonly (infer T)[] ? T : - I extends undefined ? undefined : - never>; - function getIterator(iterable: readonly any[] | ReadonlySet | ReadonlyESMap | undefined): Iterator | undefined { - // override `ts.getIterator` with a version that allows us to iterate over a `SetShim` in an environment with a native `Set`. - if (iterable instanceof SetShim) return iterable.values(); - return ts.getIterator(iterable); - } - - SetShim = ShimCollections.createSetShim(getIterator); - }); - afterEach(() => { - SetShim = undefined!; - }); - - it("iterates values in insertion order and handles changes with string keys", () => { - const expectedResult = "1;3;2;4;0;3;999;A;Z;X;Y;"; - - // First, ensure the test actually has the same behavior as a native Set. - let nativeSet = new Set(); - const nativeSetForEachResult = testSetIterationAddedValues(stringKeys, nativeSet, /* useForEach */ true); - assert.equal(nativeSetForEachResult, expectedResult, "nativeSet-forEach"); - - nativeSet = new Set(); - const nativeSetIteratorResult = testSetIterationAddedValues(stringKeys, nativeSet, /* useForEach */ false); - assert.equal(nativeSetIteratorResult, expectedResult, "nativeSet-iterator"); - - // Then, test the set shim. - let localShimSet = new SetShim(); - const shimSetForEachResult = testSetIterationAddedValues(stringKeys, localShimSet, /* useForEach */ true); - assert.equal(shimSetForEachResult, expectedResult, "shimSet-forEach"); - - localShimSet = new SetShim(); - const shimSetIteratorResult = testSetIterationAddedValues(stringKeys, localShimSet, /* useForEach */ false); - assert.equal(shimSetIteratorResult, expectedResult, "shimSet-iterator"); - }); - - it("iterates values in insertion order and handles changes with mixed-type keys", () => { - const expectedResult = "true;3;2;4;false;3;null;undefined;Z;X;Y;"; - - // First, ensure the test actually has the same behavior as a native Set. - let nativeSet = new Set(); - const nativeSetForEachResult = testSetIterationAddedValues(mixedKeys, nativeSet, /* useForEach */ true); - assert.equal(nativeSetForEachResult, expectedResult, "nativeSet-forEach"); - - nativeSet = new Set(); - const nativeSetIteratorResult = testSetIterationAddedValues(mixedKeys, nativeSet, /* useForEach */ false); - assert.equal(nativeSetIteratorResult, expectedResult, "nativeSet-iterator"); - - // Then, test the set shim. - let localshimSet = new SetShim(); - const shimSetForEachResult = testSetIterationAddedValues(mixedKeys, localshimSet, /* useForEach */ true); - assert.equal(shimSetForEachResult, expectedResult, "shimSet-forEach"); - - localshimSet = new SetShim(); - const shimSetIteratorResult = testSetIterationAddedValues(mixedKeys, localshimSet, /* useForEach */ false); - assert.equal(shimSetIteratorResult, expectedResult, "shimSet-iterator"); - }); - - it("create from Array", () => { - const set = new SetShim(["a"]); - assert.equal(set.size, 1); - assert.isTrue(set.has("a")); - }); - - it("create from set", () => { - const set1 = new SetShim(["a"]); - const set2 = new SetShim(set1); - assert.equal(set1.size, 1); - assert.equal(set2.size, 1); - assert.isTrue(set2.has("a")); - }); - - it("add when not present", () => { - const set = new SetShim(); - const result = set.add("a"); - assert.equal(set.size, 1); - assert.strictEqual(result, set); - assert.isTrue(set.has("a")); - }); - - it("add when present", () => { - const set = new SetShim(); - set.add("a"); - const result = set.add("a"); - assert.equal(set.size, 1); - assert.strictEqual(result, set); - assert.isTrue(set.has("a")); - }); - - it("has when not present", () => { - const set = new SetShim(); - assert.isFalse(set.has("a")); - }); - - it("has when present", () => { - const set = new SetShim(); - set.add("a"); - assert.isTrue(set.has("a")); - }); - - it("delete when not present", () => { - const set = new SetShim(); - assert.isFalse(set.delete("a")); - }); - - it("delete when present", () => { - const set = new SetShim(); - set.add("a"); - assert.isTrue(set.delete("a")); - }); - - it("delete twice when present", () => { - const set = new SetShim(); - set.add("a"); - assert.isTrue(set.delete("a")); - assert.isFalse(set.delete("a")); - }); - - it("remove only item and iterate", () => { - const set = new SetShim(); - set.add("a"); - set.delete("a"); - const actual = arrayFrom(set.keys()); - assert.deepEqual(actual, []); - }); - - it("remove first item and iterate", () => { - const set = new SetShim(); - set.add("a"); - set.add("c"); - set.delete("a"); - assert.deepEqual(arrayFrom(set.keys()), ["c"]); - assert.deepEqual(arrayFrom(set.values()), ["c"]); - assert.deepEqual(arrayFrom(set.entries()), [["c", "c"]]); - }); - - it("remove last item and iterate", () => { - const set = new SetShim(); - set.add("a"); - set.add("c"); - set.delete("c"); - assert.deepEqual(arrayFrom(set.keys()), ["a"]); - assert.deepEqual(arrayFrom(set.values()), ["a"]); - assert.deepEqual(arrayFrom(set.entries()), [["a", "a"]]); - }); - - it("remove middle item and iterate", () => { - const set = new SetShim(); - set.add("a"); - set.add("c"); - set.add("e"); - set.delete("c"); - assert.deepEqual(arrayFrom(set.keys()), ["a", "e"]); - assert.deepEqual(arrayFrom(set.values()), ["a", "e"]); - assert.deepEqual(arrayFrom(set.entries()), [["a", "a"], ["e", "e"]]); - }); - - it("keys", () => { - const set = new SetShim(); - set.add("c"); - set.add("a"); - assert.deepEqual(arrayFrom(set.keys()), ["c", "a"]); - }); - - it("values", () => { - const set = new SetShim(); - set.add("c"); - set.add("a"); - assert.deepEqual(arrayFrom(set.values()), ["c", "a"]); - }); - - it("entries", () => { - const set = new SetShim(); - set.add("c"); - set.add("a"); - assert.deepEqual(arrayFrom(set.entries()), [["c", "c"], ["a", "a"]]); - }); - - it("forEach", () => { - const set = new SetShim(); - set.add("c"); - set.add("a"); - const actual: [string, string][] = []; - set.forEach((value, key) => actual.push([key, value])); - assert.deepEqual(actual, [["c", "c"], ["a", "a"]]); - }); - }); -} diff --git a/src/tsconfig.json b/src/tsconfig.json index ca929ee198ca1..a8ae1655e8fd4 100644 --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -2,7 +2,6 @@ "files": [], "include": [], "references": [ - { "path": "./shims" }, { "path": "./tsc" }, { "path": "./tsserver" }, { "path": "./typingsInstaller" }, @@ -12,4 +11,4 @@ { "path": "./dynamicImportCompat" }, { "path": "./testRunner" } ] -} \ No newline at end of file +} diff --git a/src/tsserverlibrary/tsconfig.json b/src/tsserverlibrary/tsconfig.json index 28217e40cf80e..0450e98a8a4e7 100644 --- a/src/tsserverlibrary/tsconfig.json +++ b/src/tsserverlibrary/tsconfig.json @@ -7,7 +7,6 @@ "tsserverlibrary.ts" ], "references": [ - { "path": "../shims", "prepend": true }, { "path": "../compiler", "prepend": true }, { "path": "../jsTyping", "prepend": true }, { "path": "../services", "prepend": true }, diff --git a/src/typescriptServices/tsconfig.json b/src/typescriptServices/tsconfig.json index 68b1e50254ddc..e2ec0c2700988 100644 --- a/src/typescriptServices/tsconfig.json +++ b/src/typescriptServices/tsconfig.json @@ -7,7 +7,6 @@ "typescriptServices.ts" ], "references": [ - { "path": "../shims", "prepend": true }, { "path": "../compiler", "prepend": true }, { "path": "../jsTyping", "prepend": true }, { "path": "../services", "prepend": true },