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

refactor(transformer/class-properties): move supers to super_converter #8103

Draft
wants to merge 1 commit into
base: 12-25-feat_transformer_class-properties_transform_private_field_expression_which_refers_to_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
6 changes: 3 additions & 3 deletions crates/oxc_transformer/src/es2022/class_properties/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@
//! * `static_block_and_prop_init.rs`: Transform of static property initializers and static blocks.
//! * `computed_key.rs`: Transform of property/method computed keys.
//! * `private_field.rs`: Transform of private fields (`this.#prop`).
//! * `private_method.rs`: Transform of private methods (`this.#method()`).
//! * `super.rs`: Transform `super` expressions.
//! * `private_method.rs`: Transform of private methods (`this.#method()`).
//! * `super_converter.rs`: Transform `super` expressions.
//! * `class_details.rs`: Structures containing details of classes and private properties.
//! * `class_bindings.rs`: Structure containing bindings for class name and temp var.
//! * `utils.rs`: Utility functions.
Expand Down Expand Up @@ -218,7 +218,7 @@ mod private_field;
mod private_method;
mod prop_decl;
mod static_block_and_prop_init;
mod supers;
mod super_converter;
mod utils;
use class_bindings::ClassBindings;
use class_details::{ClassDetails, ClassesStack, PrivateProp, ResolvedPrivateProp};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ use oxc_syntax::scope::{ScopeFlags, ScopeId};
use oxc_traverse::TraverseCtx;

use super::super::ClassStaticBlock;
use super::ClassProperties;
use super::{
super_converter::{ClassPropertiesSuperConverter, ClassPropertiesSuperConverterMode},
ClassProperties,
};

impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
/// Transform static property initializer.
Expand Down Expand Up @@ -179,8 +182,8 @@ struct StaticVisitor<'a, 'ctx, 'v> {
/// the `ScopeId` of the old static block, so we don't need to reparent scopes anyway,
/// so `scope_depth` is ignored.
scope_depth: u32,
/// Main transform instance.
class_properties: &'v mut ClassProperties<'a, 'ctx>,
/// Converter for `super` expressions.
super_converter: ClassPropertiesSuperConverter<'a, 'ctx, 'v>,
/// `TraverseCtx` object.
ctx: &'v mut TraverseCtx<'a>,
}
Expand All @@ -200,7 +203,17 @@ impl<'a, 'ctx, 'v> StaticVisitor<'a, 'ctx, 'v> {
#[expect(clippy::bool_to_int_with_if)]
let scope_depth = if reparent_scopes { 0 } else { 1 };

Self { walk_deep, make_sloppy_mode, this_depth: 0, scope_depth, class_properties, ctx }
Self {
walk_deep,
make_sloppy_mode,
this_depth: 0,
scope_depth,
super_converter: ClassPropertiesSuperConverter::new(
ClassPropertiesSuperConverterMode::Static,
class_properties,
),
ctx,
}
}
}

