import { Map } from "./map"; // @ts-ignore: decorator @lazy var stringToId: Map; // @ts-ignore: decorator @lazy var idToString: Map; // @ts-ignore: decorator @lazy var nextId: usize = 12; // Symbol.unscopables + 1 @unmanaged @sealed abstract class _Symbol { // TODO: all of the following default symbols are unused currently yet add to // binary size if #toString becomes compiled. Ultimately we'll most likely want // to remove the unsupported ones and only keep what's actually supported. // @ts-ignore: decorator @lazy static readonly hasInstance: symbol = changetype(1); // @ts-ignore: decorator @lazy static readonly isConcatSpreadable: symbol = changetype(2); // @ts-ignore: decorator @lazy static readonly isRegExp: symbol = changetype(3); // @ts-ignore: decorator @lazy static readonly iterator: symbol = changetype(3); // @ts-ignore: decorator @lazy static readonly match: symbol = changetype(4); // @ts-ignore: decorator @lazy static readonly replace: symbol = changetype(5); // @ts-ignore: decorator @lazy static readonly search: symbol = changetype(6); // @ts-ignore: decorator @lazy static readonly species: symbol = changetype(7); // @ts-ignore: decorator @lazy static readonly split: symbol = changetype(8); // @ts-ignore: decorator @lazy static readonly toPrimitive: symbol = changetype(9); // @ts-ignore: decorator @lazy static readonly toStringTag: symbol = changetype(10); // @ts-ignore: decorator @lazy static readonly unscopables: symbol = changetype(11); static for(key: string): symbol { if (!stringToId) { stringToId = new Map(); idToString = new Map(); } else if (stringToId.has(key)) return changetype(stringToId.get(key)); var id = nextId++; if (!id) unreachable(); // out of ids stringToId.set(key, id); idToString.set(id, key); return changetype(id); } static keyFor(sym: symbol): string | null { return idToString !== null && idToString.has(changetype(sym)) ? idToString.get(changetype(sym)) : null; } toString(): string { var id = changetype(this); var str = ""; switch (id) { case 1: { str = "hasInstance"; break; } case 2: { str = "isConcatSpreadable"; break; } case 3: { str = "isRegExp"; break; } case 4: { str = "match"; break; } case 5: { str = "replace"; break; } case 6: { str = "search"; break; } case 7: { str = "species"; break; } case 8: { str = "split"; break; } case 9: { str = "toPrimitive"; break; } case 10: { str = "toStringTag"; break; } case 11: { str = "unscopables"; break; } default: { if (idToString !== null && idToString.has(id)) str = idToString.get(id); break; } } return "Symbol(" + str + ")"; } } export function Symbol(description: string | null = null): symbol { var id = nextId++; if (!id) unreachable(); // out of ids return changetype(id); } export type Symbol = _Symbol; // @ts-ignore: nolib export type symbol = _Symbol;