Skip to content

Commit

Permalink
fix(transformer/class-properties): use UID for args in created clas…
Browse files Browse the repository at this point in the history
…s constructor (#7866)

When creating class constructor for a class which has super class, use UID `_args` for temp var (rather than `args`). This avoids shadowing a var called `args` used in an instance property initializer.

This diverges from Babel. Babel uses `args` unless it finds a var called `args` in an instance property initializer. But searching the AST of initializers can be fairly expensive, so it's better to skip it. The overrides for test fixtures included in this PR are just to account for that difference.
  • Loading branch information
overlookmotel committed Dec 14, 2024
1 parent 0b67b37 commit c0576fa
Show file tree
Hide file tree
Showing 14 changed files with 125 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -228,17 +228,12 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
let has_super_class = class.super_class.is_some();
let mut stmts = ctx.ast.vec_with_capacity(inits.len() + usize::from(has_super_class));

// Add `super(...args);` statement and `...args` param if class has a super class.
// `constructor(...args) { super(...args); /* prop initialization */ }`
// TODO: One of initializers could access a var called `args` from outer scope.
// Use a UID `_args` instead of `args` here.
// Add `super(..._args);` statement and `..._args` param if class has a super class.
// `constructor(..._args) { super(..._args); /* prop initialization */ }`
let mut params_rest = None;
if has_super_class {
let args_binding = ctx.generate_binding(
Atom::from("args"),
constructor_scope_id,
SymbolFlags::FunctionScopedVariable,
);
let args_binding =
ctx.generate_uid("args", constructor_scope_id, SymbolFlags::FunctionScopedVariable);
params_rest = Some(
ctx.ast.alloc_binding_rest_element(SPAN, args_binding.create_binding_pattern(ctx)),
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class A extends B {
constructor(..._args) {
super(..._args);
babelHelpers.defineProperty(this, "foo", super.bar);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class Foo extends Bar {
constructor(..._args) {
super(..._args);
this.bar = "foo";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class A {
foo() {
return "bar";
}
}
class B extends A {
constructor(..._args) {
super(..._args);
this.foo = super.foo();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
var _prop = babelHelpers.classPrivateFieldLooseKey("prop");
class Foo {
constructor() {
Object.defineProperty(this, _prop, {
writable: true,
value: "foo"
});
}
}
var _prop2 = babelHelpers.classPrivateFieldLooseKey("prop");
class Bar extends Foo {
constructor(..._args) {
super(..._args);
Object.defineProperty(this, _prop2, {
writable: true,
value: "bar"
});
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
var _foo = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("foo");
var _foo = babelHelpers.classPrivateFieldLooseKey("foo");
class Foo {
constructor() {
Object.defineProperty(this, _foo, {
Expand All @@ -9,8 +9,8 @@ class Foo {
test() {
var _foo3;
let _this$foo;
var _foo2 = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("foo");
class Nested extends (_foo3 = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("foo"), _this$foo = babelHelpers.classPrivateFieldLooseBase(this, _foo3)[_foo3], class {
var _foo2 = babelHelpers.classPrivateFieldLooseKey("foo");
class Nested extends (_foo3 = babelHelpers.classPrivateFieldLooseKey("foo"), _this$foo = babelHelpers.classPrivateFieldLooseBase(this, _foo3)[_foo3], class {
constructor() {
Object.defineProperty(this, _foo3, {
writable: true,
Expand All @@ -19,8 +19,8 @@ class Foo {
this[_this$foo] = 2;
}
}) {
constructor(...args) {
super(...args);
constructor(..._args) {
super(..._args);
Object.defineProperty(this, _foo2, {
writable: true,
value: 3
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
var _prop = new WeakMap();
class Foo {
constructor() {
babelHelpers.classPrivateFieldInitSpec(this, _prop, "foo");
}
}
var _prop2 = new WeakMap();
class Bar extends Foo {
constructor(..._args) {
super(..._args);
babelHelpers.classPrivateFieldInitSpec(this, _prop2, "bar");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class A {
foo() {
return "bar";
}
}
var _foo = new WeakMap();
class B extends A {
constructor(..._args) {
super(..._args);
babelHelpers.classPrivateFieldInitSpec(this, _foo, super.foo());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class Foo extends Bar {
constructor(..._args) {
super(..._args);
this.bar = "foo";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class A {
foo() {
return "bar";
}
}
class B extends A {
constructor(..._args) {
super(..._args);
this.foo = super.foo();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class Foo extends Bar {
constructor(..._args) {
super(..._args);
babelHelpers.defineProperty(this, "bar", "foo");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class A {
foo() {
return "bar";
}
}
class B extends A {
constructor(..._args) {
super(..._args);
babelHelpers.defineProperty(this, "foo", super.foo());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class Test {
constructor() {
var _Other;
class Other extends Test {
constructor(..._args) {
super(..._args);
babelHelpers.defineProperty(this, "a", () => super.test);
}
}
_Other = Other;
babelHelpers.defineProperty(Other, "a", () => babelHelpers.superPropGet(_Other, "test", _Other));
}
}
7 changes: 2 additions & 5 deletions tasks/transform_conformance/snapshots/babel.snap.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
commit: 54a8389f

Passed: 581/927
Passed: 582/927

# All Passed:
* babel-plugin-transform-class-static-block
Expand Down Expand Up @@ -276,7 +276,7 @@ x Output mismatch
x Output mismatch


# babel-plugin-transform-class-properties (193/264)
# babel-plugin-transform-class-properties (194/264)
* assumption-constantSuper/complex-super-class/input.js
x Output mismatch

Expand Down Expand Up @@ -499,9 +499,6 @@ x Output mismatch
* regression/6153/input.js
x Output mismatch

* regression/7951/input.mjs
x Output mismatch


# babel-plugin-transform-nullish-coalescing-operator (5/12)
* assumption-noDocumentAll/transform/input.js
Expand Down

0 comments on commit c0576fa

Please sign in to comment.