Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions crates/oxc_transformer/src/common/helper_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ pub enum Helper {
ClassPrivateFieldGet2,
ClassPrivateFieldSet2,
AssertClassBrand,
ToSetter,
}

impl Helper {
Expand All @@ -172,6 +173,7 @@ impl Helper {
Self::ClassPrivateFieldGet2 => "classPrivateFieldGet2",
Self::ClassPrivateFieldSet2 => "classPrivateFieldSet2",
Self::AssertClassBrand => "assertClassBrand",
Self::ToSetter => "toSetter",
}
}
}
Expand Down
46 changes: 37 additions & 9 deletions crates/oxc_transformer/src/es2022/class_properties/private.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,13 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
) {
let owned_expr = ctx.ast.move_expression(expr);
let Expression::PrivateFieldExpression(field_expr) = owned_expr else { unreachable!() };
*expr = self.transform_private_field_expression_impl(field_expr, ctx);
*expr = self.transform_private_field_expression_impl(field_expr, false, ctx);
}

fn transform_private_field_expression_impl(
&mut self,
field_expr: ArenaBox<'a, PrivateFieldExpression<'a>>,
is_assignment: bool,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
let prop_details = self.private_props_stack.find(&field_expr.field);
Expand Down Expand Up @@ -87,6 +88,9 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
ctx,
)
}
} else if is_assignment {
// `_toSetter(_classPrivateFieldSet2, [_prop, object])._`
self.create_to_setter(prop_ident, object, span, ctx)
} else {
// `_classPrivateFieldGet2(_prop, object)`
self.create_private_field_get(prop_ident, object, span, ctx)
Expand Down Expand Up @@ -1428,22 +1432,22 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
// `object.#prop` in assignment pattern.
// Must be in assignment pattern, as `enter_expression` already transformed `AssignmentExpression`s.
if matches!(target, AssignmentTarget::PrivateFieldExpression(_)) {
self.transform_assignment_target_impl(target, ctx);
*target = self.transform_assignment_target_impl(target, ctx);
}
}

#[expect(clippy::unused_self)]
fn transform_assignment_target_impl(
&mut self,
target: &mut AssignmentTarget<'a>,
_ctx: &mut TraverseCtx<'a>,
) {
let AssignmentTarget::PrivateFieldExpression(_private_field) = target else {
ctx: &mut TraverseCtx<'a>,
) -> AssignmentTarget<'a> {
let AssignmentTarget::PrivateFieldExpression(private_field) =
ctx.ast.move_assignment_target(target)
else {
unreachable!()
};

// TODO: `[object.#prop] = value`
// TODO: `({x: object.#prop} = value)`
let expr = self.transform_private_field_expression_impl(private_field, true, ctx);
AssignmentTarget::from(SimpleAssignmentTarget::from(expr.into_member_expression()))
}

/// Duplicate object to be used in get/set pair.
Expand Down Expand Up @@ -1571,6 +1575,30 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
)
}

/// `_toSetter(_classPrivateFieldSet2, [_prop, object])._`
fn create_to_setter(
&self,
prop_ident: Expression<'a>,
object: Expression<'a>,
span: Span,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
let arguments = ctx.ast.expression_array(
SPAN,
ctx.ast.vec_from_array([
ArrayExpressionElement::from(prop_ident),
ArrayExpressionElement::from(object),
]),
None,
);
let arguments = ctx.ast.vec_from_array([
Argument::from(self.ctx.helper_load(Helper::ClassPrivateFieldSet2, ctx)),
Argument::from(arguments),
]);
let call = self.ctx.helper_call_expr(Helper::ToSetter, span, arguments, ctx);
Self::create_underscore_member_expression(call, span, ctx)
}

/// `_assertClassBrand(Class, object, value)` or `_assertClassBrand(Class, object, _prop)`
fn create_assert_class_brand(
&self,
Expand Down
10 changes: 10 additions & 0 deletions crates/oxc_transformer/src/es2022/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,14 @@ impl<'a, 'ctx> Traverse<'a> for ES2022<'a, 'ctx> {
class_properties.exit_class(class, ctx);
}
}

fn enter_assignment_target(
&mut self,
node: &mut AssignmentTarget<'a>,
ctx: &mut TraverseCtx<'a>,
) {
if let Some(class_properties) = &mut self.class_properties {
class_properties.enter_assignment_target(node, ctx);
}
}
}
1 change: 1 addition & 0 deletions crates/oxc_transformer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ impl<'a, 'ctx> Traverse<'a> for TransformerImpl<'a, 'ctx> {
if let Some(typescript) = self.x0_typescript.as_mut() {
typescript.enter_assignment_target(node, ctx);
}
self.x2_es2022.enter_assignment_target(node, ctx);
}

fn enter_formal_parameters(
Expand Down
37 changes: 2 additions & 35 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: 416/846
Passed: 427/846

# 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 (89/264)
# babel-plugin-transform-class-properties (100/264)
* assumption-constantSuper/complex-super-class/input.js
x Output mismatch

Expand Down Expand Up @@ -412,9 +412,6 @@ x Output mismatch
* nested-class/super-property-in-decorator/input.js
x Output mismatch

* private/1-helpermemberexpressionfunction/input.js
x Output mismatch

* private/call/input.js
Scope children mismatch:
after transform: ScopeId(1): [ScopeId(2), ScopeId(3), ScopeId(4)]
Expand All @@ -435,36 +432,6 @@ x Output mismatch
* private/derived-multiple-supers/input.js
x Output mismatch

* private/destructuring-array-pattern/input.js
x Output mismatch

* private/destructuring-array-pattern-1/input.js
x Output mismatch

* private/destructuring-array-pattern-2/input.js
x Output mismatch

* private/destructuring-array-pattern-3/input.js
x Output mismatch

* private/destructuring-array-pattern-static/input.js
x Output mismatch

* private/destructuring-object-pattern/input.js
x Output mismatch

* private/destructuring-object-pattern-1/input.js
x Output mismatch

* private/destructuring-object-pattern-2/input.js
x Output mismatch

* private/destructuring-object-pattern-3/input.js
x Output mismatch

* private/destructuring-object-pattern-static/input.js
x Output mismatch

* private/extracted-this/input.js
x Output mismatch

Expand Down
Loading