Expand Down Expand Up @@ -476,7 +489,7 @@ impl<'a, 'ctx, 'v> StaticVisitor<'a, 'ctx, 'v> {
/// Replace `this` with reference to temp var for class.
fn replace_this_with_temp_var(&mut self, expr: &mut Expression<'a>, span: Span) {
if self.this_depth == 0 {
let class_details = self.class_properties.current_class_mut();
let class_details = self.super_converter.class_properties.current_class_mut();
let temp_binding = class_details.bindings.get_or_init_static_binding(self.ctx);
*expr = temp_binding.create_spanned_read_expression(span, self.ctx);
}
Expand All @@ -485,7 +498,7 @@ impl<'a, 'ctx, 'v> StaticVisitor<'a, 'ctx, 'v> {
/// Replace reference to class name with reference to temp var for class.
fn replace_class_name_with_temp_var(&mut self, ident: &mut IdentifierReference<'a>) {
// Check identifier is reference to class name
let class_details = self.class_properties.current_class_mut();
let class_details = self.super_converter.class_properties.current_class_mut();
let class_name_symbol_id = class_details.bindings.name_symbol_id();
let Some(class_name_symbol_id) = class_name_symbol_id else { return };

Expand Down Expand Up @@ -527,15 +540,15 @@ impl<'a, 'ctx, 'v> StaticVisitor<'a, 'ctx, 'v> {
#[inline]
fn transform_static_member_expression_if_super(&mut self, expr: &mut Expression<'a>) {
if self.this_depth == 0 {
self.class_properties.transform_static_member_expression(expr, self.ctx);
self.super_converter.transform_static_member_expression(expr, self.ctx);
}
}

// `#[inline]` into visitor to keep common path where member expression isn't `super.prop` fast
#[inline]
fn transform_computed_member_expression_if_super(&mut self, expr: &mut Expression<'a>) {
if self.this_depth == 0 {
self.class_properties.transform_computed_member_expression(expr, self.ctx);
self.super_converter.transform_computed_member_expression(expr, self.ctx);
}
}

Expand All @@ -546,7 +559,7 @@ impl<'a, 'ctx, 'v> StaticVisitor<'a, 'ctx, 'v> {
call_expr: &mut CallExpression<'a>,
) {
if self.this_depth == 0 {
self.class_properties
self.super_converter
.transform_call_expression_for_super_member_expr(call_expr, self.ctx);
}
}
Expand All @@ -559,7 +572,7 @@ impl<'a, 'ctx, 'v> StaticVisitor<'a, 'ctx, 'v> {
expr: &mut Expression<'a>,
) {
if self.this_depth == 0 {
self.class_properties
self.super_converter
.transform_assignment_expression_for_super_assignment_target(expr, self.ctx);
}
}
Expand All @@ -572,7 +585,7 @@ impl<'a, 'ctx, 'v> StaticVisitor<'a, 'ctx, 'v> {
expr: &mut Expression<'a>,
) {
if self.this_depth == 0 {
self.class_properties
self.super_converter
.transform_update_expression_for_super_assignment_target(expr, self.ctx);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,29 @@ use crate::Helper;

use super::{utils::create_assignment, ClassProperties};

impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
#[derive(Debug)]
pub(super) enum ClassPropertiesSuperConverterMode {
// `static prop` or `static {}`
Static,
}

/// Convert `super` expressions.
pub(super) struct ClassPropertiesSuperConverter<'a, 'ctx, 'v> {
#[expect(unused)]
mode: ClassPropertiesSuperConverterMode,
pub(super) class_properties: &'v mut ClassProperties<'a, 'ctx>,
}

impl<'a, 'ctx, 'v> ClassPropertiesSuperConverter<'a, 'ctx, 'v> {
pub(super) fn new(
mode: ClassPropertiesSuperConverterMode,
class_properties: &'v mut ClassProperties<'a, 'ctx>,
) -> Self {
Self { mode, class_properties }
}
}

impl<'a, 'ctx, 'v> ClassPropertiesSuperConverter<'a, 'ctx, 'v> {
/// Transform static member expression where object is `super`.
///
/// `super.prop` -> `_superPropGet(_Class, "prop", _Class)`
Expand Down Expand Up @@ -238,7 +260,7 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
self.create_super_prop_set(span, property, value, ctx)
} else {
// Make 2 copies of `object`
let (property1, property2) = self.duplicate_object(property, ctx);
let (property1, property2) = self.class_properties.duplicate_object(property, ctx);

if let Some(operator) = operator.to_binary_operator() {
// `super[prop] += value`
Expand Down Expand Up @@ -471,13 +493,14 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
// Make 2 copies of `property`
let (property1, property2) = self.duplicate_object(property, ctx);
let (property1, property2) = self.class_properties.duplicate_object(property, ctx);

// `_superPropGet(_Class, prop, _Class)`
let get_call = self.create_super_prop_get(SPAN, property2, false, ctx);

// `_super$prop = _superPropGet(_Class, prop, _Class)`
let temp_binding = self.ctx.var_declarations.create_uid_var(temp_var_name_base, ctx);
let temp_binding =
self.class_properties.ctx.var_declarations.create_uid_var(temp_var_name_base, ctx);
let assignment = create_assignment(&temp_binding, get_call, ctx);

// `++_super$prop` / `_super$prop++` (reusing existing `UpdateExpression`)
Expand All @@ -498,7 +521,8 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
} else {
// Source = `super.prop++` (postfix `++`)
// `_super$prop2 = _super$prop++`
let temp_binding2 = self.ctx.var_declarations.create_uid_var(temp_var_name_base, ctx);
let temp_binding2 =
self.class_properties.ctx.var_declarations.create_uid_var(temp_var_name_base, ctx);
let assignment2 = create_assignment(&temp_binding2, update_expr, ctx);

// `(_super$prop = _superPropGet(_Class, prop, _Class), _super$prop2 = _super$prop++, _super$prop)`
Expand Down Expand Up @@ -533,7 +557,8 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
is_callee: bool,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
let temp_binding = self.current_class_mut().bindings.get_or_init_static_binding(ctx);
let temp_binding =
self.class_properties.current_class_mut().bindings.get_or_init_static_binding(ctx);

let ident1 = Argument::from(temp_binding.create_read_expression(ctx));
let ident2 = Argument::from(temp_binding.create_read_expression(ctx));
Expand All @@ -549,7 +574,7 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
};

// `_superPropGet(_Class, prop, _Class)` or `_superPropGet(_Class, prop, _Class, 2)`
self.ctx.helper_call_expr(Helper::SuperPropGet, span, arguments, ctx)
self.class_properties.ctx.helper_call_expr(Helper::SuperPropGet, span, arguments, ctx)
}

/// `_superPropSet(_Class, prop, value, _Class, 1)`
Expand All @@ -560,7 +585,8 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
value: Expression<'a>,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
let temp_binding = self.current_class_mut().bindings.get_or_init_static_binding(ctx);
let temp_binding =
self.class_properties.current_class_mut().bindings.get_or_init_static_binding(ctx);
let arguments = ctx.ast.vec_from_array([
Argument::from(temp_binding.create_read_expression(ctx)),
Argument::from(property),
Expand All @@ -573,6 +599,6 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
NumberBase::Decimal,
)),
]);
self.ctx.helper_call_expr(Helper::SuperPropSet, span, arguments, ctx)
self.class_properties.ctx.helper_call_expr(Helper::SuperPropSet, span, arguments, ctx)
}
}
Loading