162 lines
4.0 KiB
TypeScript

import { todo } from "./util.ts";
//
export type File = IdBase & { readonly _: unique symbol };
export type IdentId = IdBase & { readonly _: unique symbol };
export type AstId = IdBase & { readonly _: unique symbol };
export type DefId = IdBase & { readonly _: unique symbol };
//
export type IdBase = { rawId: number };
export type IdRaw<IdType extends IdBase> = IdType["rawId"];
export const idRaw = <IdType extends IdBase>(id: IdType): IdRaw<IdType> =>
id.rawId;
export const idFromRaw = <IdType extends IdBase>(
rawId: IdRaw<IdType>,
): IdType => ({ rawId } as IdType);
export class Ids<IdType extends IdBase> {
private next = 0;
public nextThenStep(): IdType {
const rawId = this.next;
this.next += 1;
return idFromRaw(rawId);
}
}
export class IdSet<Id extends IdBase> implements Set<Id> {
private set = new Set<IdRaw<Id>>();
add(value: Id): this {
this.set.add(idRaw(value));
return this;
}
clear(): void {
this.set.clear();
}
delete(value: Id): boolean {
return this.set.delete(idRaw(value));
}
forEach(
callbackfn: (value: Id, value2: Id, set: Set<Id>) => void,
thisArg?: unknown,
): void {
this.set.forEach(
(v1, v2) => callbackfn(idFromRaw(v1), idFromRaw(v2), this),
thisArg,
);
}
has(value: Id): boolean {
return this.set.has(idRaw(value));
}
get size(): number {
return this.set.size;
}
entries(): SetIterator<[Id, Id]> {
return this.set.entries()
.map(([v1, v2]) => [idFromRaw(v1), idFromRaw(v2)]);
}
keys(): SetIterator<Id> {
return this.set.keys()
.map((v) => idFromRaw(v));
}
values(): SetIterator<Id> {
return this.set.values()
.map((v) => idFromRaw(v));
}
union<U>(_other: ReadonlySetLike<U>): Set<Id | U> {
return todo();
}
intersection<U>(_other: ReadonlySetLike<U>): Set<Id & U> {
return todo();
}
difference<U>(_other: ReadonlySetLike<U>): Set<Id> {
return todo();
}
symmetricDifference<U>(_other: ReadonlySetLike<U>): Set<Id | U> {
return todo();
}
isSubsetOf(_other: ReadonlySetLike<unknown>): boolean {
return todo();
}
isSupersetOf(_other: ReadonlySetLike<unknown>): boolean {
return todo();
}
isDisjointFrom(_other: ReadonlySetLike<unknown>): boolean {
return todo();
}
[Symbol.iterator](): SetIterator<Id> {
return this.set[Symbol.iterator]().map((v) => idFromRaw(v));
}
get [Symbol.toStringTag](): string {
return this.set[Symbol.toStringTag];
}
}
export class IdMap<Id extends IdBase, V> implements Map<Id, V> {
private map = new Map<IdRaw<Id>, V>();
set(id: Id, val: V): this {
this.map.set(idRaw(id), val);
return this;
}
get(id: Id): V | undefined {
return this.map.get(idRaw(id));
}
has(id: Id): boolean {
return this.map.has(idRaw(id));
}
keys(): MapIterator<Id> {
return this.map.keys()
.map((rawId) => idFromRaw(rawId));
}
clear(): void {
this.map.clear();
}
delete(id: Id): boolean {
return this.map.delete(idRaw(id));
}
forEach(
callbackfn: (value: V, key: Id, map: Map<Id, V>) => void,
thisArg?: unknown,
): void {
this.map.forEach(
(value, key, _map) => callbackfn(value, idFromRaw(key), this),
thisArg,
);
}
get size(): number {
return this.map.size;
}
entries(): MapIterator<[Id, V]> {
return this.map.entries()
.map(([rawId, v]) => [idFromRaw(rawId), v]);
}
values(): MapIterator<V> {
return this.map.values();
}
[Symbol.iterator](): MapIterator<[Id, V]> {
return this.map[Symbol.iterator]()
.map(([rawId, v]) => [idFromRaw(rawId), v]);
}
get [Symbol.toStringTag](): string {
return this.map[Symbol.toStringTag];
}
}