From 49cc2a420a84cfe65e7c0359e1089677804d79f7 Mon Sep 17 00:00:00 2001 From: Dunqing Date: Wed, 27 Nov 2024 17:16:46 +0800 Subject: [PATCH] refactor(transformer/class-properties) move transform logic of callee of CallExpression to transform_private_field_callee --- .../src/es2022/class_properties/private.rs | 48 ++++++++++++++----- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/crates/oxc_transformer/src/es2022/class_properties/private.rs b/crates/oxc_transformer/src/es2022/class_properties/private.rs index 9d2d08e3c5907d..88de9e933e6c43 100644 --- a/crates/oxc_transformer/src/es2022/class_properties/private.rs +++ b/crates/oxc_transformer/src/es2022/class_properties/private.rs @@ -144,15 +144,49 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> { let Expression::PrivateFieldExpression(field_expr) = &mut call_expr.callee else { unreachable!() }; + + let Some((callee, object)) = self.transform_private_field_callee(field_expr, ctx) else { + return; + }; + + // Substitute `.call` as callee of call expression + call_expr.callee = Expression::from(ctx.ast.member_expression_static( + SPAN, + callee, + ctx.ast.identifier_name(SPAN, Atom::from("call")), + false, + )); + // Add `object` to call arguments + call_expr.arguments.insert(0, Argument::from(object)); + } + + /// Transform [`CallExpression::callee`] or [`TaggedTemplateExpression::tag`] that is a private field. + /// + /// Return two expressions for `callee` and `object`, respectively. + /// + /// * this.#method + /// callee: `_classPrivateFieldGet(_method, this)` + /// object: `this` + /// + /// * this.obj.#method + /// callee: `_classPrivateFieldGet(_method, _this$obj = this.obj);` + /// object: `_this$obj` + fn transform_private_field_callee( + &mut self, + field_expr: &mut PrivateFieldExpression<'a>, + ctx: &mut TraverseCtx<'a>, + ) -> Option<(Expression<'a>, Expression<'a>)> { let prop_details = self.lookup_private_property(&field_expr.field); // TODO: Should never be `None` - only because implementation is incomplete. - let Some((prop, class_name_binding, is_declaration)) = prop_details else { return }; + let Some((prop, class_name_binding, is_declaration)) = prop_details else { + return None; + }; let prop_ident = prop.binding.create_read_expression(ctx); let object = ctx.ast.move_expression(&mut field_expr.object); // Get replacement for callee - let (callee, object) = if prop.is_static { + let replacement = if prop.is_static { // TODO: If `object` is reference to class name, and class is declaration, use shortcut `_prop._.call(Class)`. // TODO(improve-on-babel): No reason not to apply these shortcuts for class expressions too. @@ -197,15 +231,7 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> { (get_call, object2) }; - // Substitute `.call` as callee of call expression - call_expr.callee = Expression::from(ctx.ast.member_expression_static( - SPAN, - callee, - ctx.ast.identifier_name(SPAN, Atom::from("call")), - false, - )); - // Add `object` to call arguments - call_expr.arguments.insert(0, Argument::from(object)); + Some(replacement) } /// Transform assignment to private field.