Skip to content

Commit

Permalink
refactor(transformer/class-properties): move supers to super_converter
Browse files Browse the repository at this point in the history
  • Loading branch information
Dunqing committed Dec 28, 2024
1 parent 8fac581 commit c9eef21
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 23 deletions.
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)
}
}

0 comments on commit c9eef21

Please sign in to comment.