Skip to content

Commit

Permalink
fix(transformer/class-properties): do not transform super.prop in n…
Browse files Browse the repository at this point in the history
…ested method within static prop initializer (#7978)

Don't transform `super` in static property initializers if it's nested in another method, so is a *different* `super`.

```js
class C {
  static prop = () => {
    const object = {
      method() {
        // `super` here refers to prototype of `object`, not class `C`
        return super.foo;
      }
    };
  };
}
```
  • Loading branch information
overlookmotel committed Dec 18, 2024
1 parent 15b9bff commit bb38065
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -202,20 +202,19 @@ impl<'a, 'ctx, 'v> VisitMut<'a> for StaticInitializerVisitor<'a, 'ctx, 'v> {
}
// `super.prop`
Expression::StaticMemberExpression(_) => {
self.class_properties.transform_static_member_expression(expr, self.ctx);
self.transform_static_member_expression_if_super(expr);
}
// `super[prop]`
Expression::ComputedMemberExpression(_) => {
self.class_properties.transform_computed_member_expression(expr, self.ctx);
self.transform_computed_member_expression_if_super(expr);
}
// `object.#prop`
Expression::PrivateFieldExpression(_) => {
self.class_properties.transform_private_field_expression(expr, self.ctx);
}
// `super.prop()` or `object.#prop()`
Expression::CallExpression(call_expr) => {
self.class_properties
.transform_call_expression_for_super_member_expr(call_expr, self.ctx);
self.transform_call_expression_if_super_member_expression(call_expr);
self.class_properties.transform_call_expression(expr, self.ctx);
}
// `object.#prop = value`, `object.#prop += value`, `object.#prop ??= value` etc
Expand Down Expand Up @@ -516,4 +515,32 @@ impl<'a, 'ctx, 'v> StaticInitializerVisitor<'a, 'ctx, 'v> {
self.ctx.scopes_mut().change_parent_id(scope_id, Some(current_scope_id));
}
}

// `#[inline]` into visitor to keep common path where member expression isn't `super.prop` fast
#[inline]
fn transform_static_member_expression_if_super(&mut self, expr: &mut Expression<'a>) {
if self.this_depth == 0 {
self.class_properties.transform_static_member_expression(expr, self.ctx);
}
}

// `#[inline]` into visitor to keep common path where member expression isn't `super.prop` fast
#[inline]
fn transform_computed_member_expression_if_super(&mut self, expr: &mut Expression<'a>) {
if self.this_depth == 0 {
self.class_properties.transform_computed_member_expression(expr, self.ctx);
}
}

// `#[inline]` into visitor to keep common path where call expression isn't `super.prop()` fast
#[inline]
fn transform_call_expression_if_super_member_expression(
&mut self,
call_expr: &mut CallExpression<'a>,
) {
if self.this_depth == 0 {
self.class_properties
.transform_call_expression_for_super_member_expr(call_expr, self.ctx);
}
}
}
4 changes: 2 additions & 2 deletions tasks/transform_conformance/snapshots/oxc.snap.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
commit: 54a8389f

Passed: 111/125
Passed: 112/126

# All Passed:
* babel-plugin-transform-class-static-block
Expand All @@ -16,7 +16,7 @@ Passed: 111/125
* regexp


# babel-plugin-transform-class-properties (12/14)
# babel-plugin-transform-class-properties (13/15)
* typescript/optional-call/input.ts
Symbol reference IDs mismatch for "X":
after transform: SymbolId(0): [ReferenceId(0), ReferenceId(2), ReferenceId(6), ReferenceId(11), ReferenceId(16)]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
class C {
static prop = () => {
// Transform
super.prop;
super[prop];
super.prop();
super[prop]();

const obj = {
method() {
// Don't transform
super.prop;
super[prop];
super.prop();
super[prop]();
}
};

class Inner {
method() {
// Don't transform
super.prop;
super[prop];
super.prop();
super[prop]();
}

static staticMethod() {
// Don't transform
super.prop;
super[prop];
super.prop();
super[prop]();
}
}
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
var _C;
class C {}
_C = C;
babelHelpers.defineProperty(C, "prop", () => {
// Transform
babelHelpers.superPropGet(_C, "prop", _C);
babelHelpers.superPropGet(_C, prop, _C);
babelHelpers.superPropGet(_C, "prop", _C, 2)([]);
babelHelpers.superPropGet(_C, prop, _C, 2)([]);

const obj = {
method() {
// Don't transform
super.prop;
super[prop];
super.prop();
super[prop]();
}
};

class Inner {
method() {
// Don't transform
super.prop;
super[prop];
super.prop();
super[prop]();
}

static staticMethod() {
// Don't transform
super.prop;
super[prop];
super.prop();
super[prop]();
}
}
});

0 comments on commit bb38065

Please sign in to comment.