Skip to content

Commit

Permalink
refactor(traverse): add methods to BoundIdentifier to create `Expre…
Browse files Browse the repository at this point in the history
…ssion::Identifier`s
  • Loading branch information
overlookmotel committed Oct 7, 2024
1 parent a1e0d30 commit 0496882
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 61 deletions.
26 changes: 11 additions & 15 deletions crates/oxc_transformer/src/es2016/exponentiation_operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ impl<'a, 'ctx> ExponentiationOperator<'a, 'ctx> {
ctx.create_unbound_reference_id(SPAN, ident.name.clone(), ReferenceFlags::Read),
);
let binding = self.create_temp_var(reference, &mut temp_var_inits, ctx);
ctx.ast.expression_from_identifier_reference(binding.create_read_reference(ctx))
binding.create_read_expression(ctx)
};

(pow_left, temp_var_inits)
Expand Down Expand Up @@ -345,10 +345,8 @@ impl<'a, 'ctx> ExponentiationOperator<'a, 'ctx> {
} else {
let owned_prop = ctx.ast.move_expression(prop);
let binding = self.create_temp_var(owned_prop, &mut temp_var_inits, ctx);
let mut create_ident =
|| ctx.ast.expression_from_identifier_reference(binding.create_read_reference(ctx));
*prop = create_ident();
create_ident()
*prop = binding.create_read_expression(ctx);
binding.create_read_expression(ctx)
};

// Complete 2nd member expression
Expand Down Expand Up @@ -434,10 +432,8 @@ impl<'a, 'ctx> ExponentiationOperator<'a, 'ctx> {
}

let binding = self.create_temp_var(ctx.ast.move_expression(obj), temp_var_inits, ctx);
let mut create_id =
|| ctx.ast.expression_from_identifier_reference(binding.create_read_reference(ctx));
*obj = create_id();
create_id()
*obj = binding.create_read_expression(ctx);
binding.create_read_expression(ctx)
}

/// `x **= right` -> `x = Math.pow(pow_left, right)` (with provided `pow_left`)
Expand Down Expand Up @@ -498,12 +494,12 @@ impl<'a, 'ctx> ExponentiationOperator<'a, 'ctx> {
self.ctx.var_declarations.insert(&binding, None, ctx);

// Add new reference `_name = name` to `temp_var_inits`
let left =
AssignmentTarget::from(ctx.ast.simple_assignment_target_from_identifier_reference(
binding.create_read_write_reference(ctx),
));
let op = AssignmentOperator::Assign;
temp_var_inits.push(ctx.ast.expression_assignment(SPAN, op, left, expr));
temp_var_inits.push(ctx.ast.expression_assignment(
SPAN,
AssignmentOperator::Assign,
binding.create_read_write_target(ctx),
expr,
));

binding
}
Expand Down
10 changes: 2 additions & 8 deletions crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,17 +91,11 @@ impl<'a, 'ctx> Traverse<'a> for NullishCoalescingOperator<'a, 'ctx> {
SymbolFlags::FunctionScopedVariable,
);

let left =
AssignmentTarget::from(ctx.ast.simple_assignment_target_from_identifier_reference(
binding.create_read_write_reference(ctx),
));

let reference =
ctx.ast.expression_from_identifier_reference(binding.create_read_reference(ctx));
let reference = binding.create_read_expression(ctx);
let assignment = ctx.ast.expression_assignment(
SPAN,
AssignmentOperator::Assign,
left,
binding.create_read_write_target(ctx),
logical_expr.left,
);
let mut new_expr =
Expand Down
39 changes: 9 additions & 30 deletions crates/oxc_transformer/src/es2021/logical_assignment_operators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,7 @@ impl<'a, 'ctx> LogicalAssignmentOperators<'a, 'ctx> {
if let Some(ident) = self.maybe_generate_memoised(&static_expr.object, ctx) {
// (_o = o).a
let right = ctx.ast.move_expression(&mut static_expr.object);
let target =
AssignmentTarget::from(ctx.ast.simple_assignment_target_from_identifier_reference(
ident.create_read_write_reference(ctx),
));
let target = ident.create_read_write_target(ctx);
let object =
ctx.ast.expression_assignment(SPAN, AssignmentOperator::Assign, target, right);
let left_expr = Expression::from(ctx.ast.member_expression_static(
Expand All @@ -169,7 +166,7 @@ impl<'a, 'ctx> LogicalAssignmentOperators<'a, 'ctx> {
// (_o.a = 1)
let assign_expr = ctx.ast.member_expression_static(
SPAN,
ctx.ast.expression_from_identifier_reference(ident.create_read_reference(ctx)),
ident.create_read_expression(ctx),
static_expr.property.clone_in(ctx.ast.allocator),
false,
);
Expand Down Expand Up @@ -218,10 +215,7 @@ impl<'a, 'ctx> LogicalAssignmentOperators<'a, 'ctx> {
if let Some(ident) = self.maybe_generate_memoised(&computed_expr.object, ctx) {
// (_o = object)
let right = ctx.ast.move_expression(&mut computed_expr.object);
let target =
AssignmentTarget::from(ctx.ast.simple_assignment_target_from_identifier_reference(
ident.create_read_write_reference(ctx),
));
let target = ident.create_read_write_target(ctx);
let object =
ctx.ast.expression_assignment(SPAN, AssignmentOperator::Assign, target, right);

Expand All @@ -230,30 +224,22 @@ impl<'a, 'ctx> LogicalAssignmentOperators<'a, 'ctx> {
// _b = expression
let property = self.maybe_generate_memoised(&expression, ctx);

if let Some(ref property) = property {
let left = AssignmentTarget::from(
ctx.ast.simple_assignment_target_from_identifier_reference(
property.create_read_write_reference(ctx),
),
);
if let Some(property) = &property {
expression = ctx.ast.expression_assignment(
SPAN,
AssignmentOperator::Assign,
left,
property.create_read_write_target(ctx),
expression,
);
}

// _o[_b]
let assign_target = AssignmentTarget::from(ctx.ast.member_expression_computed(
SPAN,
ctx.ast.expression_from_identifier_reference(ident.create_read_reference(ctx)),
ident.create_read_expression(ctx),
property.map_or_else(
|| expression.clone_in(ctx.ast.allocator),
|ident| {
ctx.ast
.expression_from_identifier_reference(ident.create_read_reference(ctx))
},
|ident| ident.create_read_expression(ctx),
),
false,
));
Expand All @@ -278,15 +264,10 @@ impl<'a, 'ctx> LogicalAssignmentOperators<'a, 'ctx> {
{
// _key = ++key
if let Some(property_ident) = &property_ident {
let left = AssignmentTarget::from(
ctx.ast.simple_assignment_target_from_identifier_reference(
property_ident.create_read_write_reference(ctx),
),
);
ctx.ast.expression_assignment(
SPAN,
AssignmentOperator::Assign,
left,
property_ident.create_read_write_target(ctx),
ctx.ast.move_expression(&mut expression),
)
} else {
Expand All @@ -306,9 +287,7 @@ impl<'a, 'ctx> LogicalAssignmentOperators<'a, 'ctx> {
object,
{
if let Some(property_ident) = property_ident {
ctx.ast.expression_from_identifier_reference(
property_ident.create_read_reference(ctx),
)
property_ident.create_read_expression(ctx)
} else {
expression
}
Expand Down
3 changes: 1 addition & 2 deletions crates/oxc_transformer/src/react/jsx_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,7 @@ impl<'a, 'ctx> ReactJsxSource<'a, 'ctx> {

let filename = {
let key = ctx.ast.property_key_identifier_name(SPAN, "fileName");
let ident = self.get_filename_var(ctx).create_read_reference(ctx);
let value = ctx.ast.expression_from_identifier_reference(ident);
let value = self.get_filename_var(ctx).create_read_expression(ctx);
ctx.ast.object_property_kind_object_property(
SPAN, kind, key, value, None, false, false, false,
)
Expand Down
4 changes: 1 addition & 3 deletions crates/oxc_transformer/src/react/refresh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -469,9 +469,7 @@ impl<'a, 'ctx> ReactRefresh<'a, 'ctx> {
) -> AssignmentTarget<'a> {
let binding = ctx.generate_uid_in_root_scope("c", SymbolFlags::FunctionScopedVariable);
self.registrations.push((binding.symbol_id, persistent_id));
let ident = binding.create_reference(reference_flags, ctx);
let ident = ctx.ast.simple_assignment_target_from_identifier_reference(ident);
ctx.ast.assignment_target_simple(ident)
binding.create_target(reference_flags, ctx)
}

/// Similar to the `findInnerComponents` function in `react-refresh/babel`.
Expand Down
126 changes: 123 additions & 3 deletions crates/oxc_traverse/src/context/bound_identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use oxc_ast::{
ast::{BindingIdentifier, BindingPattern, IdentifierReference},
ast::{AssignmentTarget, BindingIdentifier, BindingPattern, Expression, IdentifierReference},
NONE,
};
use oxc_span::{Atom, Span, SPAN};
Expand Down Expand Up @@ -58,11 +58,18 @@ impl<'a> BoundIdentifier<'a> {
ctx.ast.binding_pattern(binding_pattern_kind, NONE, false)
}

// --- Read only ---

/// Create `IdentifierReference` referencing this binding, which is read from, with dummy `Span`
pub fn create_read_reference(&self, ctx: &mut TraverseCtx<'a>) -> IdentifierReference<'a> {
self.create_spanned_read_reference(SPAN, ctx)
}

/// Create `Expression::Identifier` referencing this binding, which is read from, with dummy `Span`
pub fn create_read_expression(&self, ctx: &mut TraverseCtx<'a>) -> Expression<'a> {
self.create_spanned_read_expression(SPAN, ctx)
}

/// Create `IdentifierReference` referencing this binding, which is read from, with specified `Span`
pub fn create_spanned_read_reference(
&self,
Expand All @@ -72,12 +79,32 @@ impl<'a> BoundIdentifier<'a> {
self.create_spanned_reference(span, ReferenceFlags::Read, ctx)
}

/// Create `Expression::Identifier` referencing this binding, which is read from, with specified `Span`
pub fn create_spanned_read_expression(
&self,
span: Span,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
self.create_spanned_expression(span, ReferenceFlags::Read, ctx)
}

// --- Write only ---

/// Create `IdentifierReference` referencing this binding, which is written to, with dummy `Span`
#[allow(unused)]
pub fn create_write_reference(&self, ctx: &mut TraverseCtx<'a>) -> IdentifierReference<'a> {
self.create_spanned_write_reference(SPAN, ctx)
}

/// Create `Expression::Identifier` referencing this binding, which is written to, with dummy `Span`
pub fn create_write_expression(&self, ctx: &mut TraverseCtx<'a>) -> Expression<'a> {
self.create_spanned_write_expression(SPAN, ctx)
}

/// Create `AssignmentTarget` referencing this binding, which is written to, with dummy `Span`
pub fn create_write_target(&self, ctx: &mut TraverseCtx<'a>) -> AssignmentTarget<'a> {
self.create_spanned_write_target(SPAN, ctx)
}

/// Create `IdentifierReference` referencing this binding, which is written to, with specified `Span`
pub fn create_spanned_write_reference(
&self,
Expand All @@ -87,16 +114,47 @@ impl<'a> BoundIdentifier<'a> {
self.create_spanned_reference(span, ReferenceFlags::Write, ctx)
}

/// Create `Expression::Identifier` referencing this binding, which is written to, with specified `Span`
pub fn create_spanned_write_expression(
&self,
span: Span,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
self.create_spanned_expression(span, ReferenceFlags::Write, ctx)
}

/// Create `AssignmentTarget` referencing this binding, which is written to, with specified `Span`
pub fn create_spanned_write_target(
&self,
span: Span,
ctx: &mut TraverseCtx<'a>,
) -> AssignmentTarget<'a> {
self.create_spanned_target(span, ReferenceFlags::Write, ctx)
}

// --- Read and write ---

/// Create `IdentifierReference` referencing this binding, which is read from + written to,
/// with dummy `Span`
#[allow(unused)]
pub fn create_read_write_reference(
&self,
ctx: &mut TraverseCtx<'a>,
) -> IdentifierReference<'a> {
self.create_spanned_read_write_reference(SPAN, ctx)
}

/// Create `Expression::Identifier` referencing this binding, which is read from + written to,
/// with dummy `Span`
pub fn create_read_write_expression(&self, ctx: &mut TraverseCtx<'a>) -> Expression<'a> {
self.create_spanned_read_write_expression(SPAN, ctx)
}

/// Create `AssignmentTarget` referencing this binding, which is read from + written to,
/// with dummy `Span`
pub fn create_read_write_target(&self, ctx: &mut TraverseCtx<'a>) -> AssignmentTarget<'a> {
self.create_spanned_read_write_target(SPAN, ctx)
}

/// Create `IdentifierReference` referencing this binding, which is read from + written to,
/// with specified `Span`
pub fn create_spanned_read_write_reference(
Expand All @@ -107,6 +165,28 @@ impl<'a> BoundIdentifier<'a> {
self.create_spanned_reference(span, ReferenceFlags::Read | ReferenceFlags::Write, ctx)
}

/// Create `Expression::Identifier` referencing this binding, which is read from + written to,
/// with specified `Span`
pub fn create_spanned_read_write_expression(
&self,
span: Span,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
self.create_spanned_expression(span, ReferenceFlags::Read | ReferenceFlags::Write, ctx)
}

/// Create `AssignmentTarget` referencing this binding, which is read from + written to,
/// with specified `Span`
pub fn create_spanned_read_write_target(
&self,
span: Span,
ctx: &mut TraverseCtx<'a>,
) -> AssignmentTarget<'a> {
self.create_spanned_target(span, ReferenceFlags::Read | ReferenceFlags::Write, ctx)
}

// --- Specified ReferenceFlags ---

/// Create `IdentifierReference` referencing this binding, with specified `ReferenceFlags`
pub fn create_reference(
&self,
Expand All @@ -116,6 +196,24 @@ impl<'a> BoundIdentifier<'a> {
self.create_spanned_reference(SPAN, flags, ctx)
}

/// Create `Expression::Identifier` referencing this binding, with specified `ReferenceFlags`
pub fn create_expression(
&self,
flags: ReferenceFlags,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
self.create_spanned_expression(SPAN, flags, ctx)
}

/// Create `AssignmentTarget` referencing this binding, with specified `ReferenceFlags`
pub fn create_target(
&self,
flags: ReferenceFlags,
ctx: &mut TraverseCtx<'a>,
) -> AssignmentTarget<'a> {
self.create_spanned_target(SPAN, flags, ctx)
}

/// Create `IdentifierReference` referencing this binding, with specified `Span` and `ReferenceFlags`
pub fn create_spanned_reference(
&self,
Expand All @@ -125,4 +223,26 @@ impl<'a> BoundIdentifier<'a> {
) -> IdentifierReference<'a> {
ctx.create_bound_reference_id(span, self.name.clone(), self.symbol_id, flags)
}

/// Create `Expression::Identifier` referencing this binding, with specified `Span` and `ReferenceFlags`
pub fn create_spanned_expression(
&self,
span: Span,
flags: ReferenceFlags,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
let ident = self.create_spanned_reference(span, flags, ctx);
ctx.ast.expression_from_identifier_reference(ident)
}

/// Create `Expression::Identifier` referencing this binding, with specified `Span` and `ReferenceFlags`
pub fn create_spanned_target(
&self,
span: Span,
flags: ReferenceFlags,
ctx: &mut TraverseCtx<'a>,
) -> AssignmentTarget<'a> {
let ident = self.create_spanned_reference(span, flags, ctx);
AssignmentTarget::from(ctx.ast.simple_assignment_target_from_identifier_reference(ident))
}
}

0 comments on commit 0496882

Please sign in to comment.