oxc_transformer/es2022/class_properties/
private_method.rs1use oxc_allocator::TakeIn;
5use oxc_ast::ast::*;
6use oxc_ast_visit::{VisitMut, walk_mut};
7use oxc_semantic::ScopeFlags;
8use oxc_span::SPAN;
9use oxc_traverse::TraverseCtx;
10
11use crate::Helper;
12
13use super::{
14 ClassProperties,
15 super_converter::{ClassPropertiesSuperConverter, ClassPropertiesSuperConverterMode},
16};
17
18impl<'a> ClassProperties<'a, '_> {
19 pub(super) fn convert_private_method(
41 &mut self,
42 method: &mut MethodDefinition<'a>,
43 ctx: &mut TraverseCtx<'a>,
44 ) -> Option<Statement<'a>> {
45 let MethodDefinition { key, value, span, kind, r#static, .. } = method;
46 let PropertyKey::PrivateIdentifier(ident) = &key else {
47 return None;
48 };
49
50 let mut function = value.take_in_box(ctx.ast.allocator);
51
52 let resolved_private_prop = if *kind == MethodDefinitionKind::Set {
53 self.classes_stack.find_writeable_private_prop(ident)
54 } else {
55 self.classes_stack.find_readable_private_prop(ident)
56 };
57 let temp_binding = resolved_private_prop.unwrap().prop_binding;
58
59 function.span = *span;
60 function.id = Some(temp_binding.create_binding_identifier(ctx));
61 function.r#type = FunctionType::FunctionDeclaration;
62
63 let scope_id = function.scope_id();
66 let new_parent_id = ctx.current_scope_id();
67 ctx.scoping_mut().change_scope_parent_id(scope_id, Some(new_parent_id));
68 let is_strict_mode = ctx.current_scope_flags().is_strict_mode();
69 let flags = ctx.scoping_mut().scope_flags_mut(scope_id);
70 *flags -= ScopeFlags::GetAccessor | ScopeFlags::SetAccessor;
71 if !is_strict_mode {
72 *flags -= ScopeFlags::StrictMode;
75 }
76
77 PrivateMethodVisitor::new(*r#static, self, ctx)
78 .visit_function(&mut function, ScopeFlags::Function);
79
80 Some(Statement::FunctionDeclaration(function))
81 }
82
83 pub(super) fn create_class_private_method_init_spec(
85 &self,
86 ctx: &mut TraverseCtx<'a>,
87 ) -> Expression<'a> {
88 let brand = self.classes_stack.last().bindings.brand.as_ref().unwrap();
89 let arguments = ctx.ast.vec_from_array([
90 Argument::from(ctx.ast.expression_this(SPAN)),
91 Argument::from(brand.create_read_expression(ctx)),
92 ]);
93 self.ctx.helper_call_expr(Helper::ClassPrivateMethodInitSpec, SPAN, arguments, ctx)
94 }
95}
96
97struct PrivateMethodVisitor<'a, 'ctx, 'v> {
105 super_converter: ClassPropertiesSuperConverter<'a, 'ctx, 'v>,
106 ctx: &'v mut TraverseCtx<'a>,
108}
109
110impl<'a, 'ctx, 'v> PrivateMethodVisitor<'a, 'ctx, 'v> {
111 fn new(
112 is_static: bool,
113 class_properties: &'v mut ClassProperties<'a, 'ctx>,
114 ctx: &'v mut TraverseCtx<'a>,
115 ) -> Self {
116 let mode = if is_static {
117 ClassPropertiesSuperConverterMode::StaticPrivateMethod
118 } else {
119 ClassPropertiesSuperConverterMode::PrivateMethod
120 };
121 Self { super_converter: ClassPropertiesSuperConverter::new(mode, class_properties), ctx }
122 }
123}
124
125impl<'a> VisitMut<'a> for PrivateMethodVisitor<'a, '_, '_> {
126 #[inline]
127 fn visit_expression(&mut self, expr: &mut Expression<'a>) {
128 match expr {
129 Expression::StaticMemberExpression(_) => {
131 self.super_converter.transform_static_member_expression(expr, self.ctx);
132 }
133 Expression::ComputedMemberExpression(_) => {
135 self.super_converter.transform_computed_member_expression(expr, self.ctx);
136 }
137 Expression::CallExpression(call_expr) => {
139 self.super_converter
140 .transform_call_expression_for_super_member_expr(call_expr, self.ctx);
141 }
142 Expression::AssignmentExpression(_) => {
144 self.super_converter
145 .transform_assignment_expression_for_super_assignment_target(expr, self.ctx);
146 }
147 Expression::UpdateExpression(_) => {
149 self.super_converter
150 .transform_update_expression_for_super_assignment_target(expr, self.ctx);
151 }
152 _ => {}
153 }
154 walk_mut::walk_expression(self, expr);
155 }
156
157 fn visit_identifier_reference(&mut self, ident: &mut IdentifierReference<'a>) {
159 self.super_converter.class_properties.replace_class_name_with_temp_var(ident, self.ctx);
160 }
161
162 #[inline]
163 fn visit_class(&mut self, _class: &mut Class<'a>) {
164 }
173}