mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
refactor(transformer/class-properties): move supers to super_converter (#8103)
Move to a separate struct, and then we can use it in other places. See #8106
This commit is contained in:
parent
58ed83242a
commit
d82fb52fa5
3 changed files with 62 additions and 23 deletions
|
|
@ -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.
|
||||
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -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>,
|
||||
}
|
||||
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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 };
|
||||
|
||||
|
|
@ -527,7 +540,7 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -535,7 +548,7 @@ impl<'a, 'ctx, 'v> StaticVisitor<'a, 'ctx, 'v> {
|
|||
#[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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)`
|
||||
|
|
@ -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`
|
||||
|
|
@ -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`)
|
||||
|
|
@ -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)`
|
||||
|
|
@ -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));
|
||||
|
|
@ -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)`
|
||||
|
|
@ -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),
|
||||
|
|
@ -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…
Reference in a new issue