Skip to content

Commit

Permalink
fix(transformer/class-properties): handle nested super() calls (#8506)
Browse files Browse the repository at this point in the history
Similar to #8494. Handle nested `super()` calls in class constructor e.g. `super(self = super())`. Very weird code, but legal!
  • Loading branch information
overlookmotel committed Jan 15, 2025
1 parent 7066d1c commit 356f0c1
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -639,9 +639,16 @@ impl<'a, 'ctx> ConstructorBodySuperReplacer<'a, 'ctx> {
if let Statement::ExpressionStatement(expr_stmt) = stmt {
if let Expression::CallExpression(call_expr) = &mut expr_stmt.expression {
if let Expression::Super(super_) = &call_expr.callee {
let span = super_.span;

// Visit arguments in `super(x, y, z)` call.
// Required to handle edge case `super(self = super())`.
self.visit_arguments(&mut call_expr.arguments);

// Found `super()` as top-level statement
if self.super_binding.is_none() {
// This is the first `super()` found.
// This is the first `super()` found
// (and no further `super()` calls within `super()` call's arguments).
// So can just insert initializers after it - no need for `_super` function.
let insert_location =
InstanceInitsInsertLocation::ExistingConstructor(index + 1);
Expand All @@ -652,7 +659,6 @@ impl<'a, 'ctx> ConstructorBodySuperReplacer<'a, 'ctx> {
// So we do need a `_super` function.
// But we don't need to look any further for any other `super()` calls,
// because calling `super()` after this would be an immediate error.
let span = super_.span;
self.replace_super(call_expr, span);

break 'outer;
Expand Down
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: acbc09a8

Passed: 130/152
Passed: 131/153

# All Passed:
* babel-plugin-transform-class-static-block
Expand All @@ -18,7 +18,7 @@ Passed: 130/152
* regexp


# babel-plugin-transform-class-properties (19/26)
# babel-plugin-transform-class-properties (20/27)
* private-field-resolve-to-method/input.js
x Output mismatch

Expand Down
2 changes: 1 addition & 1 deletion tasks/transform_conformance/snapshots/oxc_exec.snap.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ commit: acbc09a8

node: v22.12.0

Passed: 4 of 6 (66.67%)
Passed: 5 of 7 (71.43%)

Failures:

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
let c;

class S {}

class C extends S {
prop = 123;
constructor() {
super(c = super());
}
}

try { new C() } catch {}

expect(c).toBeInstanceOf(C);
expect(c.prop).toBe(123);
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
let c;

class S {}

class C extends S {
prop = 123;
constructor() {
super(c = super());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
let c;

class S {}

class C extends S {
constructor() {
var _super = (..._args) => (super(..._args), babelHelpers.defineProperty(this, "prop", 123), this);
_super(c = _super());
}
}

0 comments on commit 356f0c1

Please sign in to comment.