diff --git a/src/vs/base/common/map.ts b/src/vs/base/common/map.ts index 5d79ad368a744..611078e185220 100644 --- a/src/vs/base/common/map.ts +++ b/src/vs/base/common/map.ts @@ -580,7 +580,9 @@ export const enum Touch { AsNew = 2 } -export class LinkedMap { +export class LinkedMap implements Map{ + + readonly [Symbol.toStringTag] = 'LinkedMap'; private _map: Map>; private _head: Item | undefined; @@ -632,7 +634,7 @@ export class LinkedMap { return item.value; } - set(key: K, value: V, touch: Touch = Touch.None): void { + set(key: K, value: V, touch: Touch = Touch.None): this { let item = this._map.get(key); if (item) { item.value = value; @@ -658,6 +660,7 @@ export class LinkedMap { this._map.set(key, item); this._size++; } + return this; } delete(key: K): boolean { @@ -701,34 +704,13 @@ export class LinkedMap { } } - values(): V[] { - const result: V[] = []; - let current = this._head; - while (current) { - result.push(current.value); - current = current.next; - } - return result; - } - - keys(): K[] { - const result: K[] = []; - let current = this._head; - while (current) { - result.push(current.key); - current = current.next; - } - return result; - } - - /* VS Code / Monaco editor runs on es5 which has no Symbol.iterator keys(): IterableIterator { - const current = this._head; + let current = this._head; const iterator: IterableIterator = { [Symbol.iterator]() { return iterator; }, - next():IteratorResult { + next(): IteratorResult { if (current) { const result = { value: current.key, done: false }; current = current.next; @@ -742,12 +724,12 @@ export class LinkedMap { } values(): IterableIterator { - const current = this._head; + let current = this._head; const iterator: IterableIterator = { [Symbol.iterator]() { return iterator; }, - next():IteratorResult { + next(): IteratorResult { if (current) { const result = { value: current.value, done: false }; current = current.next; @@ -759,7 +741,29 @@ export class LinkedMap { }; return iterator; } - */ + + entries(): IterableIterator<[K, V]> { + let current = this._head; + const iterator: IterableIterator<[K, V]> = { + [Symbol.iterator]() { + return iterator; + }, + next(): IteratorResult<[K, V]> { + if (current) { + const result: IteratorResult<[K, V]> = { value: [current.key, current.value], done: false }; + current = current.next; + return result; + } else { + return { value: undefined, done: true }; + } + } + }; + return iterator; + } + + [Symbol.iterator](): IterableIterator<[K, V]> { + return this.entries(); + } protected trimOld(newSize: number) { if (newSize >= this.size) { @@ -961,9 +965,10 @@ export class LRUCache extends LinkedMap { return super.get(key, Touch.None); } - set(key: K, value: V): void { + set(key: K, value: V): this { super.set(key, value, Touch.AsNew); this.checkTrim(); + return this; } private checkTrim() { diff --git a/src/vs/base/test/common/map.test.ts b/src/vs/base/test/common/map.test.ts index c9a99858854e2..d10d2176cb58d 100644 --- a/src/vs/base/test/common/map.test.ts +++ b/src/vs/base/test/common/map.test.ts @@ -13,8 +13,8 @@ suite('Map', () => { let map = new LinkedMap(); map.set('ak', 'av'); map.set('bk', 'bv'); - assert.deepStrictEqual(map.keys(), ['ak', 'bk']); - assert.deepStrictEqual(map.values(), ['av', 'bv']); + assert.deepStrictEqual([...map.keys()], ['ak', 'bk']); + assert.deepStrictEqual([...map.values()], ['av', 'bv']); assert.equal(map.first, 'av'); assert.equal(map.last, 'bv'); }); @@ -23,16 +23,16 @@ suite('Map', () => { let map = new LinkedMap(); map.set('ak', 'av'); map.set('ak', 'av', Touch.AsOld); - assert.deepStrictEqual(map.keys(), ['ak']); - assert.deepStrictEqual(map.values(), ['av']); + assert.deepStrictEqual([...map.keys()], ['ak']); + assert.deepStrictEqual([...map.values()], ['av']); }); test('LinkedMap - Touch New one', () => { let map = new LinkedMap(); map.set('ak', 'av'); map.set('ak', 'av', Touch.AsNew); - assert.deepStrictEqual(map.keys(), ['ak']); - assert.deepStrictEqual(map.values(), ['av']); + assert.deepStrictEqual([...map.keys()], ['ak']); + assert.deepStrictEqual([...map.values()], ['av']); }); test('LinkedMap - Touch Old two', () => { @@ -40,8 +40,8 @@ suite('Map', () => { map.set('ak', 'av'); map.set('bk', 'bv'); map.set('bk', 'bv', Touch.AsOld); - assert.deepStrictEqual(map.keys(), ['bk', 'ak']); - assert.deepStrictEqual(map.values(), ['bv', 'av']); + assert.deepStrictEqual([...map.keys()], ['bk', 'ak']); + assert.deepStrictEqual([...map.values()], ['bv', 'av']); }); test('LinkedMap - Touch New two', () => { @@ -49,8 +49,8 @@ suite('Map', () => { map.set('ak', 'av'); map.set('bk', 'bv'); map.set('ak', 'av', Touch.AsNew); - assert.deepStrictEqual(map.keys(), ['bk', 'ak']); - assert.deepStrictEqual(map.values(), ['bv', 'av']); + assert.deepStrictEqual([...map.keys()], ['bk', 'ak']); + assert.deepStrictEqual([...map.values()], ['bv', 'av']); }); test('LinkedMap - Touch Old from middle', () => { @@ -59,8 +59,8 @@ suite('Map', () => { map.set('bk', 'bv'); map.set('ck', 'cv'); map.set('bk', 'bv', Touch.AsOld); - assert.deepStrictEqual(map.keys(), ['bk', 'ak', 'ck']); - assert.deepStrictEqual(map.values(), ['bv', 'av', 'cv']); + assert.deepStrictEqual([...map.keys()], ['bk', 'ak', 'ck']); + assert.deepStrictEqual([...map.values()], ['bv', 'av', 'cv']); }); test('LinkedMap - Touch New from middle', () => { @@ -69,8 +69,8 @@ suite('Map', () => { map.set('bk', 'bv'); map.set('ck', 'cv'); map.set('bk', 'bv', Touch.AsNew); - assert.deepStrictEqual(map.keys(), ['ak', 'ck', 'bk']); - assert.deepStrictEqual(map.values(), ['av', 'cv', 'bv']); + assert.deepStrictEqual([...map.keys()], ['ak', 'ck', 'bk']); + assert.deepStrictEqual([...map.values()], ['av', 'cv', 'bv']); }); test('LinkedMap - basics', function () { @@ -136,13 +136,15 @@ suite('Map', () => { assert.strictEqual(cache.size, 5); cache.set(6, 6); assert.strictEqual(cache.size, 5); - assert.deepStrictEqual(cache.keys(), [2, 3, 4, 5, 6]); + assert.deepStrictEqual([...cache.keys()], [2, 3, 4, 5, 6]); cache.set(7, 7); assert.strictEqual(cache.size, 5); - assert.deepStrictEqual(cache.keys(), [3, 4, 5, 6, 7]); + assert.deepStrictEqual([...cache.keys()], [3, 4, 5, 6, 7]); let values: number[] = []; [3, 4, 5, 6, 7].forEach(key => values.push(cache.get(key)!)); assert.deepStrictEqual(values, [3, 4, 5, 6, 7]); + + assert.deepEqual([...cache.entries()], [[3, 3], [4, 4], [5, 5], [6, 6], [7, 7]]); }); test('LinkedMap - LRU Cache get', () => { @@ -150,11 +152,11 @@ suite('Map', () => { [1, 2, 3, 4, 5].forEach(value => cache.set(value, value)); assert.strictEqual(cache.size, 5); - assert.deepStrictEqual(cache.keys(), [1, 2, 3, 4, 5]); + assert.deepStrictEqual([...cache.keys()], [1, 2, 3, 4, 5]); cache.get(3); - assert.deepStrictEqual(cache.keys(), [1, 2, 4, 5, 3]); + assert.deepStrictEqual([...cache.keys()], [1, 2, 4, 5, 3]); cache.peek(4); - assert.deepStrictEqual(cache.keys(), [1, 2, 4, 5, 3]); + assert.deepStrictEqual([...cache.keys()], [1, 2, 4, 5, 3]); let values: number[] = []; [1, 2, 3, 4, 5].forEach(key => values.push(cache.get(key)!)); assert.deepStrictEqual(values, [1, 2, 3, 4, 5]); @@ -169,7 +171,7 @@ suite('Map', () => { assert.strictEqual(cache.size, 10); cache.limit = 5; assert.strictEqual(cache.size, 5); - assert.deepStrictEqual(cache.keys(), [6, 7, 8, 9, 10]); + assert.deepStrictEqual([...cache.keys()], [6, 7, 8, 9, 10]); cache.limit = 20; assert.strictEqual(cache.size, 5); for (let i = 11; i <= 20; i++) { @@ -181,7 +183,7 @@ suite('Map', () => { values.push(cache.get(i)!); assert.strictEqual(cache.get(i), i); } - assert.deepStrictEqual(cache.values(), values); + assert.deepStrictEqual([...cache.values()], values); }); test('LinkedMap - LRU Cache limit with ratio', () => { @@ -193,11 +195,11 @@ suite('Map', () => { assert.strictEqual(cache.size, 10); cache.set(11, 11); assert.strictEqual(cache.size, 5); - assert.deepStrictEqual(cache.keys(), [7, 8, 9, 10, 11]); + assert.deepStrictEqual([...cache.keys()], [7, 8, 9, 10, 11]); let values: number[] = []; - cache.keys().forEach(key => values.push(cache.get(key)!)); + [...cache.keys()].forEach(key => values.push(cache.get(key)!)); assert.deepStrictEqual(values, [7, 8, 9, 10, 11]); - assert.deepStrictEqual(cache.values(), values); + assert.deepStrictEqual([...cache.values()], values); }); test('LinkedMap - toJSON / fromJSON', () => { @@ -237,7 +239,7 @@ suite('Map', () => { map.delete('1'); assert.equal(map.get('1'), undefined); assert.equal(map.size, 0); - assert.equal(map.keys().length, 0); + assert.equal([...map.keys()].length, 0); }); test('LinkedMap - delete Head', function () { @@ -251,8 +253,8 @@ suite('Map', () => { map.delete('1'); assert.equal(map.get('2'), 2); assert.equal(map.size, 1); - assert.equal(map.keys().length, 1); - assert.equal(map.keys()[0], 2); + assert.equal([...map.keys()].length, 1); + assert.equal([...map.keys()][0], 2); }); test('LinkedMap - delete Tail', function () { @@ -266,8 +268,8 @@ suite('Map', () => { map.delete('2'); assert.equal(map.get('1'), 1); assert.equal(map.size, 1); - assert.equal(map.keys().length, 1); - assert.equal(map.keys()[0], 1); + assert.equal([...map.keys()].length, 1); + assert.equal([...map.keys()][0], 1); }); diff --git a/src/vs/workbench/browser/parts/editor/editorsObserver.ts b/src/vs/workbench/browser/parts/editor/editorsObserver.ts index 47d62dc935135..7d8ae5490342d 100644 --- a/src/vs/workbench/browser/parts/editor/editorsObserver.ts +++ b/src/vs/workbench/browser/parts/editor/editorsObserver.ts @@ -48,7 +48,7 @@ export class EditorsObserver extends Disposable { } get editors(): IEditorIdentifier[] { - return this.mostRecentEditorsMap.values(); + return [...this.mostRecentEditorsMap.values()]; } hasEditor(resource: URI): boolean { @@ -283,7 +283,7 @@ export class EditorsObserver extends Disposable { // Across all editor groups else { - await this.doEnsureOpenedEditorsLimit(limit, this.mostRecentEditorsMap.values(), exclude); + await this.doEnsureOpenedEditorsLimit(limit, [...this.mostRecentEditorsMap.values()], exclude); } } @@ -342,7 +342,7 @@ export class EditorsObserver extends Disposable { private serialize(): ISerializedEditorsList { const registry = Registry.as(Extensions.EditorInputFactories); - const entries = this.mostRecentEditorsMap.values(); + const entries = [...this.mostRecentEditorsMap.values()]; const mapGroupToSerializableEditorsOfGroup = new Map(); return { diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index fd1ee7b2abf3b..b95522fd605f2 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -791,7 +791,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer if (quickOpenHistoryLimit === 0) { return; } - let keys = this._recentlyUsedTasks.keys(); + let keys = [...this._recentlyUsedTasks.keys()]; if (keys.length > quickOpenHistoryLimit) { keys = keys.slice(0, quickOpenHistoryLimit); } @@ -2323,7 +2323,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer taskMap[key] = task; } }); - const reversed = recentlyUsedTasks.keys().reverse(); + const reversed = [...recentlyUsedTasks.keys()].reverse(); for (const key in reversed) { let task = taskMap[key]; if (task) {