Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(transformer/class-properties): transform private field expression which invokes private method #8102

Draft
wants to merge 1 commit into
base: 12-25-feat_transformer_class-properties_transform_callee_that_is_referred_to_a_private_method
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions .typos.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ extend-exclude = [
"tasks/prettier_conformance/snapshots",
"tasks/transform_conformance/tests/**/output.js",
"tasks/transform_conformance/overrides",
"tasks/transform_conformance/snapshots",
"npm/oxc-wasm/oxc_wasm.js",
]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,18 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
is_declaration,
} = self.classes_stack.find_private_prop(&field_expr.field);

let span = field_expr.span;

if is_method || is_accessor {
return None;
let prop_ident = prop_binding.create_read_expression(ctx);
return if is_assignment {
// TODO: Handle assignment to private method or accessor
None
} else {
Some(self.create_assert_class_brand_for_private_method(prop_ident, span, ctx))
};
};

let span = field_expr.span;
let object = ctx.ast.move_expression(&mut field_expr.object);

if self.private_fields_as_properties {
Expand Down Expand Up @@ -268,11 +275,12 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
is_declaration,
} = self.classes_stack.find_private_prop(&field_expr.field);

let span = field_expr.span;
let prop_ident = prop_binding.create_read_expression(ctx);

if is_method || is_accessor {
return (
self.create_assert_class_brand_for_private_method(prop_ident, ctx),
self.create_assert_class_brand_for_private_method(prop_ident, span, ctx),
ctx.ast.expression_this(SPAN),
);
};
Expand Down Expand Up @@ -301,8 +309,7 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
.is_some()
{
// `_prop._`
let callee =
Self::create_underscore_member_expression(prop_ident, field_expr.span, ctx);
let callee = Self::create_underscore_member_expression(prop_ident, span, ctx);
(callee, object)
} else {
let class_binding = class_bindings.get_or_init_static_binding(ctx);
Expand All @@ -316,7 +323,7 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
class_ident,
object1,
prop_ident,
field_expr.span,
span,
ctx,
);
(assert_obj, object2)
Expand All @@ -327,7 +334,7 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
let (object1, object2) = self.duplicate_object(object, ctx);

// `_classPrivateFieldGet2(_prop, object)`
let get_call = self.create_private_field_get(prop_ident, object1, field_expr.span, ctx);
let get_call = self.create_private_field_get(prop_ident, object1, span, ctx);
(get_call, object2)
};

Expand Down Expand Up @@ -533,7 +540,8 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
// Replace right side of assignment with `_assertClassBrand(Class, object, _prop)`
// TODO: Ensure there are tests for nested classes with references to private static props
// of outer class inside inner class, to make sure we're getting the right `class_binding`.
assign_expr.right = self.create_assert_class_brand(class_ident, object, value, ctx);
assign_expr.right =
self.create_assert_class_brand(class_ident, object, value, SPAN, ctx);
} else {
let class_ident = class_binding.create_read_expression(ctx);
let value = ctx.ast.move_expression(&mut assign_expr.right);
Expand Down Expand Up @@ -563,7 +571,7 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
let value = ctx.ast.expression_binary(SPAN, get_expr, operator, value);
// `_assertClassBrand(Class, object, _assertClassBrand(Class, object, _prop)._ + value)`
assign_expr.right =
self.create_assert_class_brand(class_ident2, object1, value, ctx);
self.create_assert_class_brand(class_ident2, object1, value, SPAN, ctx);
} else if let Some(operator) = operator.to_logical_operator() {
// `object.#prop &&= value`
// -> `_assertClassBrand(Class, object, _prop)._ && (_prop._ = _assertClassBrand(Class, object, value))`
Expand All @@ -585,7 +593,7 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
assign_expr.span = SPAN;
assign_expr.operator = AssignmentOperator::Assign;
assign_expr.right =
self.create_assert_class_brand(class_ident2, object2, value, ctx);
self.create_assert_class_brand(class_ident2, object2, value, SPAN, ctx);
let right = ctx.ast.move_expression(expr);
// `_assertClassBrand(Class, object, _prop)._ && (_prop._ = _assertClassBrand(Class, object, value))`
*expr = ctx.ast.expression_logical(span, left, operator, right);
Expand Down Expand Up @@ -869,7 +877,7 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {

// If no shortcut, wrap in `_assertClassBrand(Class, object, <value>)`
if let Some(class_ident) = class_ident {
value = self.create_assert_class_brand(class_ident, object, value, ctx);
value = self.create_assert_class_brand(class_ident, object, value, SPAN, ctx);
}

// `_prop._ = <value>`
Expand Down Expand Up @@ -899,7 +907,7 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {

// If no shortcut, wrap in `_assertClassBrand(Class, object, <value>)`
if let Some(class_ident) = class_ident {
value = self.create_assert_class_brand(class_ident, object, value, ctx);
value = self.create_assert_class_brand(class_ident, object, value, SPAN, ctx);
}

// `_prop._ = <value>`
Expand Down Expand Up @@ -1772,11 +1780,12 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
class_ident: Expression<'a>,
object: Expression<'a>,
value_or_prop_ident: Expression<'a>,
span: Span,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
self.ctx.helper_call_expr(
Helper::AssertClassBrand,
SPAN,
span,
ctx.ast.vec_from_array([
Argument::from(class_ident),
Argument::from(object),
Expand All @@ -1791,11 +1800,12 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
fn create_assert_class_brand_for_private_method(
&self,
value_or_prop_ident: Expression<'a>,
span: Span,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
let class_ident = self.current_class().bindings.brand().create_read_expression(ctx);
let object = ctx.ast.expression_this(SPAN);
self.create_assert_class_brand(class_ident, object, value_or_prop_ident, ctx)
self.create_assert_class_brand(class_ident, object, value_or_prop_ident, span, ctx)
}

/// `_assertClassBrand(Class, object, _prop)._`
Expand All @@ -1807,7 +1817,7 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
span: Span,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
let func_call = self.create_assert_class_brand(class_ident, object, prop_ident, ctx);
let func_call = self.create_assert_class_brand(class_ident, object, prop_ident, SPAN, ctx);
Self::create_underscore_member_expression(func_call, span, ctx)
}

Expand Down
10 changes: 2 additions & 8 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: 628/1095
Passed: 630/1095

# All Passed:
* babel-plugin-transform-logical-assignment-operators
Expand Down Expand Up @@ -462,7 +462,7 @@ x Output mismatch
x Output mismatch


# babel-plugin-transform-private-methods (13/148)
# babel-plugin-transform-private-methods (15/148)
* accessors/arguments/input.js
x Output mismatch

Expand Down Expand Up @@ -571,15 +571,9 @@ x Output mismatch
* private-method/class-expression/input.js
x Output mismatch

* private-method/context/input.js
x Output mismatch

* private-method/destructuring/input.js
x Output mismatch

* private-method/exfiltrated/input.js
x Output mismatch

* private-method/read-only/input.js
x Output mismatch

Expand Down
Loading
Loading