Skip to content

fix: listener handler scope should not merge parent local_definitions…#4

Merged
Brooooooklyn merged 1 commit into
mainfrom
02-04-fix_listener_handler_scope_resolve_names
Feb 4, 2026
Merged

fix: listener handler scope should not merge parent local_definitions…#4
Brooooooklyn merged 1 commit into
mainfrom
02-04-fix_listener_handler_scope_resolve_names

Conversation

@Brooooooklyn
Copy link
Copy Markdown
Member

@Brooooooklyn Brooooooklyn commented Feb 4, 2026

… in resolve_names

In Angular's resolve_names.ts, listener handler ops are processed as a completely separate lexical scope via recursive processLexicalScope(unit, op.handlerOps, savedView) — no merging from the parent view's scope.

OXC incorrectly merged the parent view's update_scope (including local_definitions) into the handler scope. This caused @let declarations (which have local=true) from the update scope to take precedence over the handler's ContextLetReferenceExpr variables. The ContextLetReferenceExpr became unused, was removed by optimizeVariables, and then optimizeStoreLet couldn't find external @let usage — incorrectly removing the storeLet wrapper and causing cumulative pipe varOffset drift.

The fix makes handler ops self-contained (matching Angular), since generateVariables already prepends all necessary variables to handler_ops.

Fixes 43 ClickUp comparison mismatches (203 → 160, 96.5% → 97.3%).


Note

Medium Risk
Changes lexical name resolution for all listener/animation handler ops, which can alter generated JS and variable binding behavior across many templates. The logic is localized but touches core scoping used by event callbacks and could regress edge-case variable capture if mis-modeled.

Overview
Aligns resolve_names with Angular by treating listener/animation handler_ops as a fresh lexical scope built only from handler variables, removing the previous merge of parent scope/local_definitions into handler resolution.

Adds integration coverage for @let values produced via pipes when referenced from child views or listener callbacks, asserting ɵɵstoreLet preservation (avoiding pipe varOffset drift) and snapshotting the expected declareLet/readContextLet output.

Written by Cursor Bugbot for commit fddd914. This will update automatically on new commits. Configure here.

… in resolve_names

In Angular's resolve_names.ts, listener handler ops are processed as a
completely separate lexical scope via recursive processLexicalScope(unit,
op.handlerOps, savedView) — no merging from the parent view's scope.

OXC incorrectly merged the parent view's update_scope (including
local_definitions) into the handler scope. This caused @let declarations
(which have local=true) from the update scope to take precedence over
the handler's ContextLetReferenceExpr variables. The ContextLetReferenceExpr
became unused, was removed by optimizeVariables, and then optimizeStoreLet
couldn't find external @let usage — incorrectly removing the storeLet
wrapper and causing cumulative pipe varOffset drift.

The fix makes handler ops self-contained (matching Angular), since
generateVariables already prepends all necessary variables to handler_ops.

Fixes 43 ClickUp comparison mismatches (203 → 160, 96.5% → 97.3%).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@Brooooooklyn Brooooooklyn merged commit ad9a858 into main Feb 4, 2026
3 checks passed
@Brooooooklyn Brooooooklyn deleted the 02-04-fix_listener_handler_scope_resolve_names branch February 4, 2026 04:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant