Skip to content

Conversation

@kdy1
Copy link
Member

@kdy1 kdy1 commented Nov 19, 2025

Description:

BREAKING CHANGE:

Related issue (if exists):

@changeset-bot
Copy link

changeset-bot bot commented Nov 19, 2025

⚠️ No Changeset found

Latest commit: 3841ccf

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Member Author

kdy1 commented Nov 19, 2025

@kdy1 kdy1 changed the title exponentation_operator perf(es/compat): Merge exponentation operator Nov 19, 2025
@kdy1 kdy1 marked this pull request as ready for review November 19, 2025 19:51
@kdy1 kdy1 requested a review from a team as a code owner November 19, 2025 19:51
@kdy1 kdy1 force-pushed the kdy1/exponentation-operator branch from 946f74a to 3f8225b Compare November 19, 2025 19:52
@claude
Copy link
Contributor

claude bot commented Nov 19, 2025

Pull Request Review: perf(es/compat): Merge exponentation operator

Thank you for working on this performance optimization! I've reviewed the PR and have several concerns about the implementation.

Critical Issues

1. Empty Implementation - No Transformation Logic

The new ExponentiationOperatorPass in crates/swc_ecma_transformer/src/es2016/exponentation_operator.rs:10 is completely empty:

#[derive(Default)]
struct ExponentiationOperatorPass {}

impl VisitMutHook<TraverseCtx> for ExponentiationOperatorPass {}

This is missing the actual transformation logic that converts exponentiation operators. The existing implementation in crates/swc_ecma_compat_es2016/src/exponentiation.rs contains substantial logic to:

  • Transform ** binary expressions to Math.pow() calls
  • Transform **= assignment expressions to = Math.pow()
  • Handle complex cases like member expressions with temporary variables
  • Implement ParExplode for proper variable declaration handling

Impact: Without this logic, the exponentiation operator will not be transformed at all, breaking compatibility for ES2016 targets.

2. Typo in Field Name

In crates/swc_ecma_preset_env/src/lib.rs:213:

options.env.es2016.exponentation_operator = true;

The field is named exponentation_operator (missing 'i') instead of exponentiation_operator. While this is consistent with the module name, it's inconsistent with the Feature enum ExponentiationOperator and the standard spelling of "exponentiation". This should be corrected throughout.

3. Missing Import Removal

In crates/swc_ecma_preset_env/src/lib.rs:19, the es2016 module import was removed, but the code at line 213 tries to access options.env.es2016.exponentation_operator. This will likely cause a compilation error or the field won't exist on the options structure.

Code Quality & Best Practices

4. Missing Documentation

Following CLAUDE.md guideline #7 ("Write documentation for your code"), the new module and struct lack documentation explaining:

  • What the pass does
  • How it transforms code
  • Examples of input/output transformations

The existing implementation has excellent documentation starting at line 9 of crates/swc_ecma_compat_es2016/src/exponentiation.rs.

5. Missing Unit Tests

Following CLAUDE.md guideline #5 ("Write unit tests for your code"), there are no tests for the new implementation. The existing implementation includes comprehensive tests starting at line 153 of crates/swc_ecma_compat_es2016/src/exponentiation.rs.

Performance Considerations

The PR title mentions this is a performance optimization to "merge" the exponentiation operator pass. However:

  • The actual merging strategy isn't clear from the code
  • No benchmarks or performance measurements are provided
  • The empty implementation suggests the work is incomplete

Recommendations

  1. Complete the Implementation: Port the transformation logic from swc_ecma_compat_es2016 to the new hook-based implementation, including:

    • The VisitMut implementation for Expr transformation
    • The ParExplode trait implementation or equivalent
    • Variable declaration handling
  2. Fix the Typo: Rename exponentation_operator to exponentiation_operator throughout

  3. Add Documentation: Include module-level docs and examples

  4. Add Tests: Port or reference the existing test suite

  5. Verify Integration: Ensure the feature flag properly enables/disables the transformation

  6. Run Tests: Execute cargo test to ensure nothing breaks, especially for es2016-related tests

Security & Other Concerns

No security issues identified. The transformation itself is straightforward AST manipulation.


Summary: This PR appears to be a work-in-progress. The structure is good, but the implementation is incomplete. Please address the empty transformation logic before merging.

@claude
Copy link
Contributor

claude bot commented Nov 19, 2025

Code Review - PR #11310: perf(es/compat): Merge exponentation operator

Summary

This PR is migrating the exponentiation operator transformation from a separate pass to being merged into the unified single-pass transformer architecture. This is part of a larger effort to improve compilation performance by reducing the number of AST traversals.


Critical Issues

1. Typo in naming: 'exponentation' instead of 'exponentiation'

Severity: High ⚠️

Throughout the PR, there's a consistent typo: exponentation instead of exponentiation. This affects:

  • File name: crates/swc_ecma_transformer/src/es2016/exponentation_operator.rs
  • Field name: pub exponentation_operator: bool
  • Module import: mod exponentation_operator;

Location:

  • crates/swc_ecma_preset_env/src/lib.rs:213
  • crates/swc_ecma_transformer/src/es2016/mod.rs:1, :10, :15
  • crates/swc_ecma_transformer/src/es2016/exponentation_operator.rs (filename)

Recommendation: Rename all instances to use the correct spelling exponentiation.


2. Empty implementation - No actual transformation logic

Severity: Critical 🚨

The new ExponentiationOperatorPass struct in exponentation_operator.rs is completely empty:

#[derive(Default)]
struct ExponentiationOperatorPass {}

impl VisitMutHook<TraverseCtx> for ExponentiationOperatorPass {}

Issue: The implementation has no methods that actually transform the exponentiation operator. The existing transformation logic from crates/swc_ecma_compat_es2016/src/exponentiation.rs (which handles ** and **= operators) has not been ported.

Expected implementation: Should include hooks like exit_expr to transform:

  • Binary expressions with ** operator to Math.pow() calls
  • Assignment expressions with **= operator to equivalent assignments

Location: crates/swc_ecma_transformer/src/es2016/exponentation_operator.rs:10-12


Performance Considerations

3. Performance improvement is the goal but implementation is incomplete

Status: In Progress

The PR title mentions "perf" improvement by merging this operator into the single-pass compiler. However, since the transformation logic hasn't been implemented yet:

  • The old es2016::exponentiation() pass has been removed from the pipeline (lib.rs:19)
  • The new hook is wired up but does nothing
  • Result: Exponentiation operators will NOT be transformed, breaking ES2016 compatibility

Test Coverage

4. No tests included

Severity: High ⚠️

According to CLAUDE.md guideline #5: "Write unit tests for your code."

The original implementation in crates/swc_ecma_compat_es2016/src/exponentiation.rs:153-254 has comprehensive tests:

  • Binary exponentiation: 2 ** 2
  • Assignment operators: x **= 3
  • Complex expressions
  • Edge cases with member expressions

Recommendation: Port these tests to the new architecture or ensure integration tests verify the transformation still works.


Code Quality

5. Documentation missing

Severity: Medium

According to CLAUDE.md guideline #7: "Write documentation for your code."

The new exponentation_operator.rs file lacks:

  • Module-level documentation explaining what transformation it performs
  • Function documentation for hook()
  • Examples of input/output transformations

The original implementation had good documentation:

/// `@babel/plugin-transform-exponentiation-operator`
///
/// # Example
/// ## In
/// ```js
/// let x = 10 ** 2;
/// ```
/// ## Out
/// ```js
/// let x = Math.pow(10, 2);
/// ```

Architecture & Design

6. Integration with preset-env is correct

Status: Good

The change in crates/swc_ecma_preset_env/src/lib.rs correctly:

  • Removes the old separate pass
  • Sets the option flag when the feature is not supported: options.env.es2016.exponentation_operator = true
  • Relies on the single-pass compiler to handle it: options.into_pass()

This follows the same pattern as the related PR #11309 for export_namespace_from.


7. OptionalHook usage is appropriate

Status: Good

Using OptionalHook to conditionally apply the transformation is the right pattern, consistent with other ES20XX modules (e.g., es2020/mod.rs).


Security Concerns

No security issues identified. The transformation deals with syntax conversion only.


Recommendations

Before merging:

  1. Fix the typo - Rename exponentationexponentiation everywhere
  2. Implement the transformation logic - Port the actual AST transformation from swc_ecma_compat_es2016
  3. Add tests - Either unit tests in the new module or integration tests
  4. Add documentation - Document what the transformation does with examples
  5. Run cargo fmt --all - Per CLAUDE.md guideline Unignore "431ecef8c85d4d24.js" and "8386fbff927a9e0e.js". #8

Missing implementation details to port:

  • Transform Expr::Bin with op!('**') to Math.pow(left, right)
  • Transform Expr::Assign with op!('**=') to equivalent assignment
  • Handle edge cases with member expressions and complex left-hand sides
  • Implement ParExplode for variable declarations if needed in the new architecture

Related Context

This PR is part of a stack (depends on #11309) working toward merging all ES compatibility transforms into a unified single-pass compiler for better performance. The approach is sound, but this particular PR appears to be incomplete and may have been accidentally pushed before implementation was finished.


Overall Assessment: The architectural direction is correct and follows established patterns in the codebase, but the implementation is incomplete. The most critical issue is that the transformation logic is missing, which will break ES2016 compatibility for code using the exponentiation operator.

@claude
Copy link
Contributor

claude bot commented Nov 19, 2025

Code Review for PR #11310: perf(es/compat): Merge exponentation operator

Thank you for this performance optimization! This PR aims to merge the exponentiation operator transformation into the single-pass compiler. However, I've identified several critical issues that need to be addressed before this can be merged.

🔴 Critical Issues

1. Empty Implementation - No Transformation Logic

The new ExponentiationOperatorPass in crates/swc_ecma_transformer/src/es2016/exponentation_operator.rs is essentially a no-op:

impl VisitMutHook<TraverseCtx> for ExponentiationOperatorPass {}

Issue: This implementation doesn't actually transform exponentiation operators (** and **=) into Math.pow() calls. The old implementation in crates/swc_ecma_compat_es2016/src/exponentiation.rs contains the full transformation logic (150+ lines) that:

  • Converts binary expressions like 2 ** 3 to Math.pow(2, 3)
  • Handles assignment expressions like x **= 3
  • Properly manages variable hoisting and side effects
  • Includes parallel processing support

Impact: This PR will completely break exponentiation transformation, causing ES2016+ code to remain untransformed for older targets.

Fix Required: The transformation logic from swc_ecma_compat_es2016 needs to be ported to the new hook-based system. You'll need to implement the enter_expr and/or exit_expr methods (or similar hooks) to properly transform the AST nodes.

2. Typo in Field Name

pub exponentation_operator: bool,  // Should be: exponentiation_operator

Location:

  • crates/swc_ecma_transformer/src/es2016/mod.rs:10
  • crates/swc_ecma_preset_env/src/lib.rs:213

Issue: "exponentation" should be "exponentiation" (missing 'i'). This typo appears consistently across the codebase and in file names (exponentation_operator.rs).

Fix Required: Rename to exponentiation_operator throughout for consistency with existing naming (e.g., Feature::ExponentiationOperator).

⚠️ Major Concerns

3. Missing Tests

The new implementation has no unit tests. The old implementation in swc_ecma_compat_es2016 has comprehensive test coverage including:

  • Basic binary expressions
  • Assignment operators
  • Member expressions
  • Edge cases with side effects

Fix Required: Add tests to verify the transformation works correctly in the new system, or at minimum ensure existing integration tests pass.

4. Missing Documentation

Per CLAUDE.md guideline #7: "Write documentation for your code."

The new implementation lacks:

  • Module-level documentation explaining the transformation
  • Comments describing the purpose and behavior
  • Examples of input/output transformations

The old implementation has excellent documentation showing input/output examples.

📋 Additional Issues

5. Code Formatting

Per CLAUDE.md guideline #8: "Run cargo fmt --all before committing files."

Please ensure cargo fmt --all has been run on all modified files.

6. Performance Claims

The PR title mentions "perf" but:

  • There's no benchmark data showing the performance improvement
  • The "Benchmark" CI check failed
  • Without the actual transformation logic, performance can't be properly evaluated

Recommendation: Once the implementation is complete, provide benchmark comparisons showing the performance improvement from merging into the single-pass compiler.

🔍 Architecture Questions

  1. How should transformations be ported to the new hook system?

    • Should complex transformations like exponentiation use enter_expr/exit_expr hooks?
    • How should state (like the vars vector in the old implementation) be managed?
    • Are there examples of complex transformations already ported to the new system?
  2. Compatibility with old implementation

    • Should the old swc_ecma_compat_es2016 crate be kept for backward compatibility?
    • Is there a deprecation plan?

✅ What's Done Well

  1. Good integration pattern: The use of OptionalHook follows the established pattern from other ES version transformers (es2020, etc.)
  2. Correct conditional logic: The caniuse check in preset_env correctly determines when the transformation is needed
  3. Proper module structure: The new file organization matches the existing codebase structure

📝 Recommendation

This PR is not ready to merge in its current state. I recommend:

  1. Immediate: Implement the actual transformation logic in ExponentiationOperatorPass
  2. Before merge: Fix the typo (exponentation → exponentiation)
  3. Before merge: Add or verify test coverage
  4. Before merge: Add documentation following existing patterns
  5. Nice to have: Provide benchmark data demonstrating the performance improvement

Would you like me to help implement the transformation logic for the new hook system? I can show how to port the logic from swc_ecma_compat_es2016 to work with VisitMutHook.


Review performed in accordance with CLAUDE.md guidelines and SWC project conventions.

@codspeed-hq
Copy link

codspeed-hq bot commented Nov 19, 2025

CodSpeed Performance Report

Merging #11310 will degrade performances by 6.16%

Comparing kdy1/exponentation-operator (3841ccf) with main (f615cdb)1

Summary

⚡ 1 improvement
❌ 1 regression
✅ 136 untouched

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Benchmarks breakdown

Benchmark BASE HEAD Change
es2016_exponentiation 292.2 µs 285.7 µs +2.26%
es2020_nullish_coalescing 291.4 µs 310.5 µs -6.16%

Footnotes

  1. No successful run was found on main (b0d3154) during the generation of this report, so f615cdb was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@github-actions
Copy link
Contributor

github-actions bot commented Nov 19, 2025

Binary Sizes

File Size
swc.linux-x64-gnu.node 31M (31923400 bytes)

Commit: c779486

Base automatically changed from kdy1/tr-es2020 to main November 19, 2025 20:20
@kdy1 kdy1 requested a review from a team as a code owner November 19, 2025 20:20
@kdy1 kdy1 force-pushed the kdy1/exponentation-operator branch from 3f8225b to 1252b09 Compare November 19, 2025 20:39
Copilot AI review requested due to automatic review settings November 19, 2025 20:39
Copilot finished reviewing on behalf of kdy1 November 19, 2025 20:41
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR refactors the ES2016 exponentiation operator transformation to use an optional hook pattern, enabling conditional compilation based on configuration. The changes consolidate the transformation logic into a new module structure that can be selectively enabled.

  • Introduces an Es2016Options struct with a configurable flag for the exponentiation operator transform
  • Replaces the previous Es2016Pass implementation with an OptionalHook that conditionally applies the transformation
  • Creates a new module exponentation_operator (note: misspelled) with a dedicated pass for the exponentiation operator

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
crates/swc_ecma_transformer/src/es2016/mod.rs Refactored to use OptionalHook pattern with Es2016Options for conditional exponentiation operator transformation
crates/swc_ecma_transformer/src/es2016/exponentation_operator.rs New module containing dedicated ExponentiationOperatorPass (contains spelling errors)
crates/swc_ecma_preset_env/src/lib.rs Updated to set exponentation_operator flag based on Feature::ExponentiationOperator compatibility check

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@@ -1,17 +1,19 @@
mod exponentation_operator;
Copy link

Copilot AI Nov 19, 2025

Choose a reason for hiding this comment

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

Misspelled module name. Should be "exponentiation_operator" instead of "exponentation_operator" to match the standard spelling and the rest of the codebase (e.g., Feature::ExponentiationOperator, exponentiation() function).

Copilot uses AI. Check for mistakes.
pub fn hook(options: Es2016Options) -> impl VisitMutHook<TraverseCtx> {
Es2016Pass { options }
pub struct Es2016Options {
pub exponentation_operator: bool,
Copy link

Copilot AI Nov 19, 2025

Choose a reason for hiding this comment

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

Misspelled field name. Should be "exponentiation_operator" instead of "exponentation_operator" to match the standard spelling and the rest of the codebase.

Copilot uses AI. Check for mistakes.
Comment on lines 14 to 15
OptionalHook(if options.exponentation_operator {
Some(self::exponentation_operator::hook())
Copy link

Copilot AI Nov 19, 2025

Choose a reason for hiding this comment

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

Misspelled identifiers. Should be "exponentiation_operator" instead of "exponentation_operator" to match the standard spelling and the rest of the codebase.

Copilot uses AI. Check for mistakes.
Comment on lines 1 to 12
use swc_ecma_hooks::VisitMutHook;

use crate::TraverseCtx;

pub fn hook() -> impl VisitMutHook<TraverseCtx> {
ExponentiationOperatorPass::default()
}

#[derive(Default)]
struct ExponentiationOperatorPass {}

impl VisitMutHook<TraverseCtx> for ExponentiationOperatorPass {}
Copy link

Copilot AI Nov 19, 2025

Choose a reason for hiding this comment

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

Misspelled filename. This file should be named "exponentiation_operator.rs" instead of "exponentation_operator.rs" to match the standard spelling and the rest of the codebase.

Copilot uses AI. Check for mistakes.
@kdy1 kdy1 marked this pull request as draft November 19, 2025 20:45
@claude
Copy link
Contributor

claude bot commented Nov 19, 2025

Pull Request Review: perf(es/compat): Merge exponentation operator

Thank you for working on this performance optimization! I've reviewed PR #11310 and identified several critical issues that need to be addressed before merging.


🔴 Critical Issues

1. Empty Implementation - No Transformation Logic

Location: crates/swc_ecma_transformer/src/es2016/exponentation_operator.rs:1-12

The new ExponentiationOperatorPass hook is completely empty:

#[derive(Default)]
struct ExponentiationOperatorPass {}

impl VisitMutHook<TraverseCtx> for ExponentiationOperatorPass {}

Problem: This is missing all the actual transformation logic. The existing implementation in crates/swc_ecma_compat_es2016/src/exponentiation.rs:82-137 contains substantial logic to:

  • Transform ** binary expressions to Math.pow() calls
  • Transform **= assignment expressions to = Math.pow()
  • Handle complex cases like member expressions with temporary variables
  • Implement ParExplode for proper variable declaration handling

Impact: Without this logic, the exponentiation operator will not be transformed at all when using the new transformer, breaking ES2016 compatibility for affected targets.

Recommendation: Port the full transformation logic from swc_ecma_compat_es2016/src/exponentiation.rs to the new hook-based implementation.


2. Typo: "exponentation" should be "exponentiation"

Locations:

  • crates/swc_ecma_preset_env/src/lib.rs:213 - exponentation_operator
  • crates/swc_ecma_transformer/src/es2016/mod.rs:1 - module name exponentation_operator
  • crates/swc_ecma_transformer/src/es2016/mod.rs:10 - field name exponentation_operator
  • crates/swc_ecma_transformer/src/es2016/mod.rs:14-15 - variable references
  • crates/swc_ecma_transformer/src/es2016/exponentation_operator.rs - file name

Problem: Consistent misspelling throughout the codebase. The correct spelling is "exponentiation" (with an 'i').

Recommendation: Rename all occurrences to use the correct spelling.


3. Failing CI Test

The test suite Test - swc_ecma_preset_env - ubuntu-latest is failing in CI. This likely indicates that the transformation is not working correctly or that integration tests are detecting the missing implementation.

Recommendation: Investigate and fix the failing test before merging.


📋 Code Quality & Best Practices

✅ Positive Aspects:

  1. Good pattern usage: Using OptionalHook pattern is appropriate for conditional transformations
  2. Consistent structure: Following the same pattern as other es20XX modules
  3. Proper integration: Correctly integrated into the preset_env configuration flow

⚠️ Concerns:

  1. Missing unit tests: No tests in the new exponentation_operator.rs file (though the existing swc_ecma_compat_es2016 has good test coverage)
  2. Incomplete refactoring: This appears to be a partial migration - the old implementation in swc_ecma_compat_es2016 is still being used

🎯 Performance Considerations

The PR title mentions "Merge exponentation operator" suggesting this is about merging/consolidating the transformation with other passes for better performance. However:

  1. Current state: The implementation is empty, so no performance improvement can be realized yet
  2. Hook architecture: The hook-based approach should theoretically allow better composability and potentially better performance through unified traversals
  3. Missing context: Without the full implementation, it's unclear what specific performance optimizations are being applied

🔒 Security Concerns

No security issues identified. The transformation is syntactic and doesn't introduce injection vulnerabilities.


📊 Test Coverage

Current state:

  • swc_ecma_compat_es2016 has 7 tests (5 passing, 2 ignored)
  • ❌ No tests for the new hook implementation
  • ❌ CI test failure indicates integration issues

Recommendation:

  1. Add unit tests to the new implementation once logic is ported
  2. Ensure all existing tests continue to pass
  3. Follow CLAUDE.md guidance: "Write unit tests for your code" and "When instructed to fix tests, do not remove or modify existing tests"

📝 Summary

This PR appears to be incomplete. While the structure and integration points are set up correctly, the core transformation logic is missing, resulting in a non-functional implementation. Additionally, there's a typo throughout the codebase that should be corrected.

Recommended Actions:

  1. ✅ Port the full transformation logic from swc_ecma_compat_es2016/src/exponentiation.rs to the new hook
  2. ✅ Fix the typo: "exponentation" → "exponentiation"
  3. ✅ Investigate and fix the failing CI test
  4. ✅ Add unit tests for the new implementation
  5. ✅ Run cargo fmt --all before committing
  6. ✅ Verify all existing tests still pass

Overall Assessment: ❌ Not ready to merge - requires implementation completion and typo fixes.

Please let me know if you'd like help with any of these issues or have questions about the feedback!

@kdy1 kdy1 changed the title perf(es/compat): Merge exponentation operator perf(es/compat): Merge exponentation_operator Nov 19, 2025
@claude
Copy link
Contributor

claude bot commented Nov 19, 2025

Code Review for PR #11310

Summary

This PR aims to merge the exponentiation operator transformation into the new architecture. However, there is a critical issue: the new implementation is incomplete.


🚨 Critical Issues

1. Empty Implementation (crates/swc_ecma_transformer/src/es2016/exponentiation_operator.rs:12)

The new ExponentiationOperatorPass struct has an empty VisitMutHook implementation:

impl VisitMutHook<TraverseCtx> for ExponentiationOperatorPass {}

Problem: This does nothing. The original implementation in swc_ecma_compat_es2016/src/exponentiation.rs had ~127 lines of actual transformation logic that:

  • Converted ** binary expressions to Math.pow() calls
  • Converted **= assignment operators to = Math.pow()
  • Handled complex cases like member expressions and computed properties

Impact: All exponentiation operator transformations will silently fail. Tests will likely fail.

Fix needed: The transformation logic needs to be implemented. At minimum, you need:

impl VisitMutHook<TraverseCtx> for ExponentiationOperatorPass {
    fn enter_expr(&mut self, node: &mut Expr, _ctx: &mut TraverseCtx) {
        // Handle BinExpr with op!("\*\*")
        // Handle AssignExpr with op!("\*\*=")
    }
}

⚠️ Design Concerns

2. Circular Dependency (crates/swc_ecma_compat_es2016/Cargo.toml:21)

The PR adds swc_ecma_transformer as a dependency to swc_ecma_compat_es2016:

swc_ecma_transformer       = { version = "0.1.0", path = "../swc_ecma_transformer" }

Concern: This creates a potential circular dependency since:

  • swc_ecma_transformer likely depends on various compat crates
  • swc_ecma_compat_es2016 now depends on swc_ecma_transformer

Question: Is this the intended architecture? Should compat crates depend on the transformer, or should they be standalone and only used by the transformer?


📋 Other Observations

3. Missing Implementation Details

The old implementation handled several edge cases:

  • Variable hoisting for complex expressions (self.vars)
  • Parallel transformation support (ParExplode trait)
  • Member expression memoization
  • Assignment target handling

None of these are present in the new implementation.

4. Test Coverage

The tests in swc_ecma_compat_es2016/src/exponentiation.rs are preserved, which is good. However, they will all fail with the current empty implementation.

Recommendation: Run the tests locally to verify:

cargo test --package swc_ecma_compat_es2016 --lib exponentiation::tests

5. Integration Point (crates/swc_ecma_preset_env/src/lib.rs:210)

The preset-env integration looks correct:

if !caniuse(Feature::ExponentiationOperator) {
    options.env.es2016.exponentiation_operator = true;
}

This properly gates the feature based on browser support.


✅ Positive Aspects

  1. Clear migration path: The approach of keeping the old API but delegating to the new transformer is a good interim solution
  2. Consistent with project structure: Follows the pattern used in other ES version modules
  3. Proper feature gating: Uses OptionalHook to conditionally enable the transform

📝 Recommendations

  1. Immediate: Implement the actual transformation logic in ExponentiationOperatorPass
  2. Before merge: Run all tests and ensure they pass
  3. Documentation: Add comments explaining the transformation (per CLAUDE.md Travis and codecov #7)
  4. Consider: Whether the circular dependency is the right architecture

Style Notes (per CLAUDE.md)


Verdict: ❌ Cannot approve - Critical functionality is missing. The PR needs the actual transformation implementation before it can be merged.

@kdy1 kdy1 force-pushed the kdy1/exponentation-operator branch from 28a97ff to 267c144 Compare November 20, 2025 11:29
@claude
Copy link
Contributor

claude bot commented Nov 20, 2025

Pull Request Review: Merge exponentiation_operator into Single-Pass Compiler

Overview

This PR refactors the exponentiation operator transformation by moving it from the multi-pass swc_ecma_compat_es2016 crate into the new single-pass compiler infrastructure in swc_ecma_transformer. This is part of the broader effort to consolidate transforms for better performance.


Strengths

1. Architecture & Code Quality

  • Clean separation of concerns: The new StatementInjector infrastructure is well-designed for adding statements before/after AST nodes
  • Good documentation: Excellent inline documentation in exponentiation_operator.rs with references to Babel implementation and TC39 spec
  • Consistent with project direction: Aligns with the goal of creating a single-pass compiler
  • Proper integration: Well-integrated into the options system and preset-env

2. Performance Improvements

  • Single-pass transformation: Moving to the hook-based system enables single-pass compilation, which should improve performance
  • Reduced overhead: Eliminates the need for separate visitor pattern invocations
  • Better suited for parallel processing: The new architecture is more amenable to optimization

3. Code Simplicity

  • The new implementation is more straightforward and easier to understand
  • Good use of Rust's pattern matching
  • Proper use of Take trait for moving values

⚠️ Issues & Concerns

1. CRITICAL: Side-Effect Safety Regression

The old implementation used temporary variables to avoid side effects in member expressions:

// Old implementation
AssignTarget::Simple(ref e) => {
    let ref_ident = private_ident!(e.span(), "ref");
    self.vars.push(VarDeclarator {
        span: DUMMY_SP,
        name: ref_ident.clone().into(),
        init: Some(e.clone().into()),
        definite: false,
    });
    ref_ident
}

The new implementation (lines 107-113 in exponentiation_operator.rs) simply clones the expressions without creating temp variables:

// New implementation - POTENTIAL BUG
let obj = member_expr.obj.clone();
let prop = member_expr.prop.clone();

This creates a correctness issue for cases with side effects:

Example problematic case:

// Input
getObject().prop **= 2;

// Current output (INCORRECT - calls getObject() twice):
getObject().prop = Math.pow(getObject().prop, 2);

// Expected output (calls getObject() once):
var _ref = getObject();
_ref.prop = Math.pow(_ref.prop, 2);

Impact: This could cause bugs in production code where expressions with side effects are evaluated multiple times.

Recommendation:

  • Either implement the temp variable logic using the StatementInjector infrastructure
  • Or add a TODO comment acknowledging this limitation and plan to address it
  • The comment on line 130 mentions "For simplicity, handle the basic case without temp variables" but this is not just a simplification - it's a correctness issue

2. Memory Usage Consideration

In statement_injector.rs:88:

let address = stmt as *const Stmt as usize;

Concern: Using raw pointer addresses as HashMap keys could theoretically have issues:

  • If statements are moved in memory during AST transformations
  • Potential for address reuse after statements are dropped

Recommendation: Consider documenting this assumption or using a different approach (e.g., assigning unique IDs to statements that need injection)

3. Missing Test Coverage for BigInt

The implementation correctly skips BigInt literals (lines 52-54, 63-65), but I don't see explicit tests for this behavior:

if is_bigint_literal(&bin_expr.left) || is_bigint_literal(&bin_expr.right) {
    return;
}

Recommendation: Add test cases for:

10n ** 2n  // Should NOT be transformed
x **= 2n   // Should NOT be transformed

4. Unused Infrastructure

The StatementInjector infrastructure is created but not actually used by the exponentiation operator transform. The old implementation used ParExplode to inject variable declarations, but the new implementation doesn't inject any statements.

Questions:

  • Is the StatementInjector intended for future use?
  • If not currently needed, why add it in this PR?
  • The dependency on rustc-hash is added for StatementInjector but may be unnecessary if it's not used

📊 Performance Considerations

Positive:

  • Single-pass compilation should be faster overall
  • Less AST traversal overhead

Concern:

  • The new implementation clones Box<Expr> objects (lines 109-111), which could be expensive for deeply nested expressions
  • The old implementation used Take more effectively in some cases

🔒 Security Concerns

No significant security issues identified. The transformation is straightforward and doesn't introduce injection vulnerabilities.


📝 Test Coverage

Existing tests appear to pass, but:

  • Missing BigInt test coverage
  • The side-effect issue may not be caught by existing tests if they don't include expressions with side effects in member positions
  • Consider adding tests for:
    • getObj()[getKey()] **= 2 (computed property with side effects)
    • (x++).prop **= 2 (side effects in object expression)

🎯 Recommendations

  1. HIGH PRIORITY: Fix or document the side-effect safety issue for member expressions
  2. MEDIUM: Add BigInt test coverage
  3. MEDIUM: Clarify whether StatementInjector is needed or planned for future use
  4. LOW: Document the pointer-as-key assumption in StatementInjector
  5. LOW: Consider using take() instead of clone() where possible for better performance

📋 Checklist Against CLAUDE.md

✅ Write performant code - Generally yes, but cloning could be optimized
✅ Write comments in English - Excellent documentation
✅ No unstable features - Correct
✅ Unit tests - Existing tests present, but coverage gaps identified
⚠️ Don't remove tests when fixing - N/A, but ensure new issues don't break tests
✅ Documentation - Good inline docs
⚠️ Run cargo fmt - Should verify before merge


💭 Overall Assessment

This is a well-structured refactoring that moves in the right direction architecturally. However, there is a critical correctness issue with the handling of member expressions that have side effects. This needs to be addressed before merging to avoid introducing bugs.

The PR demonstrates good understanding of the codebase and the single-pass compiler goals. With the side-effect issue resolved, this would be a solid improvement.

Recommendation: Request changes to address the side-effect safety issue before merging.

@claude
Copy link
Contributor

claude bot commented Nov 20, 2025

Code Review for PR #11310: perf(es/compat): Merge exponentation_operator

Overview

This PR refactors the exponentiation operator transform by moving it from swc_ecma_compat_es2016 to the new single-pass swc_ecma_transformer architecture. This is a performance-focused refactoring that aligns with the project's migration to a unified transformer system.

✅ Strengths

  1. Architecture Improvement: Successfully merges the exponentiation operator into the single-pass transformer, which should improve compilation performance by reducing AST traversals.

  2. Good Documentation: The new implementation in exponentiation_operator.rs:1-32 includes comprehensive module documentation with examples, references, and implementation notes.

  3. Clean Abstraction: The wrapper in swc_ecma_compat_es2016/src/exponentiation.rs:22-26 provides backward compatibility while delegating to the new implementation.

  4. BigInt Handling: Correctly preserves BigInt exponentiation (exponentiation_operator.rs:53-55, 64-66) since Math.pow doesn't work with BigInt.

  5. Test Coverage: Maintains existing test suite in swc_ecma_compat_es2016, ensuring no regression.

⚠️ Issues & Concerns

1. Potential Side-Effect Bug (HIGH PRIORITY)

Location: exponentiation_operator.rs:107-113, 122-186

Issue: The comment at line 130 acknowledges: "For simplicity, handle the basic case without temp variables. A more complete implementation would add temp variables to avoid side effects."

This is a potential correctness issue. The current implementation clones expressions (line 109-110) which causes side effects to execute multiple times:

// Input
obj[i++].prop **= 2;

// Current output (INCORRECT - evaluates i++ twice)
obj[i++].prop = Math.pow(obj[i++].prop, 2);

// Correct output (should use temp variables)
var _obj = obj[i++];
_obj.prop = Math.pow(_obj.prop, 2);

Old implementation: The removed code had similar issues based on the diff, with commented-out test at lines 95-104 showing this case was known to be problematic.

Recommendation:

  • Either: Implement proper temp variable injection using the StatementInjectorStore system
  • Or: Document this limitation clearly and ensure tests explicitly mark these cases as ignore with explanatory comments
  • The ignored test babel_comprehensive:61-63 likely fails due to this issue

2. Statement Injector Not Used

Location: exponentiation_operator.rs:48

The transform receives _ctx: &mut TraverseCtx but never uses it. The new StatementInjectorStore infrastructure was added but the exponentiation operator doesn't leverage it. For member expression assignments with side effects, you should:

// Example approach:
let temp_var = self.ctx.generate_uid("ref");
self.ctx.statement_injector.insert_before(address, 
    create_var_decl(temp_var.clone(), obj));

3. Incomplete Pattern Matching

Location: exponentiation_operator.rs:115, 184

The _ => {} catch-all patterns silently ignore:

  • MemberProp::PrivateName (line 184)
  • Other AssignTarget variants like AssignTarget::Pat (line 115)

Recommendation: Add explicit handling or at minimum, warning logs using the tracing crate for unhandled cases.

4. DUMMY_SP Used Throughout

Location: Multiple locations (96, 143, 159, etc.)

Using DUMMY_SP loses source location information, making error messages and source maps less useful. Consider preserving the original span from the input expression.

5. SyntaxContext::empty() May Break Hygiene

Location: exponentiation_operator.rs:192, 198

Using SyntaxContext::empty() for Math and pow identifiers could cause issues if the user code has variables named Math or shadows the global Math:

// Edge case that could break:
const Math = { pow: () => 0 };
let x = 2 ** 3; // Should use global Math.pow, not the local Math

Recommendation: Use the unresolved_mark or a properly scoped context. Check how other transforms handle global references.

6. Dependency Direction Concern

Location: Cargo.toml changes

swc_ecma_compat_es2016 now depends on swc_ecma_transformer, which seems architecturally backwards. Typically, the higher-level transformer would depend on compat layers, not vice versa. This creates potential for circular dependencies and complicates the dependency graph.

Current: compat_es2016transformer → (uses) es2016::Options
Alternative: compat_es2016 should remain independent, with preset_env orchestrating both

7. Missing rustdoc Comments

Location: statement_injector.rs

Per CLAUDE.md rule #7: "Write documentation for your code." The public methods lack rustdoc comments:

  • StmtInjector::default()
  • Individual methods in StmtInjectorStore have comments, but could use examples

🔍 Minor Issues

  1. Performance consideration: Cloning Box<Expr> at lines 109-110 involves heap allocation. For performance-critical code, consider whether this can be avoided.

  2. Code organization: The create_math_pow function (190-219) could potentially be shared with other transforms that need to inject calls.

  3. Test marked as ok_if_code_eq (exponentiation.rs:92, 111, 128): These tests only check if code is valid, not if output is correct. Consider proper output validation.

🧪 Testing

Current: Tests exist but several are marked as ignore (lines 42, 71)

Recommendation:

  • Run cargo test -p swc_ecma_compat_es2016 to verify all non-ignored tests pass
  • Add a specific test for BigInt exponentiation to ensure it's NOT transformed
  • Consider adding tests for the edge cases mentioned above

📋 Checklist from CLAUDE.md

  • ✅ Performance-focused (Rule 1)
  • ✅ English comments/docs (Rule 2)
  • ✅ No nightly features (Rule 3)
  • ✅ Uses Cow<str> for Atoms (Rule 4) - uses .into() which creates Cow when needed
  • ⚠️ Unit tests exist but coverage incomplete (Rule 5)
  • ✅ Tests not removed (Rule 6)
  • ⚠️ Documentation good but could be more complete (Rule 7)
  • ❓ Need to run cargo fmt --all before merge (Rule 8)

🎯 Recommendations

Must Fix (Blocking)

  1. Either properly implement temp variables for member expressions with side effects, OR explicitly document the limitation and mark affected tests appropriately
  2. Address the SyntaxContext::empty() hygiene issue

Should Fix

  1. Use original spans instead of DUMMY_SP where possible
  2. Handle or document all pattern matching cases explicitly
  3. Run cargo fmt --all

Nice to Have

  1. Reconsider the dependency direction between compat_es2016 and transformer
  2. Add more comprehensive tests for edge cases

Summary

This is a solid refactoring that moves the codebase toward a more performant single-pass architecture. However, there's a potential correctness issue with side effects in member expressions that needs to be addressed before merge. The code quality is generally good, with nice documentation and clean structure.

Recommendation: Request changes to address the side-effect handling issue and hygiene concerns before merging.

@claude
Copy link
Contributor

claude bot commented Nov 20, 2025

Pull Request Review

Overview

This PR refactors the exponentiation operator transformation by moving it from into a new unified transformer architecture (). The implementation shows good architectural improvements but has several critical issues that need to be addressed.


Critical Issues

1. Incorrect Side-Effect Handling (Major Bug)

Location: crates/swc_ecma_transformer/src/es2016/exponentiation_operator.rs:106-186

The current implementation duplicates property accesses and function calls, causing side effects to execute multiple times:

// Input
array[++i] **= 2

// Current (incorrect) output - evaluates ++i multiple times
array[++i] = Math.pow(array[++i], 2)

// Expected output - evaluates ++i only once
var _ref = ++i;
array[_ref] = Math.pow(array[_ref], 2)

Impact: This is a critical correctness bug. The test snapshots show this is intentional, but it's semantically incorrect according to the ES2016 spec. The old implementation in the diff appears to have attempted to handle this with temporary variables.

Evidence from test snapshots:

  • emitCompoundExponentiationAssignmentWithIndexingOnLHS1.1.normal.js shows array[++i] = Math.pow(array[++i], 2) which evaluates ++i twice
  • emitCompoundExponentiationAssignmentWithPropertyAccessingOnLHS1.1.normal.js shows foo().prop = Math.pow(foo().prop, 2) which calls foo() twice

Recommendation: Implement proper memoization using temporary variables for:

  • Member expressions with computed properties
  • Call expressions that return objects
  • Any expression with potential side effects

The old implementation had code for this (lines using ref_ident and private_ident!) that was removed. This logic needs to be restored and properly integrated.


2. Unsafe Pointer Usage

Location: crates/swc_ecma_transformer/src/common/statement_injector.rs:88

let address = stmt as *const Stmt as usize;

Issue: Using raw pointer addresses as HashMap keys is inherently unsafe and unreliable:

  • Pointers can be invalidated when the Vec is reallocated
  • No guarantee that addresses remain stable during AST transformations
  • May cause memory safety issues or logic errors

Recommendation: Use a more robust addressing scheme:

  1. Use swc_ecma_visit's AstNodePath or path-based addressing
  2. Generate unique IDs during a pre-pass
  3. Use Rust's TypeId combined with AST node metadata

Code Quality Issues

3. Incomplete Implementation

Location: crates/swc_ecma_transformer/src/es2016/exponentiation_operator.rs:129-130

// For simplicity, handle the basic case without temp variables
// A more complete implementation would add temp variables to avoid side effects

This comment acknowledges the side-effect problem but doesn't address it. This is insufficient for a production compiler.


4. Dead Code

Location: crates/swc_ecma_transformer/src/common/statement_injector.rs

The entire StmtInjectorStore infrastructure is added but never actually used by the exponentiation operator implementation. The exponentiation pass doesn't call:

  • insert_before()
  • insert_after()
  • insert_many_after()

Question: Is this infrastructure intended for future use, or was it meant to be used in this PR but got left incomplete?


5. Inconsistent DUMMY_SP Usage

Throughout exponentiation_operator.rs, DUMMY_SP is used for all span information, losing source location data. While this follows a pattern in the codebase, it makes debugging harder. Consider preserving original spans where possible.


6. Missing Test for Side Effects

The ignored test babel_memoize_object (line 74-85 in exponentiation.rs) explicitly tests that side effects should only occur once:

reader.x **= 2;
expect(counters).toBe(1); // Should only evaluate 'reader' once

This test being ignored is a red flag that the implementation doesn't handle this correctly.


Positive Aspects

  1. Good documentation - Clear module-level docs with examples and references
  2. BigInt handling - Correctly avoids transforming BigInt exponentiation (lines 52-55, 64-65)
  3. Architectural improvement - Moving to unified transformer is the right direction
  4. Test snapshot updates - All expected test outputs are properly updated

Performance Considerations

The refactoring aligns with the project goal (per CLAUDE.md: "Write performant code"). However:

  1. Regression risk: The simpler implementation may be faster but at the cost of correctness
  2. Missing the old parallel processing: The old implementation used #[parallel(explode)] and ParExplode - was this intentionally removed? If so, document why.

Recommendations

Must Fix (Blocking)

  1. Implement proper side-effect handling with temporary variables for expressions with side effects
  2. Replace pointer-based addressing in StmtInjector with a safe alternative
  3. Document or remove the StmtInjectorStore if it's not being used

Should Fix

  1. Add unit tests specifically for side-effect scenarios
  2. Enable and fix the babel_memoize_object test
  3. Preserve source spans where possible instead of using DUMMY_SP

Nice to Have

  1. Document why parallel processing was removed (if intentional)
  2. Add inline code examples showing the transformation in doc comments

Security & Safety

No security vulnerabilities identified, but the pointer casting is unsafe and could lead to undefined behavior.


Conclusion

This PR makes good architectural progress but has a critical correctness bug in side-effect handling that makes it unsuitable for merging as-is. The exponentiation operator implementation needs to properly memoize expressions to avoid evaluating them multiple times.

The test snapshots appear to codify incorrect behavior - they should be updated once the implementation is fixed to use temporary variables appropriately.

Recommendation: Request changes to address the side-effect handling before merging.

@claude
Copy link
Contributor

claude bot commented Nov 20, 2025

Pull Request Review

This PR refactors the exponentiation operator transformation by merging it into a new unified transformer architecture. Here's my review:

✅ Strengths

  1. Good Architecture: The new hook-based architecture with swc_ecma_transformer is clean and follows good separation of concerns.

  2. Well-Documented Code: Excellent documentation in exponentiation_operator.rs with clear examples and references to Babel implementation.

  3. Performance Optimization: The transformation now generates more efficient code by avoiding unnecessary temporary variables when possible:

    • x3.a **= value now generates x3.a = Math.pow(x3.a, value) instead of creating ref variable
    • Only creates temp vars when needed to avoid side effects
  4. Test Coverage: The PR updates all test snapshots and maintains existing test cases.

⚠️ Issues Found

1. CRITICAL: Pointer-Based Statement Address (Safety Concern)

Location: crates/swc_ecma_transformer/src/common/statement_injector.rs:88

let address = stmt as *const Stmt as usize;

Issue: Using raw pointer addresses as HashMap keys is unsafe and problematic:

  • Memory safety: Pointers may become invalid after AST transformations, mutations, or reallocations
  • Undefined behavior: Comparing or using pointer addresses after the pointed-to memory is moved/dropped is UB
  • Fragility: Will break if statements are cloned, moved, or restructured

Recommendation: Use a more robust identification strategy:

  • Use swc_ecma_visit's path-based addressing
  • Generate unique IDs during traversal
  • Use spans with unique IDs
  • Reference by index within parent container

2. Missing Variable Declaration in Test Output

Location: Multiple test snapshot files

The transformed code uses _prop and _ref variables without declaring them:

// Current output:
_prop = ++i0, array0[_prop] = Math.pow(array0[_prop], 2);

// Should be:
var _prop;
_prop = ++i0, array0[_prop] = Math.pow(array0[_prop], 2);

Issue: This will cause ReferenceError at runtime. The temp variables are used but never declared with var, let, or const.

Recommendation: The exponentiation transform should inject variable declarations, likely using the statement injector.

3. CI Failures

The PR has failing CI checks:

  • ❌ Cargo clippy (failed)
  • ❌ Cargo shear (failed)

Recommendation: Fix clippy warnings and unused dependency issues before merging.

4. Statement Injector Design Concern

The StmtInjectorStore is created but I don't see it being used in the exponentiation transform. The transform generates sequence expressions instead.

Questions:

  • Is the statement injector needed for this specific transform?
  • If not used, should it be removed from this PR?
  • If it will be used, ensure it properly handles variable hoisting

📋 Recommendations

Must Fix Before Merge:

  1. Fix the pointer-based addressing in statement_injector.rs - this is a safety issue
  2. Add proper variable declarations for generated temp vars (_prop, _ref)
  3. Resolve CI failures (clippy + cargo shear)

Nice to Have:

  1. Add unit tests specifically for the new statement_injector utility
  2. Consider adding more complex test cases (nested exponentiation with side effects)
  3. Document the relationship between statement injector and the exponentiation transform

🎯 Code Quality Assessment

Following CLAUDE.md guidelines:

  • ✅ Performance-focused implementation
  • ✅ Good English documentation
  • ✅ No unstable features used
  • ❌ Missing unit tests for new utilities
  • ✅ Follows existing code patterns
  • ⚠️ Safety concerns with raw pointers

Overall Verdict

The refactoring direction is good and the code quality is generally high, but there are critical issues that must be addressed before merging:

  1. The pointer-based addressing is unsafe
  2. Missing variable declarations will cause runtime errors
  3. CI must pass

The performance improvements in the generated code are excellent and the new architecture is promising.

@socket-security
Copy link

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
Obfuscated code: npm safer-buffer is 94.0% likely obfuscated

Confidence: 0.94

Location: Package overview

From: ?npm/[email protected]

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/[email protected]. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@claude
Copy link
Contributor

claude bot commented Nov 20, 2025

Code Review for PR #11310: Merge exponentiation_operator

This PR refactors the exponentiation operator transformation by moving it from swc_ecma_compat_es2016 to a new unified transformer architecture in swc_ecma_transformer. Here's my detailed review:

✅ Strengths

1. Architecture Improvement

  • The new single-pass transformer architecture is a significant improvement over the old multi-pass approach
  • Consolidating transforms into swc_ecma_transformer provides better performance through reduced AST traversals
  • The hook-based design is clean and composable

2. Code Quality

  • Excellent documentation with comprehensive examples and references (crates/swc_ecma_transformer/src/es2016/exponentiation_operator.rs:1-33)
  • Clear separation of concerns with dedicated utility functions
  • Good use of pattern matching and Rust idioms

3. Correctness - Side Effect Handling

  • The implementation correctly handles side effects by caching object/property expressions in temporary variables
  • Example: foo()[0] **= 2 is correctly transformed to (_ref = foo(), _ref[0] = Math.pow(_ref[0], 2)) to prevent multiple function calls
  • This matches Babel's behavior and is crucial for correctness

4. Test Coverage

  • Test snapshots show improved output with fewer unnecessary temporary variables
  • The transformation now generates cleaner code (e.g., x3.a = Math.pow(x3.a, value) instead of creating ref variable for simple property access)

🔍 Issues & Concerns

1. CRITICAL: Missing Variable Declarations in Test Output

The minified test outputs show undefined variables being used:

// crates/swc/tests/tsc-references/emitCompoundExponentiationAssignmentWithIndexingOnLHS1.2.minified.js:6
array0[_prop = ++i0] = Math.pow(array0[_prop], 2);

The variable _prop is used but never declared! This appears in multiple test files. The old implementation correctly generated var ref = ... declarations. The new implementation seems to be missing the variable declaration step.

Action Required: The StmtInjectorStore infrastructure exists but I don't see where temporary variable declarations are being injected. You need to:

  • Call ctx.statement_injector.insert_before() to add var _prop; declarations
  • Or wrap in an IIFE with proper variable declarations

2. Performance Consideration: Unnecessary Sequence Expressions

In transform_member_exp_assign_impl (crates/swc_ecma_transformer/src/es2016/exponentiation_operator.rs:125-262), you create sequence expressions even when only one temp variable is needed:

if needs_obj_temp || needs_prop_temp {
    sequence_exprs.push(assignment);
    *expr = Expr::Seq(SeqExpr { ... });
}

However, when !needs_obj_temp && needs_prop_temp, you still create a sequence expression. This could be simplified.

3. Minor: Literal Check Could Be More Precise

The is_literal_expr function (line 266) considers Ident as "literal":

fn is_literal_expr(expr: &Expr) -> bool {
    matches!(expr, Expr::Lit(_) | Expr::Ident(_) | ...)
}

While safe to re-evaluate, identifiers aren't truly "literals". The function name is slightly misleading. Consider renaming to is_pure_expr or is_safe_to_duplicate.

4. BigInt Handling

Good: You correctly skip BigInt transformation (lines 53, 64)
However: The check only looks at the immediate expression, not nested BigInt operations. This is likely fine but worth noting.

5. Missing Unit Tests

While integration tests exist in swc_ecma_compat_es2016, I don't see unit tests for the new implementation in swc_ecma_transformer/src/es2016/. Per CLAUDE.md #5: "Write unit tests for your code."

📋 Recommendations

High Priority:

  1. Fix the undefined variable issue - This is a correctness bug that will break generated code
  2. Add proper variable declarations using the statement injector or IIFE wrapper

Medium Priority:
3. Add unit tests for the new exponentiation_operator module
4. Consider renaming is_literal_expr to better reflect its purpose
5. Run cargo fmt --all (per CLAUDE.md #8) - though CI should catch this

Low Priority:
6. Optimize sequence expression generation to avoid unnecessary wrapping
7. Add inline comments explaining the side-effect handling strategy

🎯 Verdict

This is a well-architected refactoring that improves code organization and performance. The core transformation logic is sound and handles edge cases well. However, the undefined variable issue in test outputs is a blocker that must be resolved before merging.

The cleaner output (fewer unnecessary temp variables) is a nice improvement, but we need to ensure the necessary temp variables are properly declared.

Overall: Good work on the refactoring! Please address the variable declaration issue and this will be ready to merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants