diff --git a/crates/oxc_transformer/src/es2022/class_properties/constructor.rs b/crates/oxc_transformer/src/es2022/class_properties/constructor.rs index 8f9e435983a7c..d539430f5b496 100644 --- a/crates/oxc_transformer/src/es2022/class_properties/constructor.rs +++ b/crates/oxc_transformer/src/es2022/class_properties/constructor.rs @@ -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); @@ -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; diff --git a/tasks/transform_conformance/snapshots/oxc.snap.md b/tasks/transform_conformance/snapshots/oxc.snap.md index be90da50ff6d6..a9701c2113ace 100644 --- a/tasks/transform_conformance/snapshots/oxc.snap.md +++ b/tasks/transform_conformance/snapshots/oxc.snap.md @@ -1,6 +1,6 @@ commit: acbc09a8 -Passed: 130/152 +Passed: 131/153 # All Passed: * babel-plugin-transform-class-static-block @@ -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 diff --git a/tasks/transform_conformance/snapshots/oxc_exec.snap.md b/tasks/transform_conformance/snapshots/oxc_exec.snap.md index 1106f853202cf..733dc043ca312 100644 --- a/tasks/transform_conformance/snapshots/oxc_exec.snap.md +++ b/tasks/transform_conformance/snapshots/oxc_exec.snap.md @@ -2,7 +2,7 @@ commit: acbc09a8 node: v22.12.0 -Passed: 4 of 6 (66.67%) +Passed: 5 of 7 (71.43%) Failures: diff --git a/tasks/transform_conformance/tests/babel-plugin-transform-class-properties/test/fixtures/super-in-constructor-nested-super/exec.js b/tasks/transform_conformance/tests/babel-plugin-transform-class-properties/test/fixtures/super-in-constructor-nested-super/exec.js new file mode 100644 index 0000000000000..ecb7c7537407d --- /dev/null +++ b/tasks/transform_conformance/tests/babel-plugin-transform-class-properties/test/fixtures/super-in-constructor-nested-super/exec.js @@ -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); diff --git a/tasks/transform_conformance/tests/babel-plugin-transform-class-properties/test/fixtures/super-in-constructor-nested-super/input.js b/tasks/transform_conformance/tests/babel-plugin-transform-class-properties/test/fixtures/super-in-constructor-nested-super/input.js new file mode 100644 index 0000000000000..9b83e120cd6e8 --- /dev/null +++ b/tasks/transform_conformance/tests/babel-plugin-transform-class-properties/test/fixtures/super-in-constructor-nested-super/input.js @@ -0,0 +1,10 @@ +let c; + +class S {} + +class C extends S { + prop = 123; + constructor() { + super(c = super()); + } +} diff --git a/tasks/transform_conformance/tests/babel-plugin-transform-class-properties/test/fixtures/super-in-constructor-nested-super/output.js b/tasks/transform_conformance/tests/babel-plugin-transform-class-properties/test/fixtures/super-in-constructor-nested-super/output.js new file mode 100644 index 0000000000000..848a6b9689c18 --- /dev/null +++ b/tasks/transform_conformance/tests/babel-plugin-transform-class-properties/test/fixtures/super-in-constructor-nested-super/output.js @@ -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()); + } +}