Files
scriptc/tests/corpus/native-callback-dispatch.ts
Chris Tate 1f10e83720 Promote canary to main (#738)
- Preserve callback identity, receiver binding, and class references across unions and collections.
- Track record field presence independently of undefined values and improve native runtime behavior.
- Expand differential coverage and streamline CI bootstrap and compiler rebuild checks.
2026-10-08 11:00:13 -05:00

78 lines
2.8 KiB
TypeScript

class Counter {
count = 0;
notify(): void { this.count++; }
callback = (n: number): number => { this.count += n; return this.count; };
}
const counter = new Counter();
counter.notify();
console.log(counter.callback(2), counter.count);
counter.callback = (n: number): number => n * 3;
console.log(counter.callback(4), counter.count);
const calls: ((n: number) => number)[] = [(n: number): number => n + 1];
let receivers = 0;
let indexes = 0;
function receiver(): ((n: number) => number)[] { receivers++; return calls; }
function index(): number { indexes++; return 0; }
function replace(): number { calls[0] = (n: number): number => n + 100; return 5; }
console.log(receiver()[index()](replace()), calls[0](5), receivers, indexes);
let effects = 0;
function effect(): number { effects++; return 1; }
try { calls[3](effect()); } catch (error) { console.log(error instanceof TypeError, effects); }
function withReceiver(this: unknown, n: number): number {
console.log(this === calls);
return n + 9;
}
calls[0] = withReceiver;
console.log(calls[0](2));
function capture(this: unknown): () => boolean { return () => this === calls; }
const captures: (() => () => boolean)[] = [capture];
const saved = captures[0]();
console.log(saved());
const captureCalls: ((same?: unknown) => () => boolean)[] = [];
function captured(this: unknown, same: unknown = this): () => boolean { return () => this === same; }
captureCalls.push(captured);
const check = captureCalls[0]();
console.log(check());
function plainReceiver(this: unknown): boolean { return this === undefined; }
function nestedReceiver(this: unknown): boolean { return plainReceiver(); }
const nestedCalls: (() => boolean)[] = [nestedReceiver];
console.log(nestedCalls[0]());
interface Callable { notify(): void; }
function replaceNamed(value: Callable): void {
value.notify = (): void => { counter.count += 10; };
}
replaceNamed(counter);
counter.notify();
console.log(counter.count);
function replaceLiteral(value: Callable): void {
value["notify"] = (): void => { counter.count += 20; };
}
replaceLiteral(counter);
counter.notify();
console.log(counter.count);
function replaceComputed(value: Callable, key: keyof Callable): void {
value[key] = (): void => { counter.count += 30; };
}
replaceComputed(counter, "notify");
counter.notify();
console.log(counter.count);
function replaceReflected(value: Callable): void {
Object.defineProperty(value, "notify", { value: (): void => { counter.count += 40; } });
}
replaceReflected(counter);
counter.notify();
console.log(counter.count);
class CallbackOwner {
value = 7;
callback = (): number => this.value;
}
const owner = new CallbackOwner();
function replaceField(value: CallbackOwner): void {
value.callback = function (this: CallbackOwner): number { return this.value + 5; };
}
replaceField(owner);
console.log(owner.callback());