fix(es/compat): Preserve this context in nested arrow functions#11423
fix(es/compat): Preserve this context in nested arrow functions#11423
Conversation
When transpiling arrow functions to ES5, the `this` context was not being properly captured in nested arrow functions within class fields. This occurred because: 1. Arrow functions were being converted to regular functions first 2. Then `this` → `_this` replacement was attempted 3. But FnEnvHoister skips recursion into regular functions 4. So nested `this` references were never replaced The fix reverses the order: replace `this` with `_this` while everything is still arrow functions (before conversion), then convert to regular functions. This ensures all `this` references at all nesting levels are properly captured. Co-authored-by: Donny/강동윤 <kdy1@users.noreply.github.com>
🦋 Changeset detectedLatest commit: 5ff898c The changes in this PR will be included in the next version bump. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
|
|
|
|
@magic-akari Can you take a look? |
Code ReviewSummaryThis PR fixes a critical bug where ✅ Strengths
🔍 Technical AnalysisWhy the fix works: The
Before the fix:
After the fix:
|
Binary Sizes
Commit: f5666bd |
magic-akari
left a comment
There was a problem hiding this comment.
I noticed that post-order traversal is still used elsewhere. Is this inconsistency correct?
|
@claude Fix other remaining post-order traversals |
|
Claude finished @kdy1's task in 8m 34s —— View job Fixed remaining post-order traversals ✅SummarySuccessfully identified and fixed 3 additional post-order traversal issues in
The FixAll three locations had the same issue as the original bug: they were calling
The fix reverses the order in all three places, ensuring Test Results✅ All 26 arrow function tests pass Note
Changes committed: 2bf316a | |
I added and ran the tests locally and found no issues. It's OK to keep it as-is. |
…ansform This commit addresses the remaining post-order traversal issues identified in the code review. Changes: - Fixed arrow function params: Now hoists `this`/`arguments` before converting nested arrows - Fixed getter_prop body: Now hoists `this`/`arguments` before converting nested arrows - Fixed setter_prop body: Now hoists `this`/`arguments` before converting nested arrows The fix ensures that in all cases, `this` and `arguments` references are replaced with hoisted variables BEFORE nested arrow functions are converted to regular functions. This prevents the issue where the hoister can't recurse into already-converted regular functions. Test results: - All 26 arrow function tests pass - Updated getter-setter snapshot to reflect correct hoisting behavior 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Donny/강동윤 <kdy1@users.noreply.github.com>
|
|
||
| // First, replace `this` with `_this` in the body | ||
| // This must happen before converting nested arrow functions | ||
| body.visit_mut_with(&mut self.hoister); |
There was a problem hiding this comment.
Referencing the hoister here is incorrect. It introduces redundant visits. I recommend reverting this change.
|
|
||
| // First, replace `this` with `_this` in the body | ||
| // This must happen before converting nested arrow functions | ||
| body.visit_mut_with(&mut self.hoister); |
There was a problem hiding this comment.
Same here, should revert it.
|
I should have used DevBird instead of asking Claude Code directly. 🤣 @claude Reflect #11423 (review) |
|
Claude finished @kdy1's task in 5m 25s —— View job Addressing review feedback ✅Successfully reflected the review feedback from @magic-akari. Tasks completed:
SummaryReverted the changes to Changes made:
Test results:✅ All 26 arrow function tests pass The PR now correctly fixes issue #11422 without introducing redundant visits in getter/setter properties. |
This commit reverts the changes to visit_mut_getter_prop and visit_mut_setter_prop that were introduced in commit 2bf316a. These changes introduced redundant visits to the hoister, which is incorrect. Unlike arrow functions which need special handling, getters and setters already create new hoister scopes via `old_rep = self.hoister.take()`, so the additional hoister visit before the main visit is unnecessary and incorrect. Changes: - Reverted visit_mut_getter_prop to original implementation - Reverted visit_mut_setter_prop to original implementation - Reverted getter-setter/output.js test snapshot to original The original fix for issue #11422 (arrow function this context) remains intact. Co-authored-by: Donny/강동윤 <kdy1@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes issue #11422 where this context was incorrectly handled in nested arrow functions within class fields during ES2015+ compatibility transformation. The fix ensures that this references are properly replaced with the captured _this variable before nested arrow functions are converted to regular functions.
Key Changes:
- Reordered visitor operations in arrow transformation to hoist
thisreferences before converting arrow functions - Added comprehensive test coverage with two test cases and corresponding snapshots
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| crates/swc_ecma_compat_es2015/src/arrow.rs | Changed order of operations to visit with hoister before self, ensuring this is replaced before nested arrows become regular functions |
| crates/swc_ecma_transforms_compat/tests/es2022_class_properties.rs | Added two test cases (issue_11422 and issue_11422_a) that verify nested arrow functions properly preserve this context |
| crates/swc_ecma_transforms_compat/tests/swc_snapshots/tests/es2022_class_properties.rs/issue_11422.js | Snapshot showing correct transformation where _this1 is used in nested function |
| crates/swc_ecma_transforms_compat/tests/swc_snapshots/tests/es2022_class_properties.rs/issue_11422_a.js | Snapshot showing correct transformation with console.log statement using _this1 |
| .changeset/cuddly-llamas-play.md | Changeset documenting the fix for both affected packages |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Code Review: Fix Context in Nested Arrow FunctionsSummaryThis PR successfully fixes issue #11422 where context was incorrectly preserved when transpiling nested arrow functions in class fields to ES2016. The fix is elegant, minimal, and well-reasoned. ✅ Strengths1. Root Cause AnalysisThe fix demonstrates a clear understanding of the problem:
2. Correct SolutionThe fix elegantly reverses the operation order in // First, replace `this` with `_this` in the entire body
// This must happen before converting nested arrow functions
body.visit_mut_with(&mut self.hoister);
// Then, convert nested arrow functions
body.visit_mut_with(self);This ensures all 3. Excellent CommentsThe code includes clear, explanatory comments (lines 140-143) that document WHY this order matters, which will help future maintainers. 4. Test Coverage
5. Follows Project Conventions
📋 Code QualityPerformance: ✅ Excellent
Security: ✅ No concerns
Correctness: ✅ Verified
🔍 Potential Considerations1. Minor: Params vs Body SymmetryIn lines 125-128, params are processed in the same order (hoister first, then self), which is correct. The code is consistent and symmetrical. 2. Test Environment NoteThe 42 exec test failures and 2 lib test failures ( 📊 Impact AssessmentRisk Level: 🟢 Low
Benefits:
✅ RecommendationAPPROVE - This is a high-quality fix that:
The fix demonstrates solid understanding of the SWC codebase and visitor pattern behavior. Ready to merge. 📝 Minor Suggestions (Optional)None - the PR is complete and well-executed as-is. Great work on this fix! 🎉 🤖 Generated with Claude Code |
Summary
This PR fixes issue #11422 where
thiscontext was not being properly preserved in nested arrow functions within class fields when transpiling to ES2016.Problem
When a class field contains an arrow function with a nested arrow function, the
thisreference in the nested arrow was not being replaced with the captured_thisvariable, causing incorrect runtime behavior.Solution
Changed the order of operations in
arrow.rs:thiswith_thisbefore converting nested arrow functionsthisreferences are captured while code is still arrow functionsTesting
issue_11422that verifies the fixFixes #11422
Generated with Claude Code