Skip to content

fix(angular): fix nested @for track expression with outer-scope variable#29

Merged
Brooooooklyn merged 1 commit into
mainfrom
fix/angular-nested-for-track-scope
Feb 22, 2026
Merged

fix(angular): fix nested @for track expression with outer-scope variable#29
Brooooooklyn merged 1 commit into
mainfrom
fix/angular-nested-for-track-scope

Conversation

@Brooooooklyn
Copy link
Copy Markdown
Member

@Brooooooklyn Brooooooklyn commented Feb 22, 2026

The Rust resolve_names phase was merging update-scope variables into the
create-scope, making @for loop variables (like $implicit) visible when
resolving RepeaterCreate.track expressions. Angular TypeScript processes
create and update ops as separate lexical scopes. This caused track
expressions referencing outer @for variables to resolve incorrectly,
producing broken output with out-of-scope identifiers instead of
generating this-based track functions with usesComponentInstance=true.

Three fixes applied:

  • resolve_names: stop merging update scope into create scope, process
    RepeaterCreate.track_by_ops with their own scope
  • resolve_contexts: process view.functions (arrow fn ops) and
    RepeaterCreate.track_by_ops
  • reify: handle track_by_ops in reify_track_by, generating proper
    function vs arrow forms based on usesComponentInstance

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com


Note

Medium Risk
Touches core template compilation phases (name/context resolution and reification) and changes lexical scoping semantics, which can subtly affect generated output across templates beyond nested @for cases.

Overview
Fixes incorrect codegen for nested @for where an inner track expression references an outer-scope variable, aligning Rust pipeline behavior with Angular’s lexical scoping rules.

resolve_names now treats create and update ops as separate lexical scopes (no longer merging update-scope vars into create), preventing @for update variables (e.g. $implicit, $index) from leaking into RepeaterCreate.track resolution. resolve_contexts additionally resolves context accesses inside arrow-function ops and RepeaterCreate.track_by_ops via a shared vec-based update-scope resolver.

reify_track_by now supports track_by_ops by reifying those ops into statements and choosing function vs arrow based on uses_component_instance and statement shape, ensuring generated track functions can safely access outer context (e.g., via this). Adds an integration snapshot test covering the nested outer-scope track case.

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

Copy link
Copy Markdown
Member Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

Comment thread crates/oxc_angular_compiler/src/pipeline/phases/resolve_names.rs Outdated
@Brooooooklyn Brooooooklyn force-pushed the fix/angular-nested-for-track-scope branch from 051a378 to 7a713e8 Compare February 22, 2026 10:25
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

The Rust resolve_names phase was merging update-scope variables into the
create-scope, making @for loop variables (like $implicit) visible when
resolving RepeaterCreate.track expressions. Angular TypeScript processes
create and update ops as separate lexical scopes. This caused track
expressions referencing outer @for variables to resolve incorrectly,
producing broken output with out-of-scope identifiers instead of
generating `this`-based track functions with usesComponentInstance=true.

Three fixes applied:
- resolve_names: stop merging update scope into create scope, process
  RepeaterCreate.track_by_ops with their own scope
- resolve_contexts: process view.functions (arrow fn ops) and
  RepeaterCreate.track_by_ops
- reify: handle track_by_ops in reify_track_by, generating proper
  function vs arrow forms based on usesComponentInstance

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Brooooooklyn Brooooooklyn force-pushed the fix/angular-nested-for-track-scope branch from 7a713e8 to e99d34b Compare February 22, 2026 11:20
@Brooooooklyn Brooooooklyn merged commit a387e4e into main Feb 22, 2026
4 checks passed
@Brooooooklyn Brooooooklyn deleted the fix/angular-nested-for-track-scope branch February 22, 2026 11:57
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