Summary
Fixes #37445
The compiler's immutable Stack data structure (compiler/packages/babel-plugin-react-compiler/src/Utils/Stack.ts) implemented find, contains, each, and print by recursing one JS call-stack frame per linked-list node. For compiler inputs with a large number of active/nested scopes (tens of thousands of stack entries), these traversals could exceed the JS call-stack depth and throw:
RangeError: Maximum call stack size exceeded
Fix
Converted find, contains, each, and print on the Node class from per-node recursion to iterative while loops that walk the linked list. Traversal order (top-to-bottom / most-recently-pushed-first) is preserved exactly; only the call-stack depth changes β it is now O(1) instead of O(n) in the number of stack entries.
To satisfy the @typescript-eslint/no-this-alias lint rule (no aliasing this to a local variable), each method first processes this's own value, then iterates over this.#next onward using a local node variable β so this itself is never aliased.
Empty#find/contains/each/print were already O(1) (terminal case) and are unchanged.
Test plan
Added src/__tests__/Stack-test.ts with:
- Basic correctness checks for find/contains/each/print on a small stack, verifying traversal order.
- A regression test that pushes 50,000 entries onto the Stack and calls find, contains, each, and print, asserting none of them throw and that results are correct β this reproduces the reported overflow on the old recursive implementation and passes with the iterative fix.
Ran:
- yarn workspace babel-plugin-react-compiler lint β passes.
- yarn jest in compiler/packages/babel-plugin-react-compiler β full suite passes (15 suites / 43 tests / 40 snapshots).