Skip to content

Commit 233ab76

Browse files
committed
fix(check:settings-bind-window): a continuation keeps its enclosing frame's bound hook-name parameters
Claude-Session: https://claude.ai/code/session_0115N1oNnQS5WqofZ2DzaT3q Co-authored-by: Claude <noreply@anthropic.com>
1 parent 91d5e5c commit 233ab76

1 file changed

Lines changed: 7 additions & 2 deletions

File tree

‎scripts/check-settings-bind-window.mjs‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,8 @@ function preBindReads(unit, src, hookNames = new Set([READY_HOOK, ...Object.keys
618618
if (PROMISE_CONTINUATIONS.has(callee.name.text)) {
619619
for (const arg of node.arguments) {
620620
const continuation = resolveCallable(arg);
621-
if (continuation) walk(continuation, origin, visited, onHook);
621+
// A closure sees its enclosing frame, parameters included.
622+
if (continuation) walk(continuation, origin, visited, onHook, bindings);
622623
}
623624
}
624625
// `this.m(...)` → same-class method or function-valued property.
@@ -1453,6 +1454,9 @@ function selfTest() {
14531454
const trigger = (ctx as any).trigger;
14541455
trigger.call(ctx, event, { sys });
14551456
}
1457+
private emitWhenSettled(ctx: PluginContext, event: string): void {
1458+
settled.then(() => ctx.trigger(event));
1459+
}
14561460
async init(ctx: PluginContext) { await ctx.trigger('x:init', {}); }
14571461
async start(ctx: PluginContext) {
14581462
await ctx.trigger('x:direct', this.service);
@@ -1462,6 +1466,7 @@ function selfTest() {
14621466
};
14631467
emitSettled(false);
14641468
this.emitCatalogEvent(ctx, 'x:param', {});
1469+
this.emitWhenSettled(ctx, 'x:then-param');
14651470
seedPromise.then(() => ctx.trigger('x:then'));
14661471
setTimeout(() => ctx.trigger('x:timer'), 10);
14671472
ctx.hook('kernel:bootstrapped', async () => { await ctx.trigger('x:late'); });
@@ -1471,7 +1476,7 @@ function selfTest() {
14711476
`);
14721477
const derived = derivePreBindHooks(units);
14731478
const names = [...derived.fired.keys()].sort();
1474-
assert(JSON.stringify(names) === JSON.stringify(['x:call', 'x:direct', 'x:init', 'x:param', 'x:then']),
1479+
assert(JSON.stringify(names) === JSON.stringify(['x:call', 'x:direct', 'x:init', 'x:param', 'x:then', 'x:then-param']),
14751480
`the derivation reads every shipped fire-site spelling and nothing deferred (got ${names.join(', ')})`);
14761481
assert(derived.fired.get('x:init')[0].origin === 'init-body', 'an init() fire site is recorded as init-body');
14771482
assert(derived.unresolved.length === 1 && derived.unresolved[0].text === 'eventName',

0 commit comments

Comments
 (0)