Skip to content

le/symbols as weak map keys #76

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
3bac33d
Update 2021 weakref types
leoelm Feb 9, 2023
5871e83
Add symbol to WeakRef and FinalizationRegistry
leoelm Feb 9, 2023
c0161d9
Update WeakSet keys
leoelm Mar 5, 2023
0596a4c
Add WeakMap symbol support
leoelm Mar 5, 2023
776c6a7
Resolve compilation and testing issues
leoelm Mar 14, 2023
4b02a2c
Add some test changes
leoelm Mar 16, 2023
0e809bf
Add testing for WeakRef and FinalizationRegistry
leoelm Mar 22, 2023
2241306
Undo lib changes
leoelm Mar 23, 2023
18ec290
Undo lib changes
leoelm Mar 23, 2023
0198657
Address PR comments
leoelm Mar 29, 2023
a103a0b
Update 2021 weakref types
leoelm Feb 9, 2023
e898ad0
Add symbol to WeakRef and FinalizationRegistry
leoelm Feb 9, 2023
8b90d0a
Update WeakSet keys
leoelm Mar 5, 2023
485aea5
Add WeakMap symbol support
leoelm Mar 5, 2023
6350617
Resolve compilation and testing issues
leoelm Mar 14, 2023
b1a8c37
Add some test changes
leoelm Mar 16, 2023
8413425
Add testing for WeakRef and FinalizationRegistry
leoelm Mar 22, 2023
f8470f1
Undo lib changes
leoelm Mar 23, 2023
ff83b5c
Undo lib changes
leoelm Mar 23, 2023
c3275ca
Address PR comments
leoelm Mar 29, 2023
0809ac2
Merge branch 'le/symbols-as-weak-map-keys' of github.com:leoelm/TypeS…
leoelm Mar 29, 2023
8c2fd56
Address PR comments
leoelm Apr 3, 2023
2eb0354
Add baselines
leoelm Apr 3, 2023
7563f5e
Address PR comments
leoelm Apr 5, 2023
71b47cb
Address PR comments
leoelm Apr 6, 2023
c966981
Merge branch 'le/symbol-as-weak-keys' into le/symbols-as-weak-map-keys
leoelm Apr 8, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/compiler/commandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,9 @@ const libEntries: [string, string][] = [
["es2022.string", "lib.es2022.string.d.ts"],
["es2022.regexp", "lib.es2022.regexp.d.ts"],
["es2023.array", "lib.es2023.array.d.ts"],
["es2023.collection", "lib.es2023.collection.d.ts"],
["esnext.array", "lib.es2023.array.d.ts"],
["esnext.collection", "lib.es2023.collection.d.ts"],
["esnext.symbol", "lib.es2019.symbol.d.ts"],
["esnext.asynciterable", "lib.es2018.asynciterable.d.ts"],
["esnext.intl", "lib.esnext.intl.d.ts"],
Expand Down
18 changes: 9 additions & 9 deletions src/lib/es2015.collection.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ interface ReadonlyMap<K, V> {
readonly size: number;
}

interface WeakMap<K extends object, V> {
interface WeakMap<K extends WeakKey, V> {
/**
* Removes the specified element from the WeakMap.
* @returns true if the element was successfully removed, or false if it was not present.
Expand All @@ -58,14 +58,14 @@ interface WeakMap<K extends object, V> {
has(key: K): boolean;
/**
* Adds a new element with a specified key and value.
* @param key Must be an object.
* @param key Must be an object or symbol.
*/
set(key: K, value: V): this;
}

interface WeakMapConstructor {
new <K extends object = object, V = any>(entries?: readonly (readonly [K, V])[] | null): WeakMap<K, V>;
readonly prototype: WeakMap<object, any>;
new <K extends WeakKey = WeakKey, V = any>(entries?: readonly [K, V][] | null): WeakMap<K, V>;
readonly prototype: WeakMap<WeakKey, any>;
}
declare var WeakMap: WeakMapConstructor;

Expand Down Expand Up @@ -107,9 +107,9 @@ interface ReadonlySet<T> {
readonly size: number;
}

interface WeakSet<T extends object> {
interface WeakSet<T extends WeakKey> {
/**
* Appends a new object to the end of the WeakSet.
* Appends a new value to the end of the WeakSet.
*/
add(value: T): this;
/**
Expand All @@ -118,13 +118,13 @@ interface WeakSet<T extends object> {
*/
delete(value: T): boolean;
/**
* @returns a boolean indicating whether an object exists in the WeakSet or not.
* @returns a boolean indicating whether a value exists in the WeakSet or not.
*/
has(value: T): boolean;
}

interface WeakSetConstructor {
new <T extends object = object>(values?: readonly T[] | null): WeakSet<T>;
readonly prototype: WeakSet<object>;
new <T extends WeakKey = WeakKey>(values?: readonly T[] | null): WeakSet<T>;
readonly prototype: WeakSet<WeakKey>;
}
declare var WeakSet: WeakSetConstructor;
8 changes: 4 additions & 4 deletions src/lib/es2015.iterable.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,10 @@ interface MapConstructor {
new <K, V>(iterable?: Iterable<readonly [K, V]> | null): Map<K, V>;
}

interface WeakMap<K extends object, V> { }
interface WeakMap<K extends WeakKey, V> { }

interface WeakMapConstructor {
new <K extends object, V>(iterable: Iterable<readonly [K, V]>): WeakMap<K, V>;
new <K extends WeakKey, V>(iterable: Iterable<readonly [K, V]>): WeakMap<K, V>;
}

interface Set<T> {
Expand Down Expand Up @@ -189,10 +189,10 @@ interface SetConstructor {
new <T>(iterable?: Iterable<T> | null): Set<T>;
}

interface WeakSet<T extends object> { }
interface WeakSet<T extends WeakKey> { }

interface WeakSetConstructor {
new <T extends object = object>(iterable: Iterable<T>): WeakSet<T>;
new <T extends WeakKey = WeakKey>(iterable: Iterable<T>): WeakSet<T>;
}

interface Promise<T> { }
Expand Down
4 changes: 2 additions & 2 deletions src/lib/es2015.symbol.wellknown.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,15 @@ interface Map<K, V> {
readonly [Symbol.toStringTag]: string;
}

interface WeakMap<K extends object, V> {
interface WeakMap<K extends WeakKey, V> {
readonly [Symbol.toStringTag]: string;
}

interface Set<T> {
readonly [Symbol.toStringTag]: string;
}

interface WeakSet<T extends object> {
interface WeakSet<T extends WeakKey> {
readonly [Symbol.toStringTag]: string;
}

Expand Down
35 changes: 19 additions & 16 deletions src/lib/es2021.weakref.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
interface WeakRef<T extends object> {
interface WeakRef<T extends WeakKey> {
readonly [Symbol.toStringTag]: "WeakRef";

/**
* Returns the WeakRef instance's target object, or undefined if the target object has been
* Returns the WeakRef instance's target value, or undefined if the target value has been
* reclaimed.
* In es2023 the value can be either a symbol or an object, in previous versions only object is permissible.
*/
deref(): T | undefined;
}
Expand All @@ -12,10 +13,11 @@ interface WeakRefConstructor {
readonly prototype: WeakRef<any>;

/**
* Creates a WeakRef instance for the given target object.
* @param target The target object for the WeakRef instance.
* Creates a WeakRef instance for the given target value.
* In es2023 the value can be either a symbol or an object, in previous versions only object is permissible.
* @param target The target value for the WeakRef instance.
*/
new<T extends object>(target: T): WeakRef<T>;
new<T extends WeakKey>(target: T): WeakRef<T>;
}

declare var WeakRef: WeakRefConstructor;
Expand All @@ -24,30 +26,31 @@ interface FinalizationRegistry<T> {
readonly [Symbol.toStringTag]: "FinalizationRegistry";

/**
* Registers an object with the registry.
* @param target The target object to register.
* @param heldValue The value to pass to the finalizer for this object. This cannot be the
* target object.
* Registers a value with the registry.
* In es2023 the value can be either a symbol or an object, in previous versions only object is permissible.
* @param target The target value to register.
* @param heldValue The value to pass to the finalizer for this value. This cannot be the
* target value.
* @param unregisterToken The token to pass to the unregister method to unregister the target
* object. If provided (and not undefined), this must be an object. If not provided, the target
* cannot be unregistered.
* value. If not provided, the target cannot be unregistered.
*/
register(target: object, heldValue: T, unregisterToken?: object): void;
register(target: WeakKey, heldValue: T, unregisterToken?: WeakKey): void;

/**
* Unregisters an object from the registry.
* Unregisters a value from the registry.
* In es2023 the value can be either a symbol or an object, in previous versions only object is permissible.
* @param unregisterToken The token that was used as the unregisterToken argument when calling
* register to register the target object.
* register to register the target value.
*/
unregister(unregisterToken: object): void;
unregister(unregisterToken: WeakKey): void;
}

interface FinalizationRegistryConstructor {
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.
* @param cleanupCallback The callback to call after a value in the registry has been reclaimed.
*/
new<T>(cleanupCallback: (heldValue: T) => void): FinalizationRegistry<T>;
}
Expand Down
3 changes: 3 additions & 0 deletions src/lib/es2023.collection.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
interface WeakKeyTypes {
symbol: symbol;
}
1 change: 1 addition & 0 deletions src/lib/es2023.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/// <reference lib="es2022" />
/// <reference lib="es2023.array" />
/// <reference lib="es2023.collection" />
9 changes: 9 additions & 0 deletions src/lib/es5.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1634,6 +1634,15 @@ type Uncapitalize<S extends string> = intrinsic;
*/
interface ThisType<T> { }

/**
* Stores types to be used with WeakSet, WeakMap, WeakRef, and FinalizationRegistry
*/
interface WeakKeyTypes {
object: object;
}

type WeakKey = WeakKeyTypes[keyof WeakKeyTypes];

/**
* Represents a raw buffer of binary data, which is used to store data for the
* different typed arrays. ArrayBuffers cannot be read from or written to directly,
Expand Down
1 change: 1 addition & 0 deletions src/lib/libs.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"es2022.string",
"es2022.regexp",
"es2023.array",
"es2023.collection",
"esnext.intl",
"decorators",
"decorators.legacy",
Expand Down
38 changes: 38 additions & 0 deletions tests/baselines/reference/acceptSymbolAsWeakType.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//// [acceptSymbolAsWeakType.ts]
const s: symbol = Symbol('s');

const ws = new WeakSet([s]);
ws.add(s);
ws.has(s);
ws.delete(s);

const wm = new WeakMap([[s, false]]);
wm.set(s, true);
wm.has(s);
wm.get(s);
wm.delete(s);

const wr = new WeakRef(s);
wr.deref();

const f = new FinalizationRegistry(() => {});
f.register(s, null);
f.unregister(s);

//// [acceptSymbolAsWeakType.js]
"use strict";
const s = Symbol('s');
const ws = new WeakSet([s]);
ws.add(s);
ws.has(s);
ws.delete(s);
const wm = new WeakMap([[s, false]]);
wm.set(s, true);
wm.has(s);
wm.get(s);
wm.delete(s);
const wr = new WeakRef(s);
wr.deref();
const f = new FinalizationRegistry(() => { });
f.register(s, null);
f.unregister(s);
83 changes: 83 additions & 0 deletions tests/baselines/reference/acceptSymbolAsWeakType.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
=== tests/cases/compiler/acceptSymbolAsWeakType.ts ===
const s: symbol = Symbol('s');
>s : Symbol(s, Decl(acceptSymbolAsWeakType.ts, 0, 5))
>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, --, --))

const ws = new WeakSet([s]);
>ws : Symbol(ws, Decl(acceptSymbolAsWeakType.ts, 2, 5))
>WeakSet : Symbol(WeakSet, 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, --, --))
>s : Symbol(s, Decl(acceptSymbolAsWeakType.ts, 0, 5))

ws.add(s);
>ws.add : Symbol(WeakSet.add, Decl(lib.es2015.collection.d.ts, --, --))
>ws : Symbol(ws, Decl(acceptSymbolAsWeakType.ts, 2, 5))
>add : Symbol(WeakSet.add, Decl(lib.es2015.collection.d.ts, --, --))
>s : Symbol(s, Decl(acceptSymbolAsWeakType.ts, 0, 5))

ws.has(s);
>ws.has : Symbol(WeakSet.has, Decl(lib.es2015.collection.d.ts, --, --))
>ws : Symbol(ws, Decl(acceptSymbolAsWeakType.ts, 2, 5))
>has : Symbol(WeakSet.has, Decl(lib.es2015.collection.d.ts, --, --))
>s : Symbol(s, Decl(acceptSymbolAsWeakType.ts, 0, 5))

ws.delete(s);
>ws.delete : Symbol(WeakSet.delete, Decl(lib.es2015.collection.d.ts, --, --))
>ws : Symbol(ws, Decl(acceptSymbolAsWeakType.ts, 2, 5))
>delete : Symbol(WeakSet.delete, Decl(lib.es2015.collection.d.ts, --, --))
>s : Symbol(s, Decl(acceptSymbolAsWeakType.ts, 0, 5))

const wm = new WeakMap([[s, false]]);
>wm : Symbol(wm, Decl(acceptSymbolAsWeakType.ts, 7, 5))
>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, --, --))
>s : Symbol(s, Decl(acceptSymbolAsWeakType.ts, 0, 5))

wm.set(s, true);
>wm.set : Symbol(WeakMap.set, Decl(lib.es2015.collection.d.ts, --, --))
>wm : Symbol(wm, Decl(acceptSymbolAsWeakType.ts, 7, 5))
>set : Symbol(WeakMap.set, Decl(lib.es2015.collection.d.ts, --, --))
>s : Symbol(s, Decl(acceptSymbolAsWeakType.ts, 0, 5))

wm.has(s);
>wm.has : Symbol(WeakMap.has, Decl(lib.es2015.collection.d.ts, --, --))
>wm : Symbol(wm, Decl(acceptSymbolAsWeakType.ts, 7, 5))
>has : Symbol(WeakMap.has, Decl(lib.es2015.collection.d.ts, --, --))
>s : Symbol(s, Decl(acceptSymbolAsWeakType.ts, 0, 5))

wm.get(s);
>wm.get : Symbol(WeakMap.get, Decl(lib.es2015.collection.d.ts, --, --))
>wm : Symbol(wm, Decl(acceptSymbolAsWeakType.ts, 7, 5))
>get : Symbol(WeakMap.get, Decl(lib.es2015.collection.d.ts, --, --))
>s : Symbol(s, Decl(acceptSymbolAsWeakType.ts, 0, 5))

wm.delete(s);
>wm.delete : Symbol(WeakMap.delete, Decl(lib.es2015.collection.d.ts, --, --))
>wm : Symbol(wm, Decl(acceptSymbolAsWeakType.ts, 7, 5))
>delete : Symbol(WeakMap.delete, Decl(lib.es2015.collection.d.ts, --, --))
>s : Symbol(s, Decl(acceptSymbolAsWeakType.ts, 0, 5))

const wr = new WeakRef(s);
>wr : Symbol(wr, Decl(acceptSymbolAsWeakType.ts, 13, 5))
>WeakRef : Symbol(WeakRef, Decl(lib.es2021.weakref.d.ts, --, --), Decl(lib.es2021.weakref.d.ts, --, --))
>s : Symbol(s, Decl(acceptSymbolAsWeakType.ts, 0, 5))

wr.deref();
>wr.deref : Symbol(WeakRef.deref, Decl(lib.es2021.weakref.d.ts, --, --))
>wr : Symbol(wr, Decl(acceptSymbolAsWeakType.ts, 13, 5))
>deref : Symbol(WeakRef.deref, Decl(lib.es2021.weakref.d.ts, --, --))

const f = new FinalizationRegistry(() => {});
>f : Symbol(f, Decl(acceptSymbolAsWeakType.ts, 16, 5))
>FinalizationRegistry : Symbol(FinalizationRegistry, Decl(lib.es2021.weakref.d.ts, --, --), Decl(lib.es2021.weakref.d.ts, --, --))

f.register(s, null);
>f.register : Symbol(FinalizationRegistry.register, Decl(lib.es2021.weakref.d.ts, --, --))
>f : Symbol(f, Decl(acceptSymbolAsWeakType.ts, 16, 5))
>register : Symbol(FinalizationRegistry.register, Decl(lib.es2021.weakref.d.ts, --, --))
>s : Symbol(s, Decl(acceptSymbolAsWeakType.ts, 0, 5))

f.unregister(s);
>f.unregister : Symbol(FinalizationRegistry.unregister, Decl(lib.es2021.weakref.d.ts, --, --))
>f : Symbol(f, Decl(acceptSymbolAsWeakType.ts, 16, 5))
>unregister : Symbol(FinalizationRegistry.unregister, Decl(lib.es2021.weakref.d.ts, --, --))
>s : Symbol(s, Decl(acceptSymbolAsWeakType.ts, 0, 5))

Loading