feat(lib/es2021): Add type parameter to FinalizationRegistry
(#42274)
* feat(lib/es2021): Add type parameter to `FinalizationRegistry` * test(lib/es2021): Add test for generic `FinalizationRegistry`
This commit is contained in:
parent
9950b6e596
commit
0723904bfb
10
src/lib/esnext.weakref.d.ts
vendored
10
src/lib/esnext.weakref.d.ts
vendored
|
@ -15,12 +15,12 @@ interface WeakRefConstructor {
|
|||
* Creates a WeakRef instance for the given target object.
|
||||
* @param target The target object for the WeakRef instance.
|
||||
*/
|
||||
new<T extends object>(target?: T): WeakRef<T>;
|
||||
new<T extends object>(target: T): WeakRef<T>;
|
||||
}
|
||||
|
||||
declare var WeakRef: WeakRefConstructor;
|
||||
|
||||
interface FinalizationRegistry {
|
||||
interface FinalizationRegistry<T> {
|
||||
readonly [Symbol.toStringTag]: "FinalizationRegistry";
|
||||
|
||||
/**
|
||||
|
@ -32,7 +32,7 @@ interface FinalizationRegistry {
|
|||
* object. If provided (and not undefined), this must be an object. If not provided, the target
|
||||
* cannot be unregistered.
|
||||
*/
|
||||
register(target: object, heldValue: any, unregisterToken?: object): void;
|
||||
register(target: object, heldValue: T, unregisterToken?: object): void;
|
||||
|
||||
/**
|
||||
* Unregisters an object from the registry.
|
||||
|
@ -43,13 +43,13 @@ interface FinalizationRegistry {
|
|||
}
|
||||
|
||||
interface FinalizationRegistryConstructor {
|
||||
readonly prototype: FinalizationRegistry;
|
||||
readonly prototype: FinalizationRegistry<any>;
|
||||
|
||||
/**
|
||||
* Creates a finalization registry with an associated cleanup callback
|
||||
* @param cleanupCallback The callback to call after an object in the registry has been reclaimed.
|
||||
*/
|
||||
new(cleanupCallback: (heldValue: any) => void): FinalizationRegistry;
|
||||
new<T>(cleanupCallback: (heldValue: T) => void): FinalizationRegistry<T>;
|
||||
}
|
||||
|
||||
declare var FinalizationRegistry: FinalizationRegistryConstructor;
|
||||
|
|
189
tests/baselines/reference/esNextWeakRefs_IterableWeakMap.js
Normal file
189
tests/baselines/reference/esNextWeakRefs_IterableWeakMap.js
Normal file
|
@ -0,0 +1,189 @@
|
|||
//// [esNextWeakRefs_IterableWeakMap.ts]
|
||||
/** `static #cleanup` */
|
||||
const IterableWeakMap_cleanup = ({ ref, set }: {
|
||||
readonly ref: WeakRef<object>;
|
||||
readonly set: Set<WeakRef<object>>;
|
||||
}) => {
|
||||
set.delete(ref);
|
||||
};
|
||||
|
||||
// Based on: https://github.com/tc39/proposal-weakrefs/blob/master/README.md#iterable-weakmaps
|
||||
export class IterableWeakMap<K extends object, V> implements WeakMap<K, V> {
|
||||
declare readonly [Symbol.toStringTag]: "IterableWeakMap";
|
||||
|
||||
#weakMap = new WeakMap<K, { readonly ref: WeakRef<K>; value: V }>();
|
||||
#refSet = new Set<WeakRef<K>>();
|
||||
#finalizationGroup = new FinalizationRegistry(IterableWeakMap_cleanup);
|
||||
|
||||
constructor(iterable: Iterable<[key: K, value: V]> | null = null) {
|
||||
if (iterable !== null) {
|
||||
for (const { 0: key, 1: value } of iterable) {
|
||||
this.set(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set(key: K, value: V): this {
|
||||
const entry = this.#weakMap.get(key);
|
||||
if (entry !== undefined) {
|
||||
entry.value = value;
|
||||
} else {
|
||||
const ref = new WeakRef(key);
|
||||
|
||||
this.#weakMap.set(key, { ref, value });
|
||||
this.#refSet.add(ref);
|
||||
this.#finalizationGroup.register(key, {
|
||||
set: this.#refSet,
|
||||
ref,
|
||||
}, ref);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
has(key: K): boolean {
|
||||
return this.#weakMap.has(key);
|
||||
}
|
||||
|
||||
get(key: K): V | undefined {
|
||||
return this.#weakMap.get(key)?.value;
|
||||
}
|
||||
|
||||
delete(key: K): boolean {
|
||||
const entry = this.#weakMap.get(key);
|
||||
if (entry === undefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const { ref } = entry;
|
||||
this.#weakMap.delete(key);
|
||||
this.#refSet.delete(ref);
|
||||
this.#finalizationGroup.unregister(ref);
|
||||
return true;
|
||||
}
|
||||
|
||||
declare [Symbol.iterator]: this["entries"];
|
||||
*entries(): Generator<[key: K, value: V], void> {
|
||||
for (const ref of this.#refSet) {
|
||||
const key = ref.deref();
|
||||
if (key === undefined) continue;
|
||||
const { value } = this.#weakMap.get(key)!;
|
||||
yield [key, value];
|
||||
}
|
||||
}
|
||||
|
||||
*keys() {
|
||||
for (const { 0: key } of this) {
|
||||
yield key;
|
||||
}
|
||||
}
|
||||
|
||||
*values() {
|
||||
for (const { 1: value } of this) {
|
||||
yield value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperties(IterableWeakMap.prototype, {
|
||||
[Symbol.iterator]: {
|
||||
configurable: true,
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
value: Object.getOwnPropertyDescriptor(
|
||||
IterableWeakMap.prototype,
|
||||
"entries",
|
||||
)!.value,
|
||||
},
|
||||
[Symbol.toStringTag]: {
|
||||
configurable: true,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: "IterableWeakMap",
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
//// [esNextWeakRefs_IterableWeakMap.js]
|
||||
/** `static #cleanup` */
|
||||
const IterableWeakMap_cleanup = ({ ref, set }) => {
|
||||
set.delete(ref);
|
||||
};
|
||||
// Based on: https://github.com/tc39/proposal-weakrefs/blob/master/README.md#iterable-weakmaps
|
||||
export class IterableWeakMap {
|
||||
#weakMap = new WeakMap();
|
||||
#refSet = new Set();
|
||||
#finalizationGroup = new FinalizationRegistry(IterableWeakMap_cleanup);
|
||||
constructor(iterable = null) {
|
||||
if (iterable !== null) {
|
||||
for (const { 0: key, 1: value } of iterable) {
|
||||
this.set(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
set(key, value) {
|
||||
const entry = this.#weakMap.get(key);
|
||||
if (entry !== undefined) {
|
||||
entry.value = value;
|
||||
}
|
||||
else {
|
||||
const ref = new WeakRef(key);
|
||||
this.#weakMap.set(key, { ref, value });
|
||||
this.#refSet.add(ref);
|
||||
this.#finalizationGroup.register(key, {
|
||||
set: this.#refSet,
|
||||
ref,
|
||||
}, ref);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
has(key) {
|
||||
return this.#weakMap.has(key);
|
||||
}
|
||||
get(key) {
|
||||
return this.#weakMap.get(key)?.value;
|
||||
}
|
||||
delete(key) {
|
||||
const entry = this.#weakMap.get(key);
|
||||
if (entry === undefined) {
|
||||
return false;
|
||||
}
|
||||
const { ref } = entry;
|
||||
this.#weakMap.delete(key);
|
||||
this.#refSet.delete(ref);
|
||||
this.#finalizationGroup.unregister(ref);
|
||||
return true;
|
||||
}
|
||||
*entries() {
|
||||
for (const ref of this.#refSet) {
|
||||
const key = ref.deref();
|
||||
if (key === undefined)
|
||||
continue;
|
||||
const { value } = this.#weakMap.get(key);
|
||||
yield [key, value];
|
||||
}
|
||||
}
|
||||
*keys() {
|
||||
for (const { 0: key } of this) {
|
||||
yield key;
|
||||
}
|
||||
}
|
||||
*values() {
|
||||
for (const { 1: value } of this) {
|
||||
yield value;
|
||||
}
|
||||
}
|
||||
}
|
||||
Object.defineProperties(IterableWeakMap.prototype, {
|
||||
[Symbol.iterator]: {
|
||||
configurable: true,
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
value: Object.getOwnPropertyDescriptor(IterableWeakMap.prototype, "entries").value,
|
||||
},
|
||||
[Symbol.toStringTag]: {
|
||||
configurable: true,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: "IterableWeakMap",
|
||||
},
|
||||
});
|
358
tests/baselines/reference/esNextWeakRefs_IterableWeakMap.symbols
Normal file
358
tests/baselines/reference/esNextWeakRefs_IterableWeakMap.symbols
Normal file
|
@ -0,0 +1,358 @@
|
|||
=== tests/cases/compiler/esNextWeakRefs_IterableWeakMap.ts ===
|
||||
/** `static #cleanup` */
|
||||
const IterableWeakMap_cleanup = ({ ref, set }: {
|
||||
>IterableWeakMap_cleanup : Symbol(IterableWeakMap_cleanup, Decl(esNextWeakRefs_IterableWeakMap.ts, 1, 5))
|
||||
>ref : Symbol(ref, Decl(esNextWeakRefs_IterableWeakMap.ts, 1, 34))
|
||||
>set : Symbol(set, Decl(esNextWeakRefs_IterableWeakMap.ts, 1, 39))
|
||||
|
||||
readonly ref: WeakRef<object>;
|
||||
>ref : Symbol(ref, Decl(esNextWeakRefs_IterableWeakMap.ts, 1, 48))
|
||||
>WeakRef : Symbol(WeakRef, Decl(lib.esnext.weakref.d.ts, --, --), Decl(lib.esnext.weakref.d.ts, --, --))
|
||||
|
||||
readonly set: Set<WeakRef<object>>;
|
||||
>set : Symbol(set, Decl(esNextWeakRefs_IterableWeakMap.ts, 2, 34))
|
||||
>Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
|
||||
>WeakRef : Symbol(WeakRef, Decl(lib.esnext.weakref.d.ts, --, --), Decl(lib.esnext.weakref.d.ts, --, --))
|
||||
|
||||
}) => {
|
||||
set.delete(ref);
|
||||
>set.delete : Symbol(Set.delete, Decl(lib.es2015.collection.d.ts, --, --))
|
||||
>set : Symbol(set, Decl(esNextWeakRefs_IterableWeakMap.ts, 1, 39))
|
||||
>delete : Symbol(Set.delete, Decl(lib.es2015.collection.d.ts, --, --))
|
||||
>ref : Symbol(ref, Decl(esNextWeakRefs_IterableWeakMap.ts, 1, 34))
|
||||
|
||||
};
|
||||
|
||||
// Based on: https://github.com/tc39/proposal-weakrefs/blob/master/README.md#iterable-weakmaps
|
||||
export class IterableWeakMap<K extends object, V> implements WeakMap<K, V> {
|
||||
>IterableWeakMap : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2))
|
||||
>K : Symbol(K, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 29))
|
||||
>V : Symbol(V, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 46))
|
||||
>WeakMap : Symbol(WeakMap, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
|
||||
>K : Symbol(K, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 29))
|
||||
>V : Symbol(V, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 46))
|
||||
|
||||
declare readonly [Symbol.toStringTag]: "IterableWeakMap";
|
||||
>[Symbol.toStringTag] : Symbol(IterableWeakMap[Symbol.toStringTag], Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 76))
|
||||
>Symbol.toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
|
||||
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --))
|
||||
>toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
|
||||
|
||||
#weakMap = new WeakMap<K, { readonly ref: WeakRef<K>; value: V }>();
|
||||
>#weakMap : Symbol(IterableWeakMap.#weakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 10, 61))
|
||||
>WeakMap : Symbol(WeakMap, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
|
||||
>K : Symbol(K, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 29))
|
||||
>ref : Symbol(ref, Decl(esNextWeakRefs_IterableWeakMap.ts, 12, 31))
|
||||
>WeakRef : Symbol(WeakRef, Decl(lib.esnext.weakref.d.ts, --, --), Decl(lib.esnext.weakref.d.ts, --, --))
|
||||
>K : Symbol(K, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 29))
|
||||
>value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 12, 57))
|
||||
>V : Symbol(V, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 46))
|
||||
|
||||
#refSet = new Set<WeakRef<K>>();
|
||||
>#refSet : Symbol(IterableWeakMap.#refSet, Decl(esNextWeakRefs_IterableWeakMap.ts, 12, 72))
|
||||
>Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
|
||||
>WeakRef : Symbol(WeakRef, Decl(lib.esnext.weakref.d.ts, --, --), Decl(lib.esnext.weakref.d.ts, --, --))
|
||||
>K : Symbol(K, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 29))
|
||||
|
||||
#finalizationGroup = new FinalizationRegistry(IterableWeakMap_cleanup);
|
||||
>#finalizationGroup : Symbol(IterableWeakMap.#finalizationGroup, Decl(esNextWeakRefs_IterableWeakMap.ts, 13, 36))
|
||||
>FinalizationRegistry : Symbol(FinalizationRegistry, Decl(lib.esnext.weakref.d.ts, --, --), Decl(lib.esnext.weakref.d.ts, --, --))
|
||||
>IterableWeakMap_cleanup : Symbol(IterableWeakMap_cleanup, Decl(esNextWeakRefs_IterableWeakMap.ts, 1, 5))
|
||||
|
||||
constructor(iterable: Iterable<[key: K, value: V]> | null = null) {
|
||||
>iterable : Symbol(iterable, Decl(esNextWeakRefs_IterableWeakMap.ts, 16, 16))
|
||||
>Iterable : Symbol(Iterable, Decl(lib.es2015.iterable.d.ts, --, --))
|
||||
>K : Symbol(K, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 29))
|
||||
>V : Symbol(V, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 46))
|
||||
|
||||
if (iterable !== null) {
|
||||
>iterable : Symbol(iterable, Decl(esNextWeakRefs_IterableWeakMap.ts, 16, 16))
|
||||
|
||||
for (const { 0: key, 1: value } of iterable) {
|
||||
>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 18, 24))
|
||||
>value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 18, 32))
|
||||
>iterable : Symbol(iterable, Decl(esNextWeakRefs_IterableWeakMap.ts, 16, 16))
|
||||
|
||||
this.set(key, value);
|
||||
>this.set : Symbol(IterableWeakMap.set, Decl(esNextWeakRefs_IterableWeakMap.ts, 22, 5))
|
||||
>this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2))
|
||||
>set : Symbol(IterableWeakMap.set, Decl(esNextWeakRefs_IterableWeakMap.ts, 22, 5))
|
||||
>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 18, 24))
|
||||
>value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 18, 32))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set(key: K, value: V): this {
|
||||
>set : Symbol(IterableWeakMap.set, Decl(esNextWeakRefs_IterableWeakMap.ts, 22, 5))
|
||||
>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 24, 8))
|
||||
>K : Symbol(K, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 29))
|
||||
>value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 24, 15))
|
||||
>V : Symbol(V, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 46))
|
||||
|
||||
const entry = this.#weakMap.get(key);
|
||||
>entry : Symbol(entry, Decl(esNextWeakRefs_IterableWeakMap.ts, 25, 13))
|
||||
>this.#weakMap.get : Symbol(WeakMap.get, Decl(lib.es2015.collection.d.ts, --, --))
|
||||
>this.#weakMap : Symbol(IterableWeakMap.#weakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 10, 61))
|
||||
>this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2))
|
||||
>get : Symbol(WeakMap.get, Decl(lib.es2015.collection.d.ts, --, --))
|
||||
>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 24, 8))
|
||||
|
||||
if (entry !== undefined) {
|
||||
>entry : Symbol(entry, Decl(esNextWeakRefs_IterableWeakMap.ts, 25, 13))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
entry.value = value;
|
||||
>entry.value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 12, 57))
|
||||
>entry : Symbol(entry, Decl(esNextWeakRefs_IterableWeakMap.ts, 25, 13))
|
||||
>value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 12, 57))
|
||||
>value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 24, 15))
|
||||
|
||||
} else {
|
||||
const ref = new WeakRef(key);
|
||||
>ref : Symbol(ref, Decl(esNextWeakRefs_IterableWeakMap.ts, 29, 17))
|
||||
>WeakRef : Symbol(WeakRef, Decl(lib.esnext.weakref.d.ts, --, --), Decl(lib.esnext.weakref.d.ts, --, --))
|
||||
>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 24, 8))
|
||||
|
||||
this.#weakMap.set(key, { ref, value });
|
||||
>this.#weakMap.set : Symbol(WeakMap.set, Decl(lib.es2015.collection.d.ts, --, --))
|
||||
>this.#weakMap : Symbol(IterableWeakMap.#weakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 10, 61))
|
||||
>this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2))
|
||||
>set : Symbol(WeakMap.set, Decl(lib.es2015.collection.d.ts, --, --))
|
||||
>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 24, 8))
|
||||
>ref : Symbol(ref, Decl(esNextWeakRefs_IterableWeakMap.ts, 31, 36))
|
||||
>value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 31, 41))
|
||||
|
||||
this.#refSet.add(ref);
|
||||
>this.#refSet.add : Symbol(Set.add, Decl(lib.es2015.collection.d.ts, --, --))
|
||||
>this.#refSet : Symbol(IterableWeakMap.#refSet, Decl(esNextWeakRefs_IterableWeakMap.ts, 12, 72))
|
||||
>this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2))
|
||||
>add : Symbol(Set.add, Decl(lib.es2015.collection.d.ts, --, --))
|
||||
>ref : Symbol(ref, Decl(esNextWeakRefs_IterableWeakMap.ts, 29, 17))
|
||||
|
||||
this.#finalizationGroup.register(key, {
|
||||
>this.#finalizationGroup.register : Symbol(FinalizationRegistry.register, Decl(lib.esnext.weakref.d.ts, --, --))
|
||||
>this.#finalizationGroup : Symbol(IterableWeakMap.#finalizationGroup, Decl(esNextWeakRefs_IterableWeakMap.ts, 13, 36))
|
||||
>this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2))
|
||||
>register : Symbol(FinalizationRegistry.register, Decl(lib.esnext.weakref.d.ts, --, --))
|
||||
>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 24, 8))
|
||||
|
||||
set: this.#refSet,
|
||||
>set : Symbol(set, Decl(esNextWeakRefs_IterableWeakMap.ts, 33, 51))
|
||||
>this.#refSet : Symbol(IterableWeakMap.#refSet, Decl(esNextWeakRefs_IterableWeakMap.ts, 12, 72))
|
||||
>this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2))
|
||||
|
||||
ref,
|
||||
>ref : Symbol(ref, Decl(esNextWeakRefs_IterableWeakMap.ts, 34, 34))
|
||||
|
||||
}, ref);
|
||||
>ref : Symbol(ref, Decl(esNextWeakRefs_IterableWeakMap.ts, 29, 17))
|
||||
}
|
||||
return this;
|
||||
>this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2))
|
||||
}
|
||||
|
||||
has(key: K): boolean {
|
||||
>has : Symbol(IterableWeakMap.has, Decl(esNextWeakRefs_IterableWeakMap.ts, 39, 5))
|
||||
>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 41, 8))
|
||||
>K : Symbol(K, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 29))
|
||||
|
||||
return this.#weakMap.has(key);
|
||||
>this.#weakMap.has : Symbol(WeakMap.has, Decl(lib.es2015.collection.d.ts, --, --))
|
||||
>this.#weakMap : Symbol(IterableWeakMap.#weakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 10, 61))
|
||||
>this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2))
|
||||
>has : Symbol(WeakMap.has, Decl(lib.es2015.collection.d.ts, --, --))
|
||||
>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 41, 8))
|
||||
}
|
||||
|
||||
get(key: K): V | undefined {
|
||||
>get : Symbol(IterableWeakMap.get, Decl(esNextWeakRefs_IterableWeakMap.ts, 43, 5))
|
||||
>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 45, 8))
|
||||
>K : Symbol(K, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 29))
|
||||
>V : Symbol(V, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 46))
|
||||
|
||||
return this.#weakMap.get(key)?.value;
|
||||
>this.#weakMap.get(key)?.value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 12, 57))
|
||||
>this.#weakMap.get : Symbol(WeakMap.get, Decl(lib.es2015.collection.d.ts, --, --))
|
||||
>this.#weakMap : Symbol(IterableWeakMap.#weakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 10, 61))
|
||||
>this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2))
|
||||
>get : Symbol(WeakMap.get, Decl(lib.es2015.collection.d.ts, --, --))
|
||||
>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 45, 8))
|
||||
>value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 12, 57))
|
||||
}
|
||||
|
||||
delete(key: K): boolean {
|
||||
>delete : Symbol(IterableWeakMap.delete, Decl(esNextWeakRefs_IterableWeakMap.ts, 47, 5))
|
||||
>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 49, 11))
|
||||
>K : Symbol(K, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 29))
|
||||
|
||||
const entry = this.#weakMap.get(key);
|
||||
>entry : Symbol(entry, Decl(esNextWeakRefs_IterableWeakMap.ts, 50, 13))
|
||||
>this.#weakMap.get : Symbol(WeakMap.get, Decl(lib.es2015.collection.d.ts, --, --))
|
||||
>this.#weakMap : Symbol(IterableWeakMap.#weakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 10, 61))
|
||||
>this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2))
|
||||
>get : Symbol(WeakMap.get, Decl(lib.es2015.collection.d.ts, --, --))
|
||||
>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 49, 11))
|
||||
|
||||
if (entry === undefined) {
|
||||
>entry : Symbol(entry, Decl(esNextWeakRefs_IterableWeakMap.ts, 50, 13))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const { ref } = entry;
|
||||
>ref : Symbol(ref, Decl(esNextWeakRefs_IterableWeakMap.ts, 55, 15))
|
||||
>entry : Symbol(entry, Decl(esNextWeakRefs_IterableWeakMap.ts, 50, 13))
|
||||
|
||||
this.#weakMap.delete(key);
|
||||
>this.#weakMap.delete : Symbol(WeakMap.delete, Decl(lib.es2015.collection.d.ts, --, --))
|
||||
>this.#weakMap : Symbol(IterableWeakMap.#weakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 10, 61))
|
||||
>this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2))
|
||||
>delete : Symbol(WeakMap.delete, Decl(lib.es2015.collection.d.ts, --, --))
|
||||
>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 49, 11))
|
||||
|
||||
this.#refSet.delete(ref);
|
||||
>this.#refSet.delete : Symbol(Set.delete, Decl(lib.es2015.collection.d.ts, --, --))
|
||||
>this.#refSet : Symbol(IterableWeakMap.#refSet, Decl(esNextWeakRefs_IterableWeakMap.ts, 12, 72))
|
||||
>this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2))
|
||||
>delete : Symbol(Set.delete, Decl(lib.es2015.collection.d.ts, --, --))
|
||||
>ref : Symbol(ref, Decl(esNextWeakRefs_IterableWeakMap.ts, 55, 15))
|
||||
|
||||
this.#finalizationGroup.unregister(ref);
|
||||
>this.#finalizationGroup.unregister : Symbol(FinalizationRegistry.unregister, Decl(lib.esnext.weakref.d.ts, --, --))
|
||||
>this.#finalizationGroup : Symbol(IterableWeakMap.#finalizationGroup, Decl(esNextWeakRefs_IterableWeakMap.ts, 13, 36))
|
||||
>this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2))
|
||||
>unregister : Symbol(FinalizationRegistry.unregister, Decl(lib.esnext.weakref.d.ts, --, --))
|
||||
>ref : Symbol(ref, Decl(esNextWeakRefs_IterableWeakMap.ts, 55, 15))
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
declare [Symbol.iterator]: this["entries"];
|
||||
>[Symbol.iterator] : Symbol(IterableWeakMap[Symbol.iterator], Decl(esNextWeakRefs_IterableWeakMap.ts, 60, 5))
|
||||
>Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --))
|
||||
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --))
|
||||
>iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --))
|
||||
|
||||
*entries(): Generator<[key: K, value: V], void> {
|
||||
>entries : Symbol(IterableWeakMap.entries, Decl(esNextWeakRefs_IterableWeakMap.ts, 62, 47))
|
||||
>Generator : Symbol(Generator, Decl(lib.es2015.generator.d.ts, --, --))
|
||||
>K : Symbol(K, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 29))
|
||||
>V : Symbol(V, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 46))
|
||||
|
||||
for (const ref of this.#refSet) {
|
||||
>ref : Symbol(ref, Decl(esNextWeakRefs_IterableWeakMap.ts, 64, 18))
|
||||
>this.#refSet : Symbol(IterableWeakMap.#refSet, Decl(esNextWeakRefs_IterableWeakMap.ts, 12, 72))
|
||||
>this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2))
|
||||
|
||||
const key = ref.deref();
|
||||
>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 65, 17))
|
||||
>ref.deref : Symbol(WeakRef.deref, Decl(lib.esnext.weakref.d.ts, --, --))
|
||||
>ref : Symbol(ref, Decl(esNextWeakRefs_IterableWeakMap.ts, 64, 18))
|
||||
>deref : Symbol(WeakRef.deref, Decl(lib.esnext.weakref.d.ts, --, --))
|
||||
|
||||
if (key === undefined) continue;
|
||||
>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 65, 17))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
const { value } = this.#weakMap.get(key)!;
|
||||
>value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 67, 19))
|
||||
>this.#weakMap.get : Symbol(WeakMap.get, Decl(lib.es2015.collection.d.ts, --, --))
|
||||
>this.#weakMap : Symbol(IterableWeakMap.#weakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 10, 61))
|
||||
>this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2))
|
||||
>get : Symbol(WeakMap.get, Decl(lib.es2015.collection.d.ts, --, --))
|
||||
>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 65, 17))
|
||||
|
||||
yield [key, value];
|
||||
>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 65, 17))
|
||||
>value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 67, 19))
|
||||
}
|
||||
}
|
||||
|
||||
*keys() {
|
||||
>keys : Symbol(IterableWeakMap.keys, Decl(esNextWeakRefs_IterableWeakMap.ts, 70, 5))
|
||||
|
||||
for (const { 0: key } of this) {
|
||||
>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 73, 20))
|
||||
>this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2))
|
||||
|
||||
yield key;
|
||||
>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 73, 20))
|
||||
}
|
||||
}
|
||||
|
||||
*values() {
|
||||
>values : Symbol(IterableWeakMap.values, Decl(esNextWeakRefs_IterableWeakMap.ts, 76, 5))
|
||||
|
||||
for (const { 1: value } of this) {
|
||||
>value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 79, 20))
|
||||
>this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2))
|
||||
|
||||
yield value;
|
||||
>value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 79, 20))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperties(IterableWeakMap.prototype, {
|
||||
>Object.defineProperties : Symbol(ObjectConstructor.defineProperties, Decl(lib.es5.d.ts, --, --))
|
||||
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>defineProperties : Symbol(ObjectConstructor.defineProperties, Decl(lib.es5.d.ts, --, --))
|
||||
>IterableWeakMap.prototype : Symbol(IterableWeakMap.prototype)
|
||||
>IterableWeakMap : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2))
|
||||
>prototype : Symbol(IterableWeakMap.prototype)
|
||||
|
||||
[Symbol.iterator]: {
|
||||
>[Symbol.iterator] : Symbol([Symbol.iterator], Decl(esNextWeakRefs_IterableWeakMap.ts, 85, 52))
|
||||
>Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --))
|
||||
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --))
|
||||
>iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --))
|
||||
|
||||
configurable: true,
|
||||
>configurable : Symbol(configurable, Decl(esNextWeakRefs_IterableWeakMap.ts, 86, 24))
|
||||
|
||||
enumerable: false,
|
||||
>enumerable : Symbol(enumerable, Decl(esNextWeakRefs_IterableWeakMap.ts, 87, 27))
|
||||
|
||||
writable: true,
|
||||
>writable : Symbol(writable, Decl(esNextWeakRefs_IterableWeakMap.ts, 88, 26))
|
||||
|
||||
value: Object.getOwnPropertyDescriptor(
|
||||
>value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 89, 23))
|
||||
>Object.getOwnPropertyDescriptor( IterableWeakMap.prototype, "entries", )!.value : Symbol(PropertyDescriptor.value, Decl(lib.es5.d.ts, --, --))
|
||||
>Object.getOwnPropertyDescriptor : Symbol(ObjectConstructor.getOwnPropertyDescriptor, Decl(lib.es5.d.ts, --, --))
|
||||
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>getOwnPropertyDescriptor : Symbol(ObjectConstructor.getOwnPropertyDescriptor, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
IterableWeakMap.prototype,
|
||||
>IterableWeakMap.prototype : Symbol(IterableWeakMap.prototype)
|
||||
>IterableWeakMap : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2))
|
||||
>prototype : Symbol(IterableWeakMap.prototype)
|
||||
|
||||
"entries",
|
||||
)!.value,
|
||||
>value : Symbol(PropertyDescriptor.value, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
},
|
||||
[Symbol.toStringTag]: {
|
||||
>[Symbol.toStringTag] : Symbol([Symbol.toStringTag], Decl(esNextWeakRefs_IterableWeakMap.ts, 94, 6))
|
||||
>Symbol.toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
|
||||
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --))
|
||||
>toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
|
||||
|
||||
configurable: true,
|
||||
>configurable : Symbol(configurable, Decl(esNextWeakRefs_IterableWeakMap.ts, 95, 27))
|
||||
|
||||
enumerable: false,
|
||||
>enumerable : Symbol(enumerable, Decl(esNextWeakRefs_IterableWeakMap.ts, 96, 27))
|
||||
|
||||
writable: false,
|
||||
>writable : Symbol(writable, Decl(esNextWeakRefs_IterableWeakMap.ts, 97, 26))
|
||||
|
||||
value: "IterableWeakMap",
|
||||
>value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 98, 24))
|
||||
|
||||
},
|
||||
});
|
||||
|
383
tests/baselines/reference/esNextWeakRefs_IterableWeakMap.types
Normal file
383
tests/baselines/reference/esNextWeakRefs_IterableWeakMap.types
Normal file
|
@ -0,0 +1,383 @@
|
|||
=== tests/cases/compiler/esNextWeakRefs_IterableWeakMap.ts ===
|
||||
/** `static #cleanup` */
|
||||
const IterableWeakMap_cleanup = ({ ref, set }: {
|
||||
>IterableWeakMap_cleanup : ({ ref, set }: { readonly ref: WeakRef<object>; readonly set: Set<WeakRef<object>>; }) => void
|
||||
>({ ref, set }: { readonly ref: WeakRef<object>; readonly set: Set<WeakRef<object>>;}) => { set.delete(ref);} : ({ ref, set }: { readonly ref: WeakRef<object>; readonly set: Set<WeakRef<object>>; }) => void
|
||||
>ref : WeakRef<object>
|
||||
>set : Set<WeakRef<object>>
|
||||
|
||||
readonly ref: WeakRef<object>;
|
||||
>ref : WeakRef<object>
|
||||
|
||||
readonly set: Set<WeakRef<object>>;
|
||||
>set : Set<WeakRef<object>>
|
||||
|
||||
}) => {
|
||||
set.delete(ref);
|
||||
>set.delete(ref) : boolean
|
||||
>set.delete : (value: WeakRef<object>) => boolean
|
||||
>set : Set<WeakRef<object>>
|
||||
>delete : (value: WeakRef<object>) => boolean
|
||||
>ref : WeakRef<object>
|
||||
|
||||
};
|
||||
|
||||
// Based on: https://github.com/tc39/proposal-weakrefs/blob/master/README.md#iterable-weakmaps
|
||||
export class IterableWeakMap<K extends object, V> implements WeakMap<K, V> {
|
||||
>IterableWeakMap : IterableWeakMap<K, V>
|
||||
|
||||
declare readonly [Symbol.toStringTag]: "IterableWeakMap";
|
||||
>[Symbol.toStringTag] : "IterableWeakMap"
|
||||
>Symbol.toStringTag : symbol
|
||||
>Symbol : SymbolConstructor
|
||||
>toStringTag : symbol
|
||||
|
||||
#weakMap = new WeakMap<K, { readonly ref: WeakRef<K>; value: V }>();
|
||||
>#weakMap : WeakMap<K, { readonly ref: WeakRef<K>; value: V; }>
|
||||
>new WeakMap<K, { readonly ref: WeakRef<K>; value: V }>() : WeakMap<K, { readonly ref: WeakRef<K>; value: V; }>
|
||||
>WeakMap : WeakMapConstructor
|
||||
>ref : WeakRef<K>
|
||||
>value : V
|
||||
|
||||
#refSet = new Set<WeakRef<K>>();
|
||||
>#refSet : Set<WeakRef<K>>
|
||||
>new Set<WeakRef<K>>() : Set<WeakRef<K>>
|
||||
>Set : SetConstructor
|
||||
|
||||
#finalizationGroup = new FinalizationRegistry(IterableWeakMap_cleanup);
|
||||
>#finalizationGroup : FinalizationRegistry<{ readonly ref: WeakRef<object>; readonly set: Set<WeakRef<object>>; }>
|
||||
>new FinalizationRegistry(IterableWeakMap_cleanup) : FinalizationRegistry<{ readonly ref: WeakRef<object>; readonly set: Set<WeakRef<object>>; }>
|
||||
>FinalizationRegistry : FinalizationRegistryConstructor
|
||||
>IterableWeakMap_cleanup : ({ ref, set }: { readonly ref: WeakRef<object>; readonly set: Set<WeakRef<object>>; }) => void
|
||||
|
||||
constructor(iterable: Iterable<[key: K, value: V]> | null = null) {
|
||||
>iterable : Iterable<[key: K, value: V]> | null
|
||||
>null : null
|
||||
>null : null
|
||||
|
||||
if (iterable !== null) {
|
||||
>iterable !== null : boolean
|
||||
>iterable : Iterable<[key: K, value: V]> | null
|
||||
>null : null
|
||||
|
||||
for (const { 0: key, 1: value } of iterable) {
|
||||
>key : K
|
||||
>value : V
|
||||
>iterable : Iterable<[key: K, value: V]>
|
||||
|
||||
this.set(key, value);
|
||||
>this.set(key, value) : this
|
||||
>this.set : (key: K, value: V) => this
|
||||
>this : this
|
||||
>set : (key: K, value: V) => this
|
||||
>key : K
|
||||
>value : V
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set(key: K, value: V): this {
|
||||
>set : (key: K, value: V) => this
|
||||
>key : K
|
||||
>value : V
|
||||
|
||||
const entry = this.#weakMap.get(key);
|
||||
>entry : { readonly ref: WeakRef<K>; value: V; } | undefined
|
||||
>this.#weakMap.get(key) : { readonly ref: WeakRef<K>; value: V; } | undefined
|
||||
>this.#weakMap.get : (key: K) => { readonly ref: WeakRef<K>; value: V; } | undefined
|
||||
>this.#weakMap : WeakMap<K, { readonly ref: WeakRef<K>; value: V; }>
|
||||
>this : this
|
||||
>get : (key: K) => { readonly ref: WeakRef<K>; value: V; } | undefined
|
||||
>key : K
|
||||
|
||||
if (entry !== undefined) {
|
||||
>entry !== undefined : boolean
|
||||
>entry : { readonly ref: WeakRef<K>; value: V; } | undefined
|
||||
>undefined : undefined
|
||||
|
||||
entry.value = value;
|
||||
>entry.value = value : V
|
||||
>entry.value : V
|
||||
>entry : { readonly ref: WeakRef<K>; value: V; }
|
||||
>value : V
|
||||
>value : V
|
||||
|
||||
} else {
|
||||
const ref = new WeakRef(key);
|
||||
>ref : WeakRef<K>
|
||||
>new WeakRef(key) : WeakRef<K>
|
||||
>WeakRef : WeakRefConstructor
|
||||
>key : K
|
||||
|
||||
this.#weakMap.set(key, { ref, value });
|
||||
>this.#weakMap.set(key, { ref, value }) : WeakMap<K, { readonly ref: WeakRef<K>; value: V; }>
|
||||
>this.#weakMap.set : (key: K, value: { readonly ref: WeakRef<K>; value: V; }) => WeakMap<K, { readonly ref: WeakRef<K>; value: V; }>
|
||||
>this.#weakMap : WeakMap<K, { readonly ref: WeakRef<K>; value: V; }>
|
||||
>this : this
|
||||
>set : (key: K, value: { readonly ref: WeakRef<K>; value: V; }) => WeakMap<K, { readonly ref: WeakRef<K>; value: V; }>
|
||||
>key : K
|
||||
>{ ref, value } : { ref: WeakRef<K>; value: V; }
|
||||
>ref : WeakRef<K>
|
||||
>value : V
|
||||
|
||||
this.#refSet.add(ref);
|
||||
>this.#refSet.add(ref) : Set<WeakRef<K>>
|
||||
>this.#refSet.add : (value: WeakRef<K>) => Set<WeakRef<K>>
|
||||
>this.#refSet : Set<WeakRef<K>>
|
||||
>this : this
|
||||
>add : (value: WeakRef<K>) => Set<WeakRef<K>>
|
||||
>ref : WeakRef<K>
|
||||
|
||||
this.#finalizationGroup.register(key, {
|
||||
>this.#finalizationGroup.register(key, { set: this.#refSet, ref, }, ref) : void
|
||||
>this.#finalizationGroup.register : (target: object, heldValue: { readonly ref: WeakRef<object>; readonly set: Set<WeakRef<object>>; }, unregisterToken?: object | undefined) => void
|
||||
>this.#finalizationGroup : FinalizationRegistry<{ readonly ref: WeakRef<object>; readonly set: Set<WeakRef<object>>; }>
|
||||
>this : this
|
||||
>register : (target: object, heldValue: { readonly ref: WeakRef<object>; readonly set: Set<WeakRef<object>>; }, unregisterToken?: object | undefined) => void
|
||||
>key : K
|
||||
>{ set: this.#refSet, ref, } : { set: Set<WeakRef<K>>; ref: WeakRef<K>; }
|
||||
|
||||
set: this.#refSet,
|
||||
>set : Set<WeakRef<K>>
|
||||
>this.#refSet : Set<WeakRef<K>>
|
||||
>this : this
|
||||
|
||||
ref,
|
||||
>ref : WeakRef<K>
|
||||
|
||||
}, ref);
|
||||
>ref : WeakRef<K>
|
||||
}
|
||||
return this;
|
||||
>this : this
|
||||
}
|
||||
|
||||
has(key: K): boolean {
|
||||
>has : (key: K) => boolean
|
||||
>key : K
|
||||
|
||||
return this.#weakMap.has(key);
|
||||
>this.#weakMap.has(key) : boolean
|
||||
>this.#weakMap.has : (key: K) => boolean
|
||||
>this.#weakMap : WeakMap<K, { readonly ref: WeakRef<K>; value: V; }>
|
||||
>this : this
|
||||
>has : (key: K) => boolean
|
||||
>key : K
|
||||
}
|
||||
|
||||
get(key: K): V | undefined {
|
||||
>get : (key: K) => V | undefined
|
||||
>key : K
|
||||
|
||||
return this.#weakMap.get(key)?.value;
|
||||
>this.#weakMap.get(key)?.value : V | undefined
|
||||
>this.#weakMap.get(key) : { readonly ref: WeakRef<K>; value: V; } | undefined
|
||||
>this.#weakMap.get : (key: K) => { readonly ref: WeakRef<K>; value: V; } | undefined
|
||||
>this.#weakMap : WeakMap<K, { readonly ref: WeakRef<K>; value: V; }>
|
||||
>this : this
|
||||
>get : (key: K) => { readonly ref: WeakRef<K>; value: V; } | undefined
|
||||
>key : K
|
||||
>value : V | undefined
|
||||
}
|
||||
|
||||
delete(key: K): boolean {
|
||||
>delete : (key: K) => boolean
|
||||
>key : K
|
||||
|
||||
const entry = this.#weakMap.get(key);
|
||||
>entry : { readonly ref: WeakRef<K>; value: V; } | undefined
|
||||
>this.#weakMap.get(key) : { readonly ref: WeakRef<K>; value: V; } | undefined
|
||||
>this.#weakMap.get : (key: K) => { readonly ref: WeakRef<K>; value: V; } | undefined
|
||||
>this.#weakMap : WeakMap<K, { readonly ref: WeakRef<K>; value: V; }>
|
||||
>this : this
|
||||
>get : (key: K) => { readonly ref: WeakRef<K>; value: V; } | undefined
|
||||
>key : K
|
||||
|
||||
if (entry === undefined) {
|
||||
>entry === undefined : boolean
|
||||
>entry : { readonly ref: WeakRef<K>; value: V; } | undefined
|
||||
>undefined : undefined
|
||||
|
||||
return false;
|
||||
>false : false
|
||||
}
|
||||
|
||||
const { ref } = entry;
|
||||
>ref : WeakRef<K>
|
||||
>entry : { readonly ref: WeakRef<K>; value: V; }
|
||||
|
||||
this.#weakMap.delete(key);
|
||||
>this.#weakMap.delete(key) : boolean
|
||||
>this.#weakMap.delete : (key: K) => boolean
|
||||
>this.#weakMap : WeakMap<K, { readonly ref: WeakRef<K>; value: V; }>
|
||||
>this : this
|
||||
>delete : (key: K) => boolean
|
||||
>key : K
|
||||
|
||||
this.#refSet.delete(ref);
|
||||
>this.#refSet.delete(ref) : boolean
|
||||
>this.#refSet.delete : (value: WeakRef<K>) => boolean
|
||||
>this.#refSet : Set<WeakRef<K>>
|
||||
>this : this
|
||||
>delete : (value: WeakRef<K>) => boolean
|
||||
>ref : WeakRef<K>
|
||||
|
||||
this.#finalizationGroup.unregister(ref);
|
||||
>this.#finalizationGroup.unregister(ref) : void
|
||||
>this.#finalizationGroup.unregister : (unregisterToken: object) => void
|
||||
>this.#finalizationGroup : FinalizationRegistry<{ readonly ref: WeakRef<object>; readonly set: Set<WeakRef<object>>; }>
|
||||
>this : this
|
||||
>unregister : (unregisterToken: object) => void
|
||||
>ref : WeakRef<K>
|
||||
|
||||
return true;
|
||||
>true : true
|
||||
}
|
||||
|
||||
declare [Symbol.iterator]: this["entries"];
|
||||
>[Symbol.iterator] : this["entries"]
|
||||
>Symbol.iterator : symbol
|
||||
>Symbol : SymbolConstructor
|
||||
>iterator : symbol
|
||||
|
||||
*entries(): Generator<[key: K, value: V], void> {
|
||||
>entries : () => Generator<[key: K, value: V], void>
|
||||
|
||||
for (const ref of this.#refSet) {
|
||||
>ref : WeakRef<K>
|
||||
>this.#refSet : Set<WeakRef<K>>
|
||||
>this : this
|
||||
|
||||
const key = ref.deref();
|
||||
>key : K | undefined
|
||||
>ref.deref() : K | undefined
|
||||
>ref.deref : () => K | undefined
|
||||
>ref : WeakRef<K>
|
||||
>deref : () => K | undefined
|
||||
|
||||
if (key === undefined) continue;
|
||||
>key === undefined : boolean
|
||||
>key : K | undefined
|
||||
>undefined : undefined
|
||||
|
||||
const { value } = this.#weakMap.get(key)!;
|
||||
>value : V
|
||||
>this.#weakMap.get(key)! : { readonly ref: WeakRef<K>; value: V; }
|
||||
>this.#weakMap.get(key) : { readonly ref: WeakRef<K>; value: V; } | undefined
|
||||
>this.#weakMap.get : (key: K) => { readonly ref: WeakRef<K>; value: V; } | undefined
|
||||
>this.#weakMap : WeakMap<K, { readonly ref: WeakRef<K>; value: V; }>
|
||||
>this : this
|
||||
>get : (key: K) => { readonly ref: WeakRef<K>; value: V; } | undefined
|
||||
>key : K
|
||||
|
||||
yield [key, value];
|
||||
>yield [key, value] : unknown
|
||||
>[key, value] : [K, V]
|
||||
>key : K
|
||||
>value : V
|
||||
}
|
||||
}
|
||||
|
||||
*keys() {
|
||||
>keys : () => Generator<K, void, unknown>
|
||||
|
||||
for (const { 0: key } of this) {
|
||||
>key : K
|
||||
>this : this
|
||||
|
||||
yield key;
|
||||
>yield key : any
|
||||
>key : K
|
||||
}
|
||||
}
|
||||
|
||||
*values() {
|
||||
>values : () => Generator<V, void, unknown>
|
||||
|
||||
for (const { 1: value } of this) {
|
||||
>value : V
|
||||
>this : this
|
||||
|
||||
yield value;
|
||||
>yield value : any
|
||||
>value : V
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperties(IterableWeakMap.prototype, {
|
||||
>Object.defineProperties(IterableWeakMap.prototype, { [Symbol.iterator]: { configurable: true, enumerable: false, writable: true, value: Object.getOwnPropertyDescriptor( IterableWeakMap.prototype, "entries", )!.value, }, [Symbol.toStringTag]: { configurable: true, enumerable: false, writable: false, value: "IterableWeakMap", },}) : any
|
||||
>Object.defineProperties : (o: any, properties: PropertyDescriptorMap & ThisType<any>) => any
|
||||
>Object : ObjectConstructor
|
||||
>defineProperties : (o: any, properties: PropertyDescriptorMap & ThisType<any>) => any
|
||||
>IterableWeakMap.prototype : IterableWeakMap<any, any>
|
||||
>IterableWeakMap : typeof IterableWeakMap
|
||||
>prototype : IterableWeakMap<any, any>
|
||||
>{ [Symbol.iterator]: { configurable: true, enumerable: false, writable: true, value: Object.getOwnPropertyDescriptor( IterableWeakMap.prototype, "entries", )!.value, }, [Symbol.toStringTag]: { configurable: true, enumerable: false, writable: false, value: "IterableWeakMap", },} : { [Symbol.iterator]: { configurable: true; enumerable: false; writable: true; value: any; }; [Symbol.toStringTag]: { configurable: true; enumerable: false; writable: false; value: string; }; }
|
||||
|
||||
[Symbol.iterator]: {
|
||||
>[Symbol.iterator] : { configurable: true; enumerable: false; writable: true; value: any; }
|
||||
>Symbol.iterator : symbol
|
||||
>Symbol : SymbolConstructor
|
||||
>iterator : symbol
|
||||
>{ configurable: true, enumerable: false, writable: true, value: Object.getOwnPropertyDescriptor( IterableWeakMap.prototype, "entries", )!.value, } : { configurable: true; enumerable: false; writable: true; value: any; }
|
||||
|
||||
configurable: true,
|
||||
>configurable : true
|
||||
>true : true
|
||||
|
||||
enumerable: false,
|
||||
>enumerable : false
|
||||
>false : false
|
||||
|
||||
writable: true,
|
||||
>writable : true
|
||||
>true : true
|
||||
|
||||
value: Object.getOwnPropertyDescriptor(
|
||||
>value : any
|
||||
>Object.getOwnPropertyDescriptor( IterableWeakMap.prototype, "entries", )!.value : any
|
||||
>Object.getOwnPropertyDescriptor( IterableWeakMap.prototype, "entries", )! : PropertyDescriptor
|
||||
>Object.getOwnPropertyDescriptor( IterableWeakMap.prototype, "entries", ) : PropertyDescriptor | undefined
|
||||
>Object.getOwnPropertyDescriptor : (o: any, p: PropertyKey) => PropertyDescriptor | undefined
|
||||
>Object : ObjectConstructor
|
||||
>getOwnPropertyDescriptor : (o: any, p: PropertyKey) => PropertyDescriptor | undefined
|
||||
|
||||
IterableWeakMap.prototype,
|
||||
>IterableWeakMap.prototype : IterableWeakMap<any, any>
|
||||
>IterableWeakMap : typeof IterableWeakMap
|
||||
>prototype : IterableWeakMap<any, any>
|
||||
|
||||
"entries",
|
||||
>"entries" : "entries"
|
||||
|
||||
)!.value,
|
||||
>value : any
|
||||
|
||||
},
|
||||
[Symbol.toStringTag]: {
|
||||
>[Symbol.toStringTag] : { configurable: true; enumerable: false; writable: false; value: string; }
|
||||
>Symbol.toStringTag : symbol
|
||||
>Symbol : SymbolConstructor
|
||||
>toStringTag : symbol
|
||||
>{ configurable: true, enumerable: false, writable: false, value: "IterableWeakMap", } : { configurable: true; enumerable: false; writable: false; value: string; }
|
||||
|
||||
configurable: true,
|
||||
>configurable : true
|
||||
>true : true
|
||||
|
||||
enumerable: false,
|
||||
>enumerable : false
|
||||
>false : false
|
||||
|
||||
writable: false,
|
||||
>writable : false
|
||||
>false : false
|
||||
|
||||
value: "IterableWeakMap",
|
||||
>value : string
|
||||
>"IterableWeakMap" : "IterableWeakMap"
|
||||
|
||||
},
|
||||
});
|
||||
|
107
tests/cases/compiler/esNextWeakRefs_IterableWeakMap.ts
Normal file
107
tests/cases/compiler/esNextWeakRefs_IterableWeakMap.ts
Normal file
|
@ -0,0 +1,107 @@
|
|||
// @lib: ESNext
|
||||
// @target: ESNext
|
||||
// @useDefineForClassFields: true
|
||||
// @strictNullChecks: true
|
||||
|
||||
/** `static #cleanup` */
|
||||
const IterableWeakMap_cleanup = ({ ref, set }: {
|
||||
readonly ref: WeakRef<object>;
|
||||
readonly set: Set<WeakRef<object>>;
|
||||
}) => {
|
||||
set.delete(ref);
|
||||
};
|
||||
|
||||
// Based on: https://github.com/tc39/proposal-weakrefs/blob/master/README.md#iterable-weakmaps
|
||||
export class IterableWeakMap<K extends object, V> implements WeakMap<K, V> {
|
||||
declare readonly [Symbol.toStringTag]: "IterableWeakMap";
|
||||
|
||||
#weakMap = new WeakMap<K, { readonly ref: WeakRef<K>; value: V }>();
|
||||
#refSet = new Set<WeakRef<K>>();
|
||||
#finalizationGroup = new FinalizationRegistry(IterableWeakMap_cleanup);
|
||||
|
||||
constructor(iterable: Iterable<[key: K, value: V]> | null = null) {
|
||||
if (iterable !== null) {
|
||||
for (const { 0: key, 1: value } of iterable) {
|
||||
this.set(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set(key: K, value: V): this {
|
||||
const entry = this.#weakMap.get(key);
|
||||
if (entry !== undefined) {
|
||||
entry.value = value;
|
||||
} else {
|
||||
const ref = new WeakRef(key);
|
||||
|
||||
this.#weakMap.set(key, { ref, value });
|
||||
this.#refSet.add(ref);
|
||||
this.#finalizationGroup.register(key, {
|
||||
set: this.#refSet,
|
||||
ref,
|
||||
}, ref);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
has(key: K): boolean {
|
||||
return this.#weakMap.has(key);
|
||||
}
|
||||
|
||||
get(key: K): V | undefined {
|
||||
return this.#weakMap.get(key)?.value;
|
||||
}
|
||||
|
||||
delete(key: K): boolean {
|
||||
const entry = this.#weakMap.get(key);
|
||||
if (entry === undefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const { ref } = entry;
|
||||
this.#weakMap.delete(key);
|
||||
this.#refSet.delete(ref);
|
||||
this.#finalizationGroup.unregister(ref);
|
||||
return true;
|
||||
}
|
||||
|
||||
declare [Symbol.iterator]: this["entries"];
|
||||
*entries(): Generator<[key: K, value: V], void> {
|
||||
for (const ref of this.#refSet) {
|
||||
const key = ref.deref();
|
||||
if (key === undefined) continue;
|
||||
const { value } = this.#weakMap.get(key)!;
|
||||
yield [key, value];
|
||||
}
|
||||
}
|
||||
|
||||
*keys() {
|
||||
for (const { 0: key } of this) {
|
||||
yield key;
|
||||
}
|
||||
}
|
||||
|
||||
*values() {
|
||||
for (const { 1: value } of this) {
|
||||
yield value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperties(IterableWeakMap.prototype, {
|
||||
[Symbol.iterator]: {
|
||||
configurable: true,
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
value: Object.getOwnPropertyDescriptor(
|
||||
IterableWeakMap.prototype,
|
||||
"entries",
|
||||
)!.value,
|
||||
},
|
||||
[Symbol.toStringTag]: {
|
||||
configurable: true,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: "IterableWeakMap",
|
||||
},
|
||||
});
|
Loading…
Reference in a new issue