feat(allocator)!: GetAllocator::allocator take &self (#23676)

Make `GetAllocator::allocator` method take `&self`, instead of `self`. Alter `TakeIn::take_in` accordingly - now takes `&A` where`A:GetAllocator` (previously took owned `A`).

This requires changing every `take_in` / `take_in_box` call site.

However, this change also means that `GetAllocator` can be implemented on all types which hold an `&Allocator` e.g. `TraverseCtx`, which shortens the code everywhere.

- Before: `expr.take_in(ctx.ast)`
- After: `expr.take_in(ctx)`

Change all those call sites to this shorter version.

This matches the pattern that new `AstBuilder` is going to introduce (#23043), and clears the way for that change.
This commit is contained in:
overlookmotel committed 2026-06-21 00:13:24 +00:00
1 parent bd74f9d35c
commit 36009ddf68
61 files changed
+436 -419

No files matched your search

+2 -2
View File
@@ -3,12 +3,12 @@ use crate::Allocator;
/// Accessor for getting the underlying allocator.
pub trait GetAllocator<'a> {
/// Get the underlying allocator.
fn allocator(self) -> &'a Allocator;
fn allocator(&self) -> &'a Allocator;
}
impl<'a> GetAllocator<'a> for &'a Allocator {
#[inline]
fn allocator(self) -> &'a Allocator {
fn allocator(&self) -> &'a Allocator {
self
}
}
+2 -2
View File
@@ -6,7 +6,7 @@ use crate::{Allocator, Box, GetAllocator, Vec};
pub trait TakeIn<'a>: Dummy<'a> {
/// Replace node with a dummy.
#[must_use]
fn take_in<A: GetAllocator<'a>>(&mut self, allocator_accessor: A) -> Self {
fn take_in<A: GetAllocator<'a>>(&mut self, allocator_accessor: &A) -> Self {
let allocator = allocator_accessor.allocator();
let dummy = Dummy::dummy(allocator);
mem::replace(self, dummy)
@@ -14,7 +14,7 @@ pub trait TakeIn<'a>: Dummy<'a> {
/// Replace node with a boxed dummy.
#[must_use]
fn take_in_box<A: GetAllocator<'a>>(&mut self, allocator_accessor: A) -> Box<'a, Self> {
fn take_in_box<A: GetAllocator<'a>>(&mut self, allocator_accessor: &A) -> Box<'a, Self> {
let allocator = allocator_accessor.allocator();
let dummy = Dummy::dummy(allocator);
Box::new_in(mem::replace(self, dummy), allocator)
+7 -7
View File
@@ -18,13 +18,6 @@ impl<'a, T> FromIn<'a, NONE> for Option<Box<'a, T>> {
}
}
impl<'a> GetAllocator<'a> for AstBuilder<'a> {
#[inline]
fn allocator(self) -> &'a Allocator {
self.allocator
}
}
/// AST builder for creating AST nodes.
#[derive(Clone, Copy)]
pub struct AstBuilder<'a> {
@@ -32,6 +25,13 @@ pub struct AstBuilder<'a> {
pub allocator: &'a Allocator,
}
impl<'a> GetAllocator<'a> for AstBuilder<'a> {
#[inline]
fn allocator(&self) -> &'a Allocator {
self.allocator
}
}
impl<'a> AstBuilder<'a> {
/// Create a new AST builder that will allocate nodes in the given allocator.
#[inline]
@@ -649,8 +649,7 @@ pub struct FormatMultilineChildren<'a> {
impl<'a> Format<'a, JsFormatContext<'a>> for FormatMultilineChildren<'a> {
fn fmt(&self, f: &mut JsFormatter<'_, 'a>) {
let format_inner = format_with(|f| {
if let Some(elements) = f.intern_vec(self.elements.borrow_mut().take_in(f.allocator()))
{
if let Some(elements) = f.intern_vec(self.elements.borrow_mut().take_in(f)) {
match self.layout {
MultilineLayout::Fill => f.write_elements([
FormatElement::Tag(Tag::StartFill),
@@ -747,7 +746,7 @@ pub struct FormatFlatChildren<'a> {
impl<'a> Format<'a, JsFormatContext<'a>> for FormatFlatChildren<'a> {
fn fmt(&self, f: &mut JsFormatter<'_, 'a>) {
if let Some(elements) = f.intern_vec(self.elements.borrow_mut().take_in(f.allocator())) {
if let Some(elements) = f.intern_vec(self.elements.borrow_mut().take_in(f)) {
f.write_element(elements);
}
}
+1 -1
View File
@@ -113,7 +113,7 @@ impl<'buf, 'ast, C> VecBuffer<'buf, 'ast, C> {
/// Takes the elements without consuming self
pub fn take_vec(&mut self) -> ArenaVec<'ast, FormatElement<'ast>> {
self.elements.take_in(self.state.allocator())
self.elements.take_in(self.state)
}
}
+8 -1
View File
@@ -1,6 +1,6 @@
#![allow(clippy::module_inception)]
use oxc_allocator::{Allocator, Vec as ArenaVec};
use oxc_allocator::{Allocator, GetAllocator, Vec as ArenaVec};
use crate::{
Argument, Arguments, Buffer, FormatContext, FormatElement, FormatState, VecBuffer,
@@ -121,3 +121,10 @@ impl<'ast, C> Buffer<'ast, C> for Formatter<'_, 'ast, C> {
self.buffer.replace_end(start, replacement);
}
}
impl<'ast, C> GetAllocator<'ast> for Formatter<'_, 'ast, C> {
#[inline]
fn allocator(&self) -> &'ast Allocator {
self.state().allocator()
}
}
+8 -1
View File
@@ -1,4 +1,4 @@
use oxc_allocator::Allocator;
use oxc_allocator::{Allocator, GetAllocator};
use rustc_hash::FxHashMap;
use crate::{GroupId, UniqueGroupIdBuilder, format_element::Interned};
@@ -70,3 +70,10 @@ impl<'ast, C> FormatState<'ast, C> {
&mut self.printed_interned_elements
}
}
impl<'ast, C> GetAllocator<'ast> for FormatState<'ast, C> {
#[inline]
fn allocator(&self) -> &'ast Allocator {
self.allocator
}
}
+8 -1
View File
@@ -9,7 +9,7 @@ use std::{cell::RefCell, iter::repeat_with, mem};
use rustc_hash::{FxHashMap, FxHashSet};
use oxc_allocator::{Allocator, CloneIn, Vec as ArenaVec};
use oxc_allocator::{Allocator, CloneIn, GetAllocator, Vec as ArenaVec};
use oxc_ast::{AstBuilder, NONE, ast::*};
use oxc_ast_visit::Visit;
use oxc_diagnostics::{Diagnostics, OxcDiagnostic};
@@ -637,3 +637,10 @@ impl<'a> IsolatedDeclarations<'a> {
!self.scope.is_ts_module_block()
}
}
impl<'a> GetAllocator<'a> for IsolatedDeclarations<'a> {
#[inline]
fn allocator(&self) -> &'a Allocator {
self.ast.allocator()
}
}
@@ -192,7 +192,7 @@ impl<'a> IsolatedDeclarations<'a> {
if let Statement::ExportNamedDeclaration(decl) = stmt
&& let Some(declaration) = &mut decl.declaration
{
*stmt = Statement::from(declaration.take_in(self.ast));
*stmt = Statement::from(declaration.take_in(self));
}
});
}
+1 -1
View File
@@ -562,7 +562,7 @@ impl Linter {
}
// `allocator` is a fixed-size allocator, so no need to clone AST into a new one
let tokens = ctx_host.parser_tokens_mut().take_in(allocator).into_arena_slice_mut();
let tokens = ctx_host.parser_tokens_mut().take_in(&allocator).into_arena_slice_mut();
// If file has a hashbang, add it to comments.
// It will be converted to a `Shebang` comment on JS side.
@@ -24,7 +24,7 @@ impl<'a> PeepholeOptimizations {
let property = ctx.ast.identifier_name(s.span, s.value);
let new_member = ctx.ast.alloc_static_member_expression(
e.span,
e.object.take_in(ctx.ast),
e.object.take_in(ctx),
property,
e.optional,
);
@@ -79,7 +79,7 @@ impl<'a> PeepholeOptimizations {
if has_optional {
ctx.notice_change();
} else {
let new_expr = Expression::from(e.expression.take_in(ctx.ast));
let new_expr = Expression::from(e.expression.take_in(ctx));
ctx.replace_expression(expr, new_expr);
}
}
@@ -130,7 +130,7 @@ impl<'a> PeepholeOptimizations {
if !lval && op.is_and() && is_cjs_module_exports_hint(&logical_expr.right) {
return None;
}
return Some(logical_expr.left.take_in(ctx.ast));
return Some(logical_expr.left.take_in(ctx));
} else if !left.may_have_side_effects(ctx) {
let should_keep_indirect_access =
Self::should_keep_indirect_access(&logical_expr.right, ctx);
@@ -145,19 +145,19 @@ impl<'a> PeepholeOptimizations {
None,
NumberBase::Decimal,
),
logical_expr.right.take_in(ctx.ast),
logical_expr.right.take_in(ctx),
]),
));
}
// (FALSE || x) => x
// (TRUE && x) => x
return Some(logical_expr.right.take_in(ctx.ast));
return Some(logical_expr.right.take_in(ctx));
}
// Left side may have side effects, but we know its boolean value.
// e.g. true_with_sideeffects || foo() => true_with_sideeffects, foo()
// or: false_with_sideeffects && foo() => false_with_sideeffects, foo()
let left = logical_expr.left.take_in(ctx.ast);
let right = logical_expr.right.take_in(ctx.ast);
let left = logical_expr.left.take_in(ctx);
let right = logical_expr.right.take_in(ctx);
let vec = ctx.ast.vec_from_array([left, right]);
let sequence_expr = ctx.ast.expression_sequence(logical_expr.span, vec);
return Some(sequence_expr);
@@ -174,8 +174,8 @@ impl<'a> PeepholeOptimizations {
if !right_boolean && left_child_op.is_or()
|| right_boolean && left_child_op.is_and()
{
let left = left_child.left.take_in(ctx.ast);
let right = logical_expr.right.take_in(ctx.ast);
let left = left_child.left.take_in(ctx);
let right = logical_expr.right.take_in(ctx);
let logic_expr =
ctx.ast.expression_logical(logical_expr.span, left, left_child_op, right);
return Some(logic_expr);
@@ -198,8 +198,8 @@ impl<'a> PeepholeOptimizations {
Some(if left.may_have_side_effects(ctx) {
// e.g. `(a(), null) ?? 1` => `(a(), null, 1)`
let expressions = ctx.ast.vec_from_array([
logical_expr.left.take_in(ctx.ast),
logical_expr.right.take_in(ctx.ast),
logical_expr.left.take_in(ctx),
logical_expr.right.take_in(ctx),
]);
ctx.ast.expression_sequence(logical_expr.span, expressions)
} else {
@@ -216,12 +216,12 @@ impl<'a> PeepholeOptimizations {
None,
NumberBase::Decimal,
),
logical_expr.right.take_in(ctx.ast),
logical_expr.right.take_in(ctx),
]),
));
}
// nullish condition => this expression evaluates to the right side.
logical_expr.right.take_in(ctx.ast)
logical_expr.right.take_in(ctx)
})
}
ValueType::Number
@@ -242,12 +242,12 @@ impl<'a> PeepholeOptimizations {
None,
NumberBase::Decimal,
),
logical_expr.left.take_in(ctx.ast),
logical_expr.left.take_in(ctx),
]),
));
}
// non-nullish condition => this expression evaluates to the left side.
Some(logical_expr.left.take_in(ctx.ast))
Some(logical_expr.left.take_in(ctx))
}
ValueType::Undetermined => None,
}
@@ -393,14 +393,14 @@ impl<'a> PeepholeOptimizations {
.unwrap_or(SPAN);
let value = ctx.ast.str_from_strs_array([&left_str, &right_str]);
let right = ctx.ast.expression_string_literal(span, value, None);
let left = left_binary_expr.left.take_in(ctx.ast);
let left = left_binary_expr.left.take_in(ctx);
return Some(ctx.ast.expression_binary(e.span, left, e.operator, right));
}
if let Some(new_right) =
Self::try_fold_add_op(&mut left_binary_expr.right, &mut e.right, e.span, ctx)
{
let left = left_binary_expr.left.take_in(ctx.ast);
let left = left_binary_expr.left.take_in(ctx);
return Some(ctx.ast.expression_binary(e.span, left, e.operator, new_right));
}
}
@@ -441,7 +441,7 @@ impl<'a> PeepholeOptimizations {
}
left.quasis.extend(right.quasis.drain(1..)); // first quasi is already handled
left.expressions.extend(right.expressions.drain(..));
return Some(left_expr.take_in(ctx.ast));
return Some(left_expr.take_in(ctx));
}
// "`${x}y` + 'z'" => "`${x}yz`"
@@ -457,7 +457,7 @@ impl<'a> PeepholeOptimizations {
.cooked
.map(|cooked| ctx.ast.str(&(cooked.as_str().to_string() + &right_str)));
last_quasi.value.cooked = new_cooked;
return Some(left_expr.take_in(ctx.ast));
return Some(left_expr.take_in(ctx));
}
} else if let Expression::TemplateLiteral(right) = right_expr {
// "'x' + `y${z}`" => "`xy${z}`"
@@ -475,17 +475,17 @@ impl<'a> PeepholeOptimizations {
.cooked
.map(|cooked| ctx.ast.str(&(left_str.into_owned() + cooked.as_str())));
first_quasi.value.cooked = new_cooked;
return Some(right_expr.take_in(ctx.ast));
return Some(right_expr.take_in(ctx));
}
}
// remove useless `+ ""` (e.g. `typeof foo + ""` -> `typeof foo`)
if Self::evaluates_to_empty_string(left_expr) && right_expr.value_type(ctx).is_string() {
return Some(right_expr.take_in(ctx.ast));
return Some(right_expr.take_in(ctx));
} else if Self::evaluates_to_empty_string(right_expr)
&& left_expr.value_type(ctx).is_string()
{
return Some(left_expr.take_in(ctx.ast));
return Some(left_expr.take_in(ctx));
}
None
@@ -527,7 +527,7 @@ impl<'a> PeepholeOptimizations {
Some(ctx.ast.expression_binary(
e.span,
expr_to_move.take_in(ctx.ast),
expr_to_move.take_in(ctx),
op,
ctx.value_to_expr(
left.right.span().merge_within(e.right.span(), e.span).unwrap_or(SPAN),
@@ -919,7 +919,7 @@ fn try_fold_at_optional<'a>(
match base.value_type(ctx) {
ValueType::Null | ValueType::Undefined => {
let base_has_side_effects = base.may_have_side_effects(ctx);
let taken = base.take_in(ctx.ast);
let taken = base.take_in(ctx);
Some(ChainFold::Collapse { base: taken, base_has_side_effects })
}
ValueType::Undetermined => None,
@@ -44,15 +44,15 @@ impl<'a> PeepholeOptimizations {
if sequence_expr.expressions.len() > 1 =>
{
let span = expr.span();
let mut sequence = expr.test.take_in(ctx.ast);
let mut sequence = expr.test.take_in(ctx);
let Expression::SequenceExpression(sequence_expr) = &mut sequence else {
unreachable!()
};
let expr = Self::minimize_conditional(
span,
sequence_expr.expressions.pop().unwrap(),
expr.consequent.take_in(ctx.ast),
expr.alternate.take_in(ctx.ast),
expr.consequent.take_in(ctx),
expr.alternate.take_in(ctx),
ctx,
);
sequence_expr.expressions.push(expr);
@@ -60,9 +60,9 @@ impl<'a> PeepholeOptimizations {
}
// "!a ? b : c" => "a ? c : b"
Expression::UnaryExpression(test_expr) if test_expr.operator.is_not() => {
let test = test_expr.argument.take_in(ctx.ast);
let consequent = expr.alternate.take_in(ctx.ast);
let alternate = expr.consequent.take_in(ctx.ast);
let test = test_expr.argument.take_in(ctx);
let consequent = expr.alternate.take_in(ctx);
let alternate = expr.consequent.take_in(ctx);
return Some(Self::minimize_conditional(
expr.span, test, consequent, alternate, ctx,
));
@@ -75,8 +75,8 @@ impl<'a> PeepholeOptimizations {
return Some(Self::join_with_left_associative_op(
expr.span,
LogicalOperator::Or,
expr.test.take_in(ctx.ast),
expr.alternate.take_in(ctx.ast),
expr.test.take_in(ctx),
expr.alternate.take_in(ctx),
ctx,
));
}
@@ -87,8 +87,8 @@ impl<'a> PeepholeOptimizations {
return Some(Self::join_with_left_associative_op(
expr.span,
LogicalOperator::And,
expr.test.take_in(ctx.ast),
expr.consequent.take_in(ctx.ast),
expr.test.take_in(ctx),
expr.consequent.take_in(ctx),
ctx,
));
}
@@ -100,9 +100,9 @@ impl<'a> PeepholeOptimizations {
BinaryOperator::Inequality | BinaryOperator::StrictInequality
) {
test_expr.operator = test_expr.operator.equality_inverse_operator().unwrap();
let test = expr.test.take_in(ctx.ast);
let consequent = expr.consequent.take_in(ctx.ast);
let alternate = expr.alternate.take_in(ctx.ast);
let test = expr.test.take_in(ctx);
let consequent = expr.consequent.take_in(ctx);
let alternate = expr.alternate.take_in(ctx);
return Some(Self::minimize_conditional(
expr.span, test, alternate, consequent, ctx,
));
@@ -120,12 +120,12 @@ impl<'a> PeepholeOptimizations {
Self::join_with_left_associative_op(
expr.test.span(),
LogicalOperator::And,
expr.test.take_in(ctx.ast),
consequent.test.take_in(ctx.ast),
expr.test.take_in(ctx),
consequent.test.take_in(ctx),
ctx,
),
consequent.consequent.take_in(ctx.ast),
consequent.alternate.take_in(ctx.ast),
consequent.consequent.take_in(ctx),
consequent.alternate.take_in(ctx),
));
}
@@ -138,12 +138,12 @@ impl<'a> PeepholeOptimizations {
Self::join_with_left_associative_op(
expr.test.span(),
LogicalOperator::Or,
expr.test.take_in(ctx.ast),
alternate.test.take_in(ctx.ast),
expr.test.take_in(ctx),
alternate.test.take_in(ctx),
ctx,
),
expr.consequent.take_in(ctx.ast),
alternate.alternate.take_in(ctx.ast),
expr.consequent.take_in(ctx),
alternate.alternate.take_in(ctx),
));
}
@@ -158,11 +158,11 @@ impl<'a> PeepholeOptimizations {
Self::join_with_left_associative_op(
expr.test.span(),
LogicalOperator::Or,
expr.test.take_in(ctx.ast),
alternate.expressions[0].take_in(ctx.ast),
expr.test.take_in(ctx),
alternate.expressions[0].take_in(ctx),
ctx,
),
expr.consequent.take_in(ctx.ast),
expr.consequent.take_in(ctx),
]),
));
}
@@ -178,11 +178,11 @@ impl<'a> PeepholeOptimizations {
Self::join_with_left_associative_op(
expr.test.span(),
LogicalOperator::And,
expr.test.take_in(ctx.ast),
consequent.expressions[0].take_in(ctx.ast),
expr.test.take_in(ctx),
consequent.expressions[0].take_in(ctx),
ctx,
),
expr.alternate.take_in(ctx.ast),
expr.alternate.take_in(ctx),
]),
));
}
@@ -197,12 +197,12 @@ impl<'a> PeepholeOptimizations {
Self::join_with_left_associative_op(
expr.test.span(),
LogicalOperator::And,
expr.test.take_in(ctx.ast),
logical_expr.left.take_in(ctx.ast),
expr.test.take_in(ctx),
logical_expr.left.take_in(ctx),
ctx,
),
LogicalOperator::Or,
expr.alternate.take_in(ctx.ast),
expr.alternate.take_in(ctx),
));
}
@@ -216,12 +216,12 @@ impl<'a> PeepholeOptimizations {
Self::join_with_left_associative_op(
expr.test.span(),
LogicalOperator::Or,
expr.test.take_in(ctx.ast),
logical_expr.left.take_in(ctx.ast),
expr.test.take_in(ctx),
logical_expr.left.take_in(ctx),
ctx,
),
LogicalOperator::And,
expr.consequent.take_in(ctx.ast),
expr.consequent.take_in(ctx),
));
}
@@ -249,25 +249,25 @@ impl<'a> PeepholeOptimizations {
if matches!(consequent.arguments[0], Argument::SpreadElement(_))
&& matches!(alternate.arguments[0], Argument::SpreadElement(_))
{
let callee = consequent.callee.take_in(ctx.ast);
let callee = consequent.callee.take_in(ctx);
let consequent_first_arg = {
let Argument::SpreadElement(el) = &mut consequent.arguments[0] else {
unreachable!()
};
el.argument.take_in(ctx.ast)
el.argument.take_in(ctx)
};
let alternate_first_arg = {
let Argument::SpreadElement(el) = &mut alternate.arguments[0] else {
unreachable!()
};
el.argument.take_in(ctx.ast)
el.argument.take_in(ctx)
};
let mut args = std::mem::replace(&mut consequent.arguments, ctx.ast.vec());
args[0] = ctx.ast.argument_spread_element(
expr.span,
ctx.ast.expression_conditional(
expr.test.span(),
expr.test.take_in(ctx.ast),
expr.test.take_in(ctx),
consequent_first_arg,
alternate_first_arg,
),
@@ -278,16 +278,16 @@ impl<'a> PeepholeOptimizations {
if !matches!(consequent.arguments[0], Argument::SpreadElement(_))
&& !matches!(alternate.arguments[0], Argument::SpreadElement(_))
{
let callee = consequent.callee.take_in(ctx.ast);
let callee = consequent.callee.take_in(ctx);
let consequent_first_arg =
consequent.arguments[0].to_expression_mut().take_in(ctx.ast);
consequent.arguments[0].to_expression_mut().take_in(ctx);
let alternate_first_arg =
alternate.arguments[0].to_expression_mut().take_in(ctx.ast);
alternate.arguments[0].to_expression_mut().take_in(ctx);
let mut args = std::mem::replace(&mut consequent.arguments, ctx.ast.vec());
let cond_expr = Self::minimize_conditional(
expr.test.span(),
expr.test.take_in(ctx.ast),
expr.test.take_in(ctx),
consequent_first_arg,
alternate_first_arg,
ctx,
@@ -344,12 +344,12 @@ impl<'a> PeepholeOptimizations {
if maybe_same_id_expr.is_specific_id(&target_id_name) {
return Some(ctx.ast.expression_logical(
expr.span,
value_expr.take_in(ctx.ast),
value_expr.take_in(ctx),
LogicalOperator::Coalesce,
if is_negate {
expr.alternate.take_in(ctx.ast)
expr.alternate.take_in(ctx)
} else {
expr.consequent.take_in(ctx.ast)
expr.consequent.take_in(ctx)
},
));
}
@@ -370,7 +370,7 @@ impl<'a> PeepholeOptimizations {
expr_to_inject_optional_chaining,
ctx,
) {
return Some(expr_to_inject_optional_chaining.take_in(ctx.ast));
return Some(expr_to_inject_optional_chaining.take_in(ctx));
}
}
}
@@ -399,13 +399,13 @@ impl<'a> PeepholeOptimizations {
.filter(|_| !expr.alternate.may_have_side_effects(ctx)),
) {
(Some(true), Some(false)) => {
let test = expr.test.take_in(ctx.ast);
let test = expr.test.take_in(ctx);
let test = Self::minimize_not(expr.span, test, ctx);
let test = Self::minimize_not(expr.span, test, ctx);
return Some(test);
}
(Some(false), Some(true)) => {
let test = expr.test.take_in(ctx.ast);
let test = expr.test.take_in(ctx);
let test = Self::minimize_not(expr.span, test, ctx);
return Some(test);
}
@@ -428,7 +428,7 @@ impl<'a> PeepholeOptimizations {
let needs_parens = Self::test_needs_parens(&expr.test);
if is_boolean {
// Known boolean: +a (saves 3 chars: "a?1:0" => "+a")
let test = expr.test.take_in(ctx.ast);
let test = expr.test.take_in(ctx);
return Some(ctx.ast.expression_unary(
expr.span,
UnaryOperator::UnaryPlus,
@@ -438,7 +438,7 @@ impl<'a> PeepholeOptimizations {
// Unknown type: +!!a (saves 1 char: "a?1:0" => "+!!a")
// But skip if parens would be needed (e.g., "a+b?1:0" => "+!!(a+b)" is longer)
if !needs_parens {
let test = expr.test.take_in(ctx.ast);
let test = expr.test.take_in(ctx);
let test = Self::minimize_not(expr.span, test, ctx);
let test = Self::minimize_not(expr.span, test, ctx);
return Some(ctx.ast.expression_unary(
@@ -452,7 +452,7 @@ impl<'a> PeepholeOptimizations {
// "a ? 0 : 1" => "+!a"
// Skip if parens would be needed (e.g., "a+b?0:1" => "+!(a+b)" is same length)
if !Self::test_needs_parens(&expr.test) => {
let test = expr.test.take_in(ctx.ast);
let test = expr.test.take_in(ctx);
let test = Self::minimize_not(expr.span, test, ctx);
return Some(ctx.ast.expression_unary(
expr.span,
@@ -466,7 +466,7 @@ impl<'a> PeepholeOptimizations {
if ctx.expr_eq(&expr.alternate, &expr.consequent) {
// "/* @__PURE__ */ a() ? b : b" => "b"
if !expr.test.may_have_side_effects(ctx) {
let result_expr = expr.consequent.take_in(ctx.ast);
let result_expr = expr.consequent.take_in(ctx);
// "(a ? eval : eval)(x)" => "(0, eval)(x)" — the bare branch
// would form a direct eval call / rebind a member call's `this`.
if Self::should_keep_indirect_access(&result_expr, ctx) {
@@ -476,9 +476,8 @@ impl<'a> PeepholeOptimizations {
}
// "a ? b : b" => "a, b"
let expressions = ctx
.ast
.vec_from_array([expr.test.take_in(ctx.ast), expr.consequent.take_in(ctx.ast)]);
let expressions =
ctx.ast.vec_from_array([expr.test.take_in(ctx), expr.consequent.take_in(ctx)]);
return Some(ctx.ast.expression_sequence(expr.span, expressions));
}
@@ -515,15 +514,15 @@ impl<'a> PeepholeOptimizations {
}
let cond_expr = Self::minimize_conditional(
expr.span,
expr.test.take_in(ctx.ast),
consequent.right.take_in(ctx.ast),
alternate.right.take_in(ctx.ast),
expr.test.take_in(ctx),
consequent.right.take_in(ctx),
alternate.right.take_in(ctx),
ctx,
);
Some(ctx.ast.expression_assignment(
expr.span,
consequent.operator,
alternate.left.take_in(ctx.ast),
alternate.left.take_in(ctx),
cond_expr,
))
}
@@ -544,10 +543,9 @@ impl<'a> PeepholeOptimizations {
ctx,
) {
if !matches!(expr, Expression::ChainExpression(_)) {
let new_expr = ctx.ast.expression_chain(
expr.span(),
expr.take_in(ctx.ast).into_chain_element().unwrap(),
);
let new_expr = ctx
.ast
.expression_chain(expr.span(), expr.take_in(ctx).into_chain_element().unwrap());
ctx.replace_expression(expr, new_expr);
}
true
@@ -567,7 +565,7 @@ impl<'a> PeepholeOptimizations {
Expression::StaticMemberExpression(e) => {
if e.object.is_specific_id(target_id_name) {
e.optional = true;
let new_object = expr_to_inject.take_in(ctx.ast);
let new_object = expr_to_inject.take_in(ctx);
ctx.replace_expression(&mut e.object, new_object);
return true;
}
@@ -583,7 +581,7 @@ impl<'a> PeepholeOptimizations {
Expression::ComputedMemberExpression(e) => {
if e.object.is_specific_id(target_id_name) {
e.optional = true;
let new_object = expr_to_inject.take_in(ctx.ast);
let new_object = expr_to_inject.take_in(ctx);
ctx.replace_expression(&mut e.object, new_object);
return true;
}
@@ -599,7 +597,7 @@ impl<'a> PeepholeOptimizations {
Expression::CallExpression(e) => {
if e.callee.is_specific_id(target_id_name) {
e.optional = true;
let new_callee = expr_to_inject.take_in(ctx.ast);
let new_callee = expr_to_inject.take_in(ctx);
ctx.replace_expression(&mut e.callee, new_callee);
return true;
}
@@ -616,7 +614,7 @@ impl<'a> PeepholeOptimizations {
ChainElement::StaticMemberExpression(e) => {
if e.object.is_specific_id(target_id_name) {
e.optional = true;
let new_object = expr_to_inject.take_in(ctx.ast);
let new_object = expr_to_inject.take_in(ctx);
ctx.replace_expression(&mut e.object, new_object);
return true;
}
@@ -632,7 +630,7 @@ impl<'a> PeepholeOptimizations {
ChainElement::ComputedMemberExpression(e) => {
if e.object.is_specific_id(target_id_name) {
e.optional = true;
let new_object = expr_to_inject.take_in(ctx.ast);
let new_object = expr_to_inject.take_in(ctx);
ctx.replace_expression(&mut e.object, new_object);
return true;
}
@@ -648,7 +646,7 @@ impl<'a> PeepholeOptimizations {
ChainElement::CallExpression(e) => {
if e.callee.is_specific_id(target_id_name) {
e.optional = true;
let new_callee = expr_to_inject.take_in(ctx.ast);
let new_callee = expr_to_inject.take_in(ctx);
ctx.replace_expression(&mut e.callee, new_callee);
return true;
}
@@ -46,9 +46,9 @@ impl<'a> PeepholeOptimizations {
if let Expression::LogicalExpression(logical_expr) = &mut b
&& logical_expr.operator == op
{
let right = logical_expr.left.take_in(ctx.ast);
let right = logical_expr.left.take_in(ctx);
a = Self::join_with_left_associative_op(span, op, a, right, ctx);
b = logical_expr.right.take_in(ctx.ast);
b = logical_expr.right.take_in(ctx);
continue;
}
break;
@@ -109,9 +109,9 @@ impl<'a> PeepholeOptimizations {
_ => return,
}
let new_expr = if b {
e.left.take_in(ctx.ast)
e.left.take_in(ctx)
} else {
let argument = e.left.take_in(ctx.ast);
let argument = e.left.take_in(ctx);
ctx.ast.expression_unary(e.span, UnaryOperator::LogicalNot, argument)
};
ctx.replace_expression(expr, new_expr);
@@ -204,7 +204,7 @@ impl<'a> PeepholeOptimizations {
reference.flags_mut().insert(ReferenceFlags::Read);
let new_op = logical_expr.operator.to_assignment_operator();
let new_right = logical_expr.right.take_in(ctx.ast);
let new_right = logical_expr.right.take_in(ctx);
expr.operator = new_op;
ctx.replace_expression(&mut expr.right, new_right);
}
@@ -226,7 +226,7 @@ impl<'a> PeepholeOptimizations {
Self::mark_assignment_target_as_read(&expr.left, ctx);
let new_right = binary_expr.right.take_in(ctx.ast);
let new_right = binary_expr.right.take_in(ctx);
expr.operator = new_op;
ctx.replace_expression(&mut expr.right, new_right);
}
@@ -253,7 +253,7 @@ impl<'a> PeepholeOptimizations {
return;
};
let Some(target) = e.left.as_simple_assignment_target_mut() else { return };
let target = target.take_in(ctx.ast);
let target = target.take_in(ctx);
let new_expr = ctx.ast.expression_update(e.span, operator, true, target);
ctx.replace_expression(expr, new_expr);
}
@@ -21,7 +21,7 @@ impl<'a> PeepholeOptimizations {
if let Expression::UnaryExpression(u2) = &mut u1.argument
&& u2.operator.is_not()
{
let mut e = u2.argument.take_in(ctx.ast);
let mut e = u2.argument.take_in(ctx);
Self::minimize_expression_in_boolean_context(&mut e, ctx);
ctx.replace_expression(expr, e);
}
@@ -31,7 +31,7 @@ impl<'a> PeepholeOptimizations {
&& e.right.is_number_0()
&& e.left.is_int32_or_uint32(ctx) =>
{
let argument = e.left.take_in(ctx.ast);
let argument = e.left.take_in(ctx);
let new_expr = if matches!(
e.operator,
BinaryOperator::StrictInequality | BinaryOperator::Inequality
@@ -50,7 +50,7 @@ impl<'a> PeepholeOptimizations {
Self::minimize_expression_in_boolean_context(&mut e.right, ctx);
// "if (anything && truthyNoSideEffects)" => "if (anything)"
if e.right.get_side_free_boolean_value(ctx) == Some(true) {
let new_expr = e.left.take_in(ctx.ast);
let new_expr = e.left.take_in(ctx);
ctx.replace_expression(expr, new_expr);
}
}
@@ -60,7 +60,7 @@ impl<'a> PeepholeOptimizations {
Self::minimize_expression_in_boolean_context(&mut e.right, ctx);
// "if (anything || falsyNoSideEffects)" => "if (anything)"
if e.right.get_side_free_boolean_value(ctx) == Some(false) {
let new_expr = e.left.take_in(ctx.ast);
let new_expr = e.left.take_in(ctx);
ctx.replace_expression(expr, new_expr);
}
}
@@ -69,8 +69,8 @@ impl<'a> PeepholeOptimizations {
Self::minimize_expression_in_boolean_context(&mut e.consequent, ctx);
Self::minimize_expression_in_boolean_context(&mut e.alternate, ctx);
if let Some(boolean) = e.consequent.get_side_free_boolean_value(ctx) {
let right = e.alternate.take_in(ctx.ast);
let left = e.test.take_in(ctx.ast);
let right = e.alternate.take_in(ctx);
let left = e.test.take_in(ctx);
let span = e.span;
let (op, left) = if boolean {
// "if (anything1 ? truthyNoSideEffects : anything2)" => "if (anything1 || anything2)"
@@ -84,8 +84,8 @@ impl<'a> PeepholeOptimizations {
return;
}
if let Some(boolean) = e.alternate.get_side_free_boolean_value(ctx) {
let left = e.test.take_in(ctx.ast);
let right = e.consequent.take_in(ctx.ast);
let left = e.test.take_in(ctx);
let right = e.consequent.take_in(ctx);
let span = e.span;
let (op, left) = if boolean {
// "if (anything1 ? anything2 : truthyNoSideEffects)" => "if (!anything1 || anything2)"
@@ -32,9 +32,9 @@ impl<'a> PeepholeOptimizations {
}
let span = for_stmt.body.span();
let (first, body) = match for_stmt.body.take_in(ctx.ast) {
let (first, body) = match for_stmt.body.take_in(ctx) {
Statement::BlockStatement(mut block_stmt) => (
block_stmt.body.get_mut(0).unwrap().take_in(ctx.ast),
block_stmt.body.get_mut(0).unwrap().take_in(ctx),
Some(Statement::BlockStatement(block_stmt)),
),
stmt => (stmt, None),
@@ -42,7 +42,7 @@ impl<'a> PeepholeOptimizations {
let Statement::IfStatement(mut if_stmt) = first else { unreachable!() };
let expr = match if_stmt.test.take_in(ctx.ast) {
let expr = match if_stmt.test.take_in(ctx) {
Expression::UnaryExpression(unary_expr) if unary_expr.operator.is_not() => {
unary_expr.unbox().argument
}
@@ -50,7 +50,7 @@ impl<'a> PeepholeOptimizations {
};
if let Some(test) = &mut for_stmt.test {
let left = test.take_in(ctx.ast);
let left = test.take_in(ctx);
let mut logical_expr =
ctx.ast.logical_expression(test.span(), left, LogicalOperator::And, expr);
let new_test = Self::try_fold_and_or(&mut logical_expr, ctx)
@@ -75,9 +75,9 @@ impl<'a> PeepholeOptimizations {
}
let span = for_stmt.body.span();
let (first, body) = match for_stmt.body.take_in(ctx.ast) {
let (first, body) = match for_stmt.body.take_in(ctx) {
Statement::BlockStatement(mut block_stmt) => (
block_stmt.body.get_mut(0).unwrap().take_in(ctx.ast),
block_stmt.body.get_mut(0).unwrap().take_in(ctx),
Some(Statement::BlockStatement(block_stmt)),
),
stmt => (stmt, None),
@@ -85,10 +85,10 @@ impl<'a> PeepholeOptimizations {
let Statement::IfStatement(mut if_stmt) = first else { unreachable!() };
let expr = if_stmt.test.take_in(ctx.ast);
let expr = if_stmt.test.take_in(ctx);
if let Some(test) = &mut for_stmt.test {
let left = test.take_in(ctx.ast);
let left = test.take_in(ctx);
let mut logical_expr =
ctx.ast.logical_expression(test.span(), left, LogicalOperator::And, expr);
let new_test = Self::try_fold_and_or(&mut logical_expr, ctx)
@@ -98,7 +98,7 @@ impl<'a> PeepholeOptimizations {
for_stmt.test = Some(expr);
}
let consequent = if_stmt.consequent.take_in(ctx.ast);
let consequent = if_stmt.consequent.take_in(ctx);
let new_body = Self::drop_first_statement(span, body, Some(consequent), ctx);
ctx.replace_statement(&mut for_stmt.body, new_body);
}
@@ -117,7 +117,7 @@ impl<'a> PeepholeOptimizations {
} else if block_stmt.body.len() == 2
&& !Self::statement_cares_about_scope(&block_stmt.body[1])
{
return block_stmt.body[1].take_in(ctx.ast);
return block_stmt.body[1].take_in(ctx);
} else {
block_stmt.body.remove(0);
}
@@ -25,17 +25,17 @@ impl<'a> PeepholeOptimizations {
// "if (a) b();" => "a && b();"
e => (LogicalOperator::And, e),
};
let a = e.take_in(ctx.ast);
let b = expr_stmt.expression.take_in(ctx.ast);
let a = e.take_in(ctx);
let b = expr_stmt.expression.take_in(ctx);
let expr = Self::join_with_left_associative_op(if_stmt.span, op, a, b, ctx);
return Some(ctx.ast.statement_expression(if_stmt.span, expr));
} else if let Some(Statement::ExpressionStatement(alternate_expr_stmt)) =
&mut if_stmt.alternate
{
// "if (a) b(); else c();" => "a ? b() : c();"
let test = if_stmt.test.take_in(ctx.ast);
let consequent = expr_stmt.expression.take_in(ctx.ast);
let alternate = alternate_expr_stmt.expression.take_in(ctx.ast);
let test = if_stmt.test.take_in(ctx);
let consequent = expr_stmt.expression.take_in(ctx);
let alternate = alternate_expr_stmt.expression.take_in(ctx);
let expr =
Self::minimize_conditional(if_stmt.span, test, consequent, alternate, ctx);
return Some(ctx.ast.statement_expression(if_stmt.span, expr));
@@ -45,7 +45,7 @@ impl<'a> PeepholeOptimizations {
|| if_stmt.alternate.as_ref().is_some_and(Self::is_statement_empty)
{
// "if (a) {}" => "a;"
let mut expr = if_stmt.test.take_in(ctx.ast);
let mut expr = if_stmt.test.take_in(ctx);
Self::remove_unused_expression(&mut expr, ctx);
return Some(ctx.ast.statement_expression(if_stmt.span, expr));
} else if let Some(Statement::ExpressionStatement(expr_stmt)) = &mut if_stmt.alternate {
@@ -57,8 +57,8 @@ impl<'a> PeepholeOptimizations {
// "if (a) {} else b();" => "a || b();"
e => (LogicalOperator::Or, e),
};
let a = e.take_in(ctx.ast);
let b = expr_stmt.expression.take_in(ctx.ast);
let a = e.take_in(ctx);
let b = expr_stmt.expression.take_in(ctx);
let expr = Self::join_with_left_associative_op(if_stmt.span, op, a, b, ctx);
return Some(ctx.ast.statement_expression(if_stmt.span, expr));
} else if let Some(stmt) = &mut if_stmt.alternate {
@@ -66,20 +66,17 @@ impl<'a> PeepholeOptimizations {
match &mut if_stmt.test {
// "if (!a) {} else return b;" => "if (a) return b;"
Expression::UnaryExpression(unary_expr) if unary_expr.operator.is_not() => {
let new_test = unary_expr.argument.take_in(ctx.ast);
let new_consequent = stmt.take_in(ctx.ast);
let new_test = unary_expr.argument.take_in(ctx);
let new_consequent = stmt.take_in(ctx);
ctx.replace_expression(&mut if_stmt.test, new_test);
ctx.replace_statement(&mut if_stmt.consequent, new_consequent);
if_stmt.alternate = None;
}
// "if (a) {} else return b;" => "if (!a) return b;"
_ => {
let new_test = Self::minimize_not(
if_stmt.test.span(),
if_stmt.test.take_in(ctx.ast),
ctx,
);
let new_consequent = stmt.take_in(ctx.ast);
let new_test =
Self::minimize_not(if_stmt.test.span(), if_stmt.test.take_in(ctx), ctx);
let new_consequent = stmt.take_in(ctx);
ctx.replace_expression(&mut if_stmt.test, new_test);
ctx.replace_statement(&mut if_stmt.consequent, new_consequent);
if_stmt.alternate = None;
@@ -96,7 +93,7 @@ impl<'a> PeepholeOptimizations {
&& unary_expr.operator.is_not()
{
// "if (!a) return b; else return c;" => "if (a) return c; else return b;"
let new_test = unary_expr.argument.take_in(ctx.ast);
let new_test = unary_expr.argument.take_in(ctx);
ctx.replace_expression(&mut if_stmt.test, new_test);
std::mem::swap(&mut if_stmt.consequent, alternate);
Self::wrap_to_avoid_ambiguous_else(if_stmt, ctx);
@@ -109,8 +106,8 @@ impl<'a> PeepholeOptimizations {
&& if2_stmt.alternate.is_none()
{
// "if (a) if (b) return c;" => "if (a && b) return c;"
let a = if_stmt.test.take_in(ctx.ast);
let b = if2_stmt.test.take_in(ctx.ast);
let a = if_stmt.test.take_in(ctx);
let b = if2_stmt.test.take_in(ctx);
let new_test = Self::join_with_left_associative_op(
if_stmt.test.span(),
LogicalOperator::And,
@@ -118,7 +115,7 @@ impl<'a> PeepholeOptimizations {
b,
ctx,
);
let new_consequent = if2_stmt.consequent.take_in(ctx.ast);
let new_consequent = if2_stmt.consequent.take_in(ctx);
ctx.replace_expression(&mut if_stmt.test, new_test);
ctx.replace_statement(&mut if_stmt.consequent, new_consequent);
}
@@ -138,7 +135,7 @@ impl<'a> PeepholeOptimizations {
let new_consequent =
Statement::BlockStatement(ctx.ast.alloc(ctx.ast.block_statement_with_scope_id(
if_stmt.consequent.span(),
ctx.ast.vec1(if_stmt.consequent.take_in(ctx.ast)),
ctx.ast.vec1(if_stmt.consequent.take_in(ctx)),
scope_id,
)));
ctx.replace_statement(&mut if_stmt.consequent, new_consequent);
@@ -63,12 +63,7 @@ impl<'a> PeepholeOptimizations {
ctx,
)
.map(|new_expr| {
ctx.ast.expression_logical(
expr.span,
left.left.take_in(ctx.ast),
expr.operator,
new_expr,
)
ctx.ast.expression_logical(expr.span, left.left.take_in(ctx), expr.operator, new_expr)
})
}
@@ -142,7 +137,7 @@ impl<'a> PeepholeOptimizations {
};
Some(ctx.ast.expression_binary(
span,
left_non_value_expr.take_in(ctx.ast),
left_non_value_expr.take_in(ctx),
replace_op,
ctx.ast.expression_null_literal(null_expr_span),
))
@@ -245,13 +240,13 @@ impl<'a> PeepholeOptimizations {
Self::mark_assignment_target_as_read(&assignment_expr.left, ctx);
let assign_value = assignment_expr.right.take_in(ctx.ast);
let assign_value = assignment_expr.right.take_in(ctx);
sequence_expr.expressions.push(assign_value);
let new_expr = ctx.ast.expression_assignment(
e.span,
e.operator.to_assignment_operator(),
assignment_expr.left.take_in(ctx.ast),
e.right.take_in(ctx.ast),
assignment_expr.left.take_in(ctx),
e.right.take_in(ctx),
);
ctx.replace_expression(expr, new_expr);
return;
@@ -277,7 +272,7 @@ impl<'a> PeepholeOptimizations {
};
assignment_expr.span = span;
assignment_expr.operator = new_op;
let new_expr = e.right.take_in(ctx.ast);
let new_expr = e.right.take_in(ctx);
ctx.replace_expression(expr, new_expr);
}
@@ -31,7 +31,7 @@ impl<'a> PeepholeOptimizations {
Expression::UnaryExpression(e)
if e.operator.is_not() && e.argument.value_type(ctx).is_boolean() =>
{
let new_expr = e.argument.take_in(ctx.ast);
let new_expr = e.argument.take_in(ctx);
ctx.replace_expression(expr, new_expr);
}
// `!(a == b)` => `a != b`
@@ -40,16 +40,16 @@ impl<'a> PeepholeOptimizations {
// `!(a !== b)` => `a === b`
Expression::BinaryExpression(binary_expr) if binary_expr.operator.is_equality() => {
binary_expr.operator = binary_expr.operator.equality_inverse_operator().unwrap();
let new_expr = e.argument.take_in(ctx.ast);
let new_expr = e.argument.take_in(ctx);
ctx.replace_expression(expr, new_expr);
}
// "!(a, b)" => "a, !b"
Expression::SequenceExpression(sequence_expr) => {
if let Some(last_expr) = sequence_expr.expressions.last_mut() {
let new_last =
Self::minimize_not(last_expr.span(), last_expr.take_in(ctx.ast), ctx);
Self::minimize_not(last_expr.span(), last_expr.take_in(ctx), ctx);
ctx.replace_expression(last_expr, new_last);
let new_expr = e.argument.take_in(ctx.ast);
let new_expr = e.argument.take_in(ctx);
ctx.replace_expression(expr, new_expr);
}
}
@@ -48,12 +48,12 @@ impl<'a> PeepholeOptimizations {
/// ## MinimizeExitPoints:
/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/MinimizeExitPoints.java>
pub fn minimize_statements(stmts: &mut Vec<'a, Statement<'a>>, ctx: &mut TraverseCtx<'a>) {
let mut old_stmts = stmts.take_in(ctx.ast);
let mut old_stmts = stmts.take_in(ctx);
let mut is_control_flow_dead = false;
let mut keep_var = KeepVar::new(ctx.ast);
let mut identity_drops = 0u32;
for i in 0..old_stmts.len() {
let stmt = old_stmts[i].take_in(ctx.ast);
let stmt = old_stmts[i].take_in(ctx);
if is_control_flow_dead
&& !stmt.is_module_declaration()
&& !matches!(stmt.as_declaration(), Some(Declaration::FunctionDeclaration(_)))
@@ -209,7 +209,7 @@ impl<'a> PeepholeOptimizations {
if let Expression::UnaryExpression(unary_expr) = &mut prev_if.test
&& unary_expr.operator.is_not()
{
prev_if.test = unary_expr.argument.take_in(ctx.ast);
prev_if.test = unary_expr.argument.take_in(ctx);
std::mem::swap(&mut left, &mut right);
}
@@ -230,7 +230,7 @@ impl<'a> PeepholeOptimizations {
// "if (a) return b; return c;" => "return a ? b : c;"
Self::minimize_conditional(
prev_if.span,
prev_if.test.take_in(ctx.ast),
prev_if.test.take_in(ctx),
left,
right,
ctx,
@@ -304,7 +304,7 @@ impl<'a> PeepholeOptimizations {
if let Expression::UnaryExpression(unary_expr) = &mut prev_if.test
&& unary_expr.operator.is_not()
{
prev_if.test = unary_expr.argument.take_in(ctx.ast);
prev_if.test = unary_expr.argument.take_in(ctx);
std::mem::swap(&mut left, &mut right);
}
@@ -325,7 +325,7 @@ impl<'a> PeepholeOptimizations {
// "if (a) throw b; throw c;" => "throw a ? b : c;"
Self::minimize_conditional(
prev_if.span,
prev_if.test.take_in(ctx.ast),
prev_if.test.take_in(ctx),
left,
right,
ctx,
@@ -417,8 +417,8 @@ impl<'a> PeepholeOptimizations {
b: &mut Expression<'a>,
ctx: &TraverseCtx<'a>,
) -> Expression<'a> {
let a = a.take_in(ctx.ast);
let b = b.take_in(ctx.ast);
let a = a.take_in(ctx);
let b = b.take_in(ctx);
if let Expression::SequenceExpression(mut sequence_expr) = a {
// `(a, b); c`
sequence_expr.expressions.push(b);
@@ -643,7 +643,7 @@ impl<'a> PeepholeOptimizations {
|| assign_expr.right.is_literal_value(true, ctx))
{
// "var a; a = b();" => "var a = b();"
decl.init = Some(assign_expr.right.take_in(ctx.ast));
decl.init = Some(assign_expr.right.take_in(ctx));
return true;
}
// Note it is not possible to compress like:
@@ -757,8 +757,8 @@ impl<'a> PeepholeOptimizations {
if_stmt.test = Self::join_with_left_associative_op(
if_stmt.test.span(),
LogicalOperator::Or,
prev_if_stmt.test.take_in(ctx.ast),
if_stmt.test.take_in(ctx.ast),
prev_if_stmt.test.take_in(ctx),
if_stmt.test.take_in(ctx),
ctx,
);
let dropped = result.pop().unwrap();
@@ -827,7 +827,7 @@ impl<'a> PeepholeOptimizations {
} else {
body[0].span()
};
let test = if_stmt.test.take_in(ctx.ast);
let test = if_stmt.test.take_in(ctx);
let mut test = Self::minimize_not(test.span(), test, ctx);
Self::minimize_expression_in_boolean_context(&mut test, ctx);
let consequent = if body.len() == 1 {
@@ -897,9 +897,8 @@ impl<'a> PeepholeOptimizations {
let a = &mut prev_expr_stmt.expression;
prev_expr_stmt.expression = Self::join_sequence(a, argument, ctx);
} else {
result.push(
ctx.ast.statement_expression(argument.span(), argument.take_in(ctx.ast)),
);
result
.push(ctx.ast.statement_expression(argument.span(), argument.take_in(ctx)));
}
}
if let Some(old) = ret_stmt.argument.take() {
@@ -1020,9 +1019,8 @@ impl<'a> PeepholeOptimizations {
ctx.drop_statement(&dropped);
}
} else {
for_stmt.init = Some(ForStatementInit::from(
prev_expr_stmt.expression.take_in(ctx.ast),
));
for_stmt.init =
Some(ForStatementInit::from(prev_expr_stmt.expression.take_in(ctx)));
let dropped = result.pop().unwrap();
ctx.drop_statement(&dropped);
}
@@ -1408,7 +1406,7 @@ impl<'a> PeepholeOptimizations {
// with the replacement expression.
// https://github.com/rolldown/rolldown/issues/8248
let target_span = target_expr.span();
let mut new_expr = replacement.take_in(ctx.ast);
let mut new_expr = replacement.take_in(ctx);
// Span fix-up on the still-owned new node before the slot replacement, not the slot replacement itself.
*new_expr.span_mut() = target_span;
ctx.replace_expression(target_expr, new_expr);
@@ -1917,7 +1915,7 @@ impl<'a> PeepholeOptimizations {
}
}
Expression::ChainExpression(chain_expr) => {
let mut expr = Expression::from(chain_expr.expression.take_in(ctx.ast));
let mut expr = Expression::from(chain_expr.expression.take_in(ctx));
let changed = Self::substitute_single_use_symbol_in_expression(
&mut expr,
search_for,
@@ -85,7 +85,7 @@ impl<'a> Traverse<'a> for Normalize {
fn exit_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
if let Expression::ParenthesizedExpression(paren_expr) = expr {
*expr = paren_expr.expression.take_in(ctx.ast);
*expr = paren_expr.expression.take_in(ctx);
}
// Handled outside the match below so the replacement can go through
// `ctx.replace_expression`, which walks the dropped call (its
@@ -139,7 +139,7 @@ impl<'a> Normalize {
}
fn convert_while_to_for(stmt: &mut Statement<'a>, ctx: &mut TraverseCtx<'a>) {
let Statement::WhileStatement(while_stmt) = stmt.take_in(ctx.ast) else { return };
let Statement::WhileStatement(while_stmt) = stmt.take_in(ctx) else { return };
let while_stmt = while_stmt.unbox();
let for_stmt = ctx.ast.alloc_for_statement_with_scope_id(
while_stmt.span,
@@ -149,7 +149,7 @@ impl<'a> PeepholeOptimizations {
return;
}
let new_stmt = if boolean {
if_stmt.consequent.take_in(ctx.ast)
if_stmt.consequent.take_in(ctx)
} else if let Some(alternate) = if_stmt.alternate.take() {
alternate
} else {
@@ -205,11 +205,9 @@ impl<'a> PeepholeOptimizations {
};
if var_init.kind.is_var() {
if let Some(var_decl) = &mut var_decl {
var_decl
.declarations
.splice(0..0, var_init.declarations.take_in(ctx.ast));
var_decl.declarations.splice(0..0, var_init.declarations.take_in(ctx));
} else {
var_decl = Some(var_init.take_in_box(ctx.ast));
var_decl = Some(var_init.take_in_box(ctx));
}
}
let new_stmt = var_decl.map_or_else(
@@ -303,7 +301,7 @@ impl<'a> PeepholeOptimizations {
var.visit_block_statement(&handler.body);
let Some(handler) = &mut s.handler else { return };
for dropped in handler.body.body.take_in(ctx.ast) {
for dropped in handler.body.body.take_in(ctx) {
ctx.drop_statement(&dropped);
}
if let Some(var_decl) = var.get_variable_declaration_statement() {
@@ -341,16 +339,15 @@ impl<'a> PeepholeOptimizations {
// "(a, true) ? b : c" => "a, b"
let exprs = ctx.ast.vec_from_array([
{
let mut test = e.test.take_in(ctx.ast);
let mut test = e.test.take_in(ctx);
Self::remove_unused_expression(&mut test, ctx);
test
},
if v { e.consequent.take_in(ctx.ast) } else { e.alternate.take_in(ctx.ast) },
if v { e.consequent.take_in(ctx) } else { e.alternate.take_in(ctx) },
]);
ctx.ast.expression_sequence(e.span, exprs)
} else {
let result_expr =
if v { e.consequent.take_in(ctx.ast) } else { e.alternate.take_in(ctx.ast) };
let result_expr = if v { e.consequent.take_in(ctx) } else { e.alternate.take_in(ctx) };
let should_keep_as_sequence_expr = Self::should_keep_indirect_access(&result_expr, ctx);
// "(1 ? a.b : 0)()" => "(0, a.b)()"
if should_keep_as_sequence_expr {
@@ -65,7 +65,7 @@ impl<'a> PeepholeOptimizations {
let Expression::UnaryExpression(unary_expr) = e else { return false };
match unary_expr.operator {
UnaryOperator::Void | UnaryOperator::LogicalNot => {
let new_expr = unary_expr.argument.take_in(ctx.ast);
let new_expr = unary_expr.argument.take_in(ctx);
ctx.replace_expression(e, new_expr);
Self::remove_unused_expression(e, ctx)
}
@@ -73,7 +73,7 @@ impl<'a> PeepholeOptimizations {
if unary_expr.argument.is_identifier_reference() {
true
} else {
let new_expr = unary_expr.argument.take_in(ctx.ast);
let new_expr = unary_expr.argument.take_in(ctx);
ctx.replace_expression(e, new_expr);
Self::remove_unused_expression(e, ctx)
}
@@ -118,7 +118,7 @@ impl<'a> PeepholeOptimizations {
}
if Self::remove_unused_expression(&mut logical_expr.right, ctx) {
Self::remove_unused_expression(&mut logical_expr.left, ctx);
let new_expr = logical_expr.left.take_in(ctx.ast);
let new_expr = logical_expr.left.take_in(ctx);
ctx.replace_expression(e, new_expr);
return false;
}
@@ -159,7 +159,7 @@ impl<'a> PeepholeOptimizations {
ctx,
)
{
let new_expr = logical_right.take_in(ctx.ast);
let new_expr = logical_right.take_in(ctx);
ctx.replace_expression(e, new_expr);
return false;
}
@@ -198,16 +198,16 @@ impl<'a> PeepholeOptimizations {
assignment_expr.operator = AssignmentOperator::LogicalNullish;
// `??=` reads the LHS to check for nullish, so update reference flags.
Self::mark_assignment_target_as_read(&assignment_expr.left, ctx);
let new_expr = logical_right.take_in(ctx.ast);
let new_expr = logical_right.take_in(ctx);
ctx.replace_expression(e, new_expr);
return false;
}
let new_expr = ctx.ast.expression_logical(
*logical_span,
new_left_hand_expr.take_in(ctx.ast),
new_left_hand_expr.take_in(ctx),
LogicalOperator::Coalesce,
logical_right.take_in(ctx.ast),
logical_right.take_in(ctx),
);
ctx.replace_expression(e, new_expr);
return false;
@@ -498,7 +498,7 @@ impl<'a> PeepholeOptimizations {
if test {
return true;
}
let new_expr = conditional_expr.test.take_in(ctx.ast);
let new_expr = conditional_expr.test.take_in(ctx);
ctx.replace_expression(e, new_expr);
return false;
}
@@ -508,8 +508,8 @@ impl<'a> PeepholeOptimizations {
let new_expr = Self::join_with_left_associative_op(
conditional_expr.span,
LogicalOperator::Or,
conditional_expr.test.take_in(ctx.ast),
conditional_expr.alternate.take_in(ctx.ast),
conditional_expr.test.take_in(ctx),
conditional_expr.alternate.take_in(ctx),
ctx,
);
ctx.replace_expression(e, new_expr);
@@ -521,8 +521,8 @@ impl<'a> PeepholeOptimizations {
let new_expr = Self::join_with_left_associative_op(
conditional_expr.span,
LogicalOperator::And,
conditional_expr.test.take_in(ctx.ast),
conditional_expr.consequent.take_in(ctx.ast),
conditional_expr.test.take_in(ctx),
conditional_expr.consequent.take_in(ctx),
ctx,
);
ctx.replace_expression(e, new_expr);
@@ -551,12 +551,12 @@ impl<'a> PeepholeOptimizations {
match (left, right) {
(true, true) => true,
(true, false) => {
let new_expr = binary_expr.right.take_in(ctx.ast);
let new_expr = binary_expr.right.take_in(ctx);
ctx.replace_expression(e, new_expr);
false
}
(false, true) => {
let new_expr = binary_expr.left.take_in(ctx.ast);
let new_expr = binary_expr.left.take_in(ctx);
ctx.replace_expression(e, new_expr);
false
}
@@ -564,8 +564,8 @@ impl<'a> PeepholeOptimizations {
let new_expr = ctx.ast.expression_sequence(
binary_expr.span,
ctx.ast.vec_from_array([
binary_expr.left.take_in(ctx.ast),
binary_expr.right.take_in(ctx.ast),
binary_expr.left.take_in(ctx),
binary_expr.right.take_in(ctx),
]),
);
ctx.replace_expression(e, new_expr);
@@ -604,7 +604,7 @@ impl<'a> PeepholeOptimizations {
if right_as_primitive.is_symbol() == Some(false)
&& !binary_expr.right.may_have_side_effects(ctx)
{
let new_expr = binary_expr.left.take_in(ctx.ast);
let new_expr = binary_expr.left.take_in(ctx);
ctx.replace_expression(e, new_expr);
return true;
}
@@ -733,7 +733,7 @@ impl<'a> PeepholeOptimizations {
if symbol_value.read_references_count > 0 {
return false;
}
let new_expr = assign_expr.right.take_in(ctx.ast);
let new_expr = assign_expr.right.take_in(ctx);
ctx.replace_expression(e, new_expr);
false
}
@@ -914,7 +914,7 @@ impl<'a> PeepholeOptimizations {
&& let Some(expr) = key.as_expression_mut()
&& expr.may_have_side_effects(ctx)
{
exprs.push(expr.take_in(ctx.ast));
exprs.push(expr.take_in(ctx));
}
// Save static initializer.
if e.r#static()
@@ -83,16 +83,16 @@ impl<'a> PeepholeOptimizations {
let wrap_with_unary_plus_if_needed = |expr: &mut Expression<'a>| {
if expr.value_type(ctx).is_number() {
expr.take_in(ctx.ast)
expr.take_in(ctx)
} else {
ctx.ast.expression_unary(SPAN, UnaryOperator::UnaryPlus, expr.take_in(ctx.ast))
ctx.ast.expression_unary(SPAN, UnaryOperator::UnaryPlus, expr.take_in(ctx))
}
};
Some(ctx.ast.expression_binary(
span,
// see [`PeepholeOptimizations::is_binary_operator_that_does_number_conversion`] why it does not require `wrap_with_unary_plus_if_needed` here
first_arg.take_in(ctx.ast),
first_arg.take_in(ctx),
BinaryOperator::Exponential,
wrap_with_unary_plus_if_needed(second_arg),
))
@@ -189,10 +189,10 @@ impl<'a> PeepholeOptimizations {
let new_expr = ctx.ast.expression_call(
original_span,
new_root_callee.take_in(ctx.ast),
new_root_callee.take_in(ctx),
NONE,
ctx.ast.vec_from_iter(
collected_arguments.into_iter().rev().flat_map(|arg| arg.take_in(ctx.ast)),
collected_arguments.into_iter().rev().flat_map(|arg| arg.take_in(ctx)),
),
false,
);
@@ -253,13 +253,13 @@ impl<'a> PeepholeOptimizations {
}
if args.is_empty() {
Some(object.take_in(ctx.ast))
Some(object.take_in(ctx))
} else if can_merge_until.is_some() {
Some(ctx.ast.expression_call(
span,
callee.take_in(ctx.ast),
callee.take_in(ctx),
NONE,
args.take_in(ctx.ast),
args.take_in(ctx),
false,
))
} else {
@@ -567,7 +567,7 @@ impl<'a> PeepholeOptimizations {
s.span = span;
s.value = ctx.ast.str(&c.to_string());
s.raw = None;
Some(object.take_in(ctx.ast))
Some(object.take_in(ctx))
} else {
None
}
@@ -104,7 +104,7 @@ impl<'a> PeepholeOptimizations {
let new_prop =
ctx.ast.assignment_target_property_assignment_target_property_identifier(
ident.span,
ident.take_in(ctx.ast),
ident.take_in(ctx),
None,
);
ctx.replace_assignment_target_property(prop, new_prop);
@@ -209,7 +209,7 @@ impl<'a> PeepholeOptimizations {
&& let Some(body) = arrow_expr.body.statements.first_mut()
&& let Statement::ReturnStatement(ret_stmt) = body
{
let return_stmt_arg = ret_stmt.argument.as_mut().map(|arg| arg.take_in(ctx.ast));
let return_stmt_arg = ret_stmt.argument.as_mut().map(|arg| arg.take_in(ctx));
if let Some(arg) = return_stmt_arg {
ctx.replace_statement(body, ctx.ast.statement_expression(arg.span(), arg));
arrow_expr.expression = true;
@@ -248,7 +248,7 @@ impl<'a> PeepholeOptimizations {
let new_value = if let Expression::Identifier(ident) = &unary_expr.argument
&& ctx.is_global_reference(ident)
{
let left = e.left.take_in(ctx.ast);
let left = e.left.take_in(ctx);
let right = ctx.ast.expression_string_literal(e.right.span(), "u", None);
ctx.ast.expression_binary(e.span, left, new_comp_op, right)
} else {
@@ -256,7 +256,7 @@ impl<'a> PeepholeOptimizations {
let Expression::UnaryExpression(unary_expr) = &mut e.left else { return };
ctx.ast.expression_binary(
span,
unary_expr.take_in(ctx.ast).argument,
unary_expr.take_in(ctx).argument,
new_eq_op,
ctx.ast.void_0(e.right.span()),
)
@@ -288,7 +288,7 @@ impl<'a> PeepholeOptimizations {
if !parent_expression_does_to_number_conversion {
return;
}
let new_value = e.argument.take_in(ctx.ast);
let new_value = e.argument.take_in(ctx);
ctx.replace_expression(expr, new_value);
}
@@ -343,16 +343,16 @@ impl<'a> PeepholeOptimizations {
if right.operator != e.operator {
return;
}
let Expression::LogicalExpression(mut right) = e.right.take_in(ctx.ast) else { return };
let Expression::LogicalExpression(mut right) = e.right.take_in(ctx) else { return };
let mut new_left = ctx.ast.expression_logical(
e.span,
e.left.take_in(ctx.ast),
e.left.take_in(ctx),
e.operator,
right.left.take_in(ctx.ast),
right.left.take_in(ctx),
);
Self::substitute_rotate_logical_expression(&mut new_left, ctx);
let new_value =
ctx.ast.expression_logical(e.span, new_left, e.operator, right.right.take_in(ctx.ast));
ctx.ast.expression_logical(e.span, new_left, e.operator, right.right.take_in(ctx));
ctx.replace_expression(expr, new_value);
}
@@ -378,22 +378,18 @@ impl<'a> PeepholeOptimizations {
&& right.operator == e.operator
&& !right.right.may_have_side_effects(ctx)
{
let Expression::BinaryExpression(mut right) = e.right.take_in(ctx.ast) else {
let Expression::BinaryExpression(mut right) = e.right.take_in(ctx) else {
return;
};
let mut new_left = ctx.ast.expression_binary(
e.span,
e.left.take_in(ctx.ast),
e.left.take_in(ctx),
e.operator,
right.left.take_in(ctx.ast),
right.left.take_in(ctx),
);
Self::substitute_rotate_binary_expression(&mut new_left, ctx);
let new_value = ctx.ast.expression_binary(
e.span,
new_left,
e.operator,
right.right.take_in(ctx.ast),
);
let new_value =
ctx.ast.expression_binary(e.span, new_left, e.operator, right.right.take_in(ctx));
ctx.replace_expression(expr, new_value);
return;
}
@@ -415,8 +411,8 @@ impl<'a> PeepholeOptimizations {
&& !right.left.may_have_side_effects(ctx)
&& !right.right.may_have_side_effects(ctx)
{
let left = e.left.take_in(ctx.ast);
let right = e.right.take_in(ctx.ast);
let left = e.left.take_in(ctx);
let right = e.right.take_in(ctx);
e.right = left;
e.left = right;
ctx.notice_change();
@@ -470,7 +466,7 @@ impl<'a> PeepholeOptimizations {
return;
};
let new_value =
ctx.ast.expression_logical(span, left.left.take_in(ctx.ast), e.operator, new_expr);
ctx.ast.expression_logical(span, left.left.take_in(ctx), e.operator, new_expr);
ctx.replace_expression(expr, new_value);
}
@@ -607,9 +603,9 @@ impl<'a> PeepholeOptimizations {
// `foo != void 0` -> `foo == null`, `foo == undefined` -> `foo == null`
if e.operator == BinaryOperator::Inequality || e.operator == BinaryOperator::Equality {
let (left, right) = if ctx.is_expression_undefined(&e.right) {
(e.left.take_in(ctx.ast), ctx.ast.expression_null_literal(e.right.span()))
(e.left.take_in(ctx), ctx.ast.expression_null_literal(e.right.span()))
} else if ctx.is_expression_undefined(&e.left) {
(e.right.take_in(ctx.ast), ctx.ast.expression_null_literal(e.left.span()))
(e.right.take_in(ctx), ctx.ast.expression_null_literal(e.left.span()))
} else {
return;
};
@@ -941,7 +937,7 @@ impl<'a> PeepholeOptimizations {
// if r is not used by other places because `[...arguments]` does not have a sideeffect
// `r` is used once in the for-loop (assignment for each index)
(ctx.scoping().get_resolved_references(de_id_symbol_id).count() > 1)
.then(|| r_id.take_in(ctx.ast))
.then(|| r_id.take_in(ctx))
};
if let Some(r_id_pat) = r_id_pat {
@@ -949,7 +945,7 @@ impl<'a> PeepholeOptimizations {
SPAN,
ctx.ast.vec1(ctx.ast.array_expression_element_spread_element(
SPAN,
Expression::Identifier(arguments_id.take_in_box(ctx.ast)),
Expression::Identifier(arguments_id.take_in_box(ctx)),
)),
);
// wrap with `.slice(offset)`
@@ -1087,7 +1083,7 @@ impl<'a> PeepholeOptimizations {
"Boolean" => match arg {
None => Some(ctx.ast.expression_boolean_literal(span, false)),
Some(arg) => {
let mut arg = arg.take_in(ctx.ast);
let mut arg = arg.take_in(ctx);
Self::minimize_expression_in_boolean_context(&mut arg, ctx);
let arg = ctx.ast.expression_unary(span, UnaryOperator::LogicalNot, arg);
Some(Self::minimize_not(span, arg, ctx))
@@ -1118,9 +1114,7 @@ impl<'a> PeepholeOptimizations {
// `BigInt(1n)` -> `1n`
"BigInt" => match arg {
None => None,
Some(arg) => {
matches!(arg, Expression::BigIntLiteral(_)).then(|| arg.take_in(ctx.ast))
}
Some(arg) => matches!(arg, Expression::BigIntLiteral(_)).then(|| arg.take_in(ctx)),
},
_ => None,
};
@@ -1216,8 +1210,8 @@ impl<'a> PeepholeOptimizations {
}
}
if is_new_expr {
let callee = callee.take_in(ctx.ast);
let args = args.take_in(ctx.ast);
let callee = callee.take_in(ctx);
let args = args.take_in(ctx);
let new_value =
ctx.ast.expression_call(*span, callee, NONE, args, false);
ctx.replace_expression(expr, new_value);
@@ -1225,15 +1219,14 @@ impl<'a> PeepholeOptimizations {
}
// `new Array(literal)` -> `[literal]`
else if arg.is_literal() || matches!(arg, Expression::ArrayExpression(_)) {
let elements =
ctx.ast.vec1(ArrayExpressionElement::from(arg.take_in(ctx.ast)));
let elements = ctx.ast.vec1(ArrayExpressionElement::from(arg.take_in(ctx)));
let new_value = ctx.ast.expression_array(*span, elements);
ctx.replace_expression(expr, new_value);
}
// `new Array(x)` -> `Array(x)`
else if is_new_expr {
let callee = callee.take_in(ctx.ast);
let args = args.take_in(ctx.ast);
let callee = callee.take_in(ctx);
let args = args.take_in(ctx);
let new_value = ctx.ast.expression_call(*span, callee, NONE, args, false);
ctx.replace_expression(expr, new_value);
}
@@ -1264,8 +1257,7 @@ impl<'a> PeepholeOptimizations {
// `new Array(1, 2, ...xs)` -> `[1, 2, ...xs]`
let elements = ctx.ast.vec_from_iter(
args.iter_mut()
.map(|arg| ArrayExpressionElement::from(arg.take_in(ctx.ast))),
args.iter_mut().map(|arg| ArrayExpressionElement::from(arg.take_in(ctx))),
);
let new_value = ctx.ast.expression_array(*span, elements);
ctx.replace_expression(expr, new_value);
@@ -1307,9 +1299,9 @@ impl<'a> PeepholeOptimizations {
} {
let new_value = ctx.ast.expression_call_with_pure(
e.span,
e.callee.take_in(ctx.ast),
e.callee.take_in(ctx),
NONE,
e.arguments.take_in(ctx.ast),
e.arguments.take_in(ctx),
false,
e.pure,
);
@@ -1442,22 +1434,24 @@ impl<'a> PeepholeOptimizations {
ArrayExpressionElement::SpreadElement(spread_el) => {
new_args.push(ctx.ast.argument_spread_element(
spread_el.span,
spread_el.argument.take_in(ctx.ast),
spread_el.argument.take_in(ctx),
));
}
ArrayExpressionElement::Elision(elision) => {
new_args.push(ctx.ast.void_0(elision.span).into());
}
match_expression!(ArrayExpressionElement) => {
new_args.push(el.to_expression_mut().take_in(ctx.ast).into());
new_args.push(el.to_expression_mut().take_in(ctx).into());
}
}
}
} else {
new_args.push(ctx.ast.argument_spread_element(
spread_el.span,
spread_el.argument.take_in(ctx.ast),
));
new_args.push(
ctx.ast.argument_spread_element(
spread_el.span,
spread_el.argument.take_in(ctx),
),
);
}
} else {
new_args.push(arg);
@@ -1476,27 +1470,27 @@ impl<'a> PeepholeOptimizations {
ChainElement::StaticMemberExpression(member) => {
if let Expression::ChainExpression(chain) = member.object.without_parentheses_mut()
{
let new_value = Expression::from(chain.expression.take_in(ctx.ast));
let new_value = Expression::from(chain.expression.take_in(ctx));
ctx.replace_expression(&mut member.object, new_value);
}
}
ChainElement::ComputedMemberExpression(member) => {
if let Expression::ChainExpression(chain) = member.object.without_parentheses_mut()
{
let new_value = Expression::from(chain.expression.take_in(ctx.ast));
let new_value = Expression::from(chain.expression.take_in(ctx));
ctx.replace_expression(&mut member.object, new_value);
}
}
ChainElement::PrivateFieldExpression(member) => {
if let Expression::ChainExpression(chain) = member.object.without_parentheses_mut()
{
let new_value = Expression::from(chain.expression.take_in(ctx.ast));
let new_value = Expression::from(chain.expression.take_in(ctx));
ctx.replace_expression(&mut member.object, new_value);
}
}
ChainElement::CallExpression(call) => {
if let Expression::ChainExpression(chain) = call.callee.without_parentheses_mut() {
let new_value = Expression::from(chain.expression.take_in(ctx.ast));
let new_value = Expression::from(chain.expression.take_in(ctx));
ctx.replace_expression(&mut call.callee, new_value);
}
}
@@ -1542,7 +1536,7 @@ impl<'a> PeepholeOptimizations {
span,
ctx.ast.vec_from_array([
ctx.ast.expression_numeric_literal(span, 0.0, None, NumberBase::Decimal),
arg_expr.take_in(ctx.ast),
arg_expr.take_in(ctx),
]),
);
ctx.replace_expression(&mut expr.callee, new_callee);
@@ -2014,7 +2008,7 @@ impl<'a> PeepholeOptimizations {
if ctx.state.dce {
return None;
}
let mut taken = body.take_in(ctx.ast);
let mut taken = body.take_in(ctx);
if is_pure {
match &mut taken {
Expression::CallExpression(c) => c.pure = true,
@@ -1,4 +1,4 @@
use oxc_allocator::{Allocator, Box as ArenaBox, Vec as ArenaVec};
use oxc_allocator::{Allocator, Box as ArenaBox, GetAllocator, Vec as ArenaVec};
use oxc_ast::{
AstBuilder,
ast::{Expression, IdentifierReference, Statement},
@@ -717,3 +717,10 @@ impl<'a, State> TraverseCtx<'a, State> {
self.scoping.set_current_block_scope_id(scope_id);
}
}
impl<'a, State> GetAllocator<'a> for TraverseCtx<'a, State> {
#[inline]
fn allocator(&self) -> &'a Allocator {
self.ast.allocator()
}
}
+2 -2
View File
@@ -752,8 +752,8 @@ impl<'a, C: Config> ParserImpl<'a, C> {
}
// Add `ChainExpression` to `a?.c?.b<c>`;
if let Expression::TSInstantiationExpression(mut expr) = lhs {
expr.expression = self
.map_to_chain_expression(expr.expression.span(), expr.expression.take_in(self.ast));
expr.expression =
self.map_to_chain_expression(expr.expression.span(), expr.expression.take_in(self));
Expression::TSInstantiationExpression(expr)
} else {
let span = self.end_span(span);
+8 -1
View File
@@ -87,7 +87,7 @@ mod lexer;
#[doc(hidden)]
pub mod lexer;
use oxc_allocator::{Allocator, Box as ArenaBox, Dummy, Vec as ArenaVec};
use oxc_allocator::{Allocator, Box as ArenaBox, Dummy, GetAllocator, Vec as ArenaVec};
use oxc_ast::{
AstBuilder,
ast::{Expression, Program},
@@ -892,6 +892,13 @@ impl<'a, C: ParserConfig> ParserImpl<'a, C> {
}
}
impl<'a, C: ParserConfig> GetAllocator<'a> for ParserImpl<'a, C> {
#[inline]
fn allocator(&self) -> &'a Allocator {
self.ast.allocator()
}
}
#[cfg(test)]
mod test {
use std::path::Path;
@@ -422,7 +422,7 @@ impl<'a> Traverse<'a, TransformState<'a>> for ArrowFunctionConverter<'a> {
// prop = (() => { return async () => {} })();
// }
// ```
Some(wrap_expression_in_arrow_function_iife(expr.take_in(ctx.ast), ctx))
Some(wrap_expression_in_arrow_function_iife(expr.take_in(ctx), ctx))
}
_ => return,
};
@@ -444,8 +444,7 @@ impl<'a> Traverse<'a, TransformState<'a>> for ArrowFunctionConverter<'a> {
return;
}
let Expression::ArrowFunctionExpression(arrow_function_expr) = expr.take_in(ctx.ast)
else {
let Expression::ArrowFunctionExpression(arrow_function_expr) = expr.take_in(ctx) else {
unreachable!()
};
@@ -745,8 +744,8 @@ impl<'a> ArrowFunctionConverter<'a> {
// The property will as a parameter to pass to the new arrow function.
// `super[property]` to `_superprop_get(property)`
argument = Some(computed_member.expression.take_in(ctx.ast));
computed_member.object.take_in(ctx.ast)
argument = Some(computed_member.expression.take_in(ctx));
computed_member.object.take_in(ctx)
}
MemberExpression::StaticMemberExpression(static_member) => {
if !static_member.object.is_super() {
@@ -755,7 +754,7 @@ impl<'a> ArrowFunctionConverter<'a> {
// Used to generate the name of the arrow function.
property = static_member.property.name.as_str();
expr.take_in(ctx.ast)
expr.take_in(ctx)
}
MemberExpression::PrivateFieldExpression(_) => {
// Private fields can't be accessed by `super`.
@@ -782,7 +781,7 @@ impl<'a> ArrowFunctionConverter<'a> {
}
// _value
if let Some(assign_value) = assign_value {
arguments.push(Argument::from(assign_value.take_in(ctx.ast)));
arguments.push(Argument::from(assign_value.take_in(ctx)));
}
let call = ctx.ast.expression_call(expr.span(), callee, NONE, arguments, false);
Some(call)
@@ -819,7 +818,7 @@ impl<'a> ArrowFunctionConverter<'a> {
// Add `this` as the first argument and original arguments as the rest.
let mut arguments = ctx.ast.vec_with_capacity(call.arguments.len() + 1);
arguments.push(Argument::from(ctx.ast.expression_this(SPAN)));
arguments.extend(call.arguments.take_in(ctx.ast));
arguments.extend(call.arguments.take_in(ctx));
let property = ctx.ast.identifier_name(SPAN, "call");
let callee = ctx.ast.member_expression_static(SPAN, object, property, false);
@@ -856,7 +855,7 @@ impl<'a> ArrowFunctionConverter<'a> {
return None;
}
let assignment_target = assignment.left.take_in(ctx.ast);
let assignment_target = assignment.left.take_in(ctx);
let mut assignment_expr = Expression::from(assignment_target.into_member_expression());
self.transform_member_expression_for_super(
&mut assignment_expr,
@@ -1329,7 +1328,7 @@ impl<'a> ConstructorBodyThisAfterSuperInserter<'a, '_> {
fn transform_super_call_expression(&mut self, expr: &mut Expression<'a>) {
let assignment = self.create_assignment_to_this_temp_var();
let span = expr.span();
let exprs = self.ctx.ast.vec_from_array([expr.take_in(self.ctx.ast), assignment]);
let exprs = self.ctx.ast.vec_from_array([expr.take_in(self.ctx), assignment]);
*expr = self.ctx.ast.expression_sequence(span, exprs);
}
@@ -997,7 +997,7 @@ impl<'a> LegacyDecorator<'a> {
let span = class.span;
class.r#type = ClassType::ClassExpression;
let initializer = Self::get_class_initializer(
Expression::ClassExpression(class.take_in_box(ctx.ast)),
Expression::ClassExpression(class.take_in_box(ctx)),
alias_binding,
ctx,
);
@@ -1254,7 +1254,7 @@ impl<'a> LegacyDecorator<'a> {
decorations.extend(
method
.decorators
.take_in(ctx.ast)
.take_in(ctx)
.into_iter()
.map(|decorator| ArrayExpressionElement::from(decorator.expression)),
);
@@ -1381,7 +1381,7 @@ impl<'a> LegacyDecorator<'a> {
let binding = VarDeclarationsStore::create_uid_var_based_on_node(key, ctx);
let operator = AssignmentOperator::Assign;
let left = binding.create_write_target(ctx);
let right = key.to_expression_mut().take_in(ctx.ast);
let right = key.to_expression_mut().take_in(ctx);
let key_expr = ctx.ast.expression_assignment(SPAN, operator, left, right);
*key = PropertyKey::from(key_expr);
binding.create_read_expression(ctx)
@@ -108,7 +108,7 @@ impl<'a> ExponentiationOperator<'a> {
// `#[inline]` so compiler knows `expr` is a `BinaryExpression`
#[inline]
fn convert_binary_expression(expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
let binary_expr = match expr.take_in(ctx.ast) {
let binary_expr = match expr.take_in(ctx) {
Expression::BinaryExpression(binary_expr) => binary_expr.unbox(),
_ => unreachable!(),
};
@@ -262,7 +262,7 @@ impl<'a> ExponentiationOperator<'a> {
let replacement_left =
AssignmentTarget::ComputedMemberExpression(ctx.ast.alloc_computed_member_expression(
member_expr.span,
member_expr.object.take_in(ctx.ast),
member_expr.object.take_in(ctx),
ctx.ast.expression_string_literal(prop_span, prop_name, None),
false,
));
@@ -342,7 +342,7 @@ impl<'a> ExponentiationOperator<'a> {
let prop = if prop.is_literal() {
prop.clone_in(ctx.ast.allocator)
} else {
let owned_prop = prop.take_in(ctx.ast);
let owned_prop = prop.take_in(ctx);
let binding = self.create_temp_var(owned_prop, &mut temp_var_inits, ctx);
*prop = binding.create_read_expression(ctx);
binding.create_read_expression(ctx)
@@ -504,7 +504,7 @@ impl<'a> ExponentiationOperator<'a> {
}
}
let binding = self.create_temp_var(obj.take_in(ctx.ast), temp_var_inits, ctx);
let binding = self.create_temp_var(obj.take_in(ctx), temp_var_inits, ctx);
*obj = binding.create_read_expression(ctx);
binding.create_read_expression(ctx)
}
@@ -516,7 +516,7 @@ impl<'a> ExponentiationOperator<'a> {
ctx: &mut TraverseCtx<'a>,
) {
let span = assign_expr.span;
let pow_right = assign_expr.right.take_in(ctx.ast);
let pow_right = assign_expr.right.take_in(ctx);
assign_expr.right = Self::math_pow(span, pow_left, pow_right, ctx);
assign_expr.operator = AssignmentOperator::Assign;
}
@@ -530,7 +530,7 @@ impl<'a> ExponentiationOperator<'a> {
) {
if !temp_var_inits.is_empty() {
temp_var_inits.reserve_exact(1);
temp_var_inits.push(expr.take_in(ctx.ast));
temp_var_inits.push(expr.take_in(ctx));
*expr = ctx.ast.expression_sequence(span, temp_var_inits);
}
}
@@ -180,7 +180,7 @@ impl<'a> AsyncToGenerator<'a> {
) -> Option<Expression<'a>> {
// We don't need to handle top-level await.
if Self::is_inside_async_function(ctx) {
Some(ctx.ast.expression_yield(expr.span, false, Some(expr.argument.take_in(ctx.ast))))
Some(ctx.ast.expression_yield(expr.span, false, Some(expr.argument.take_in(ctx))))
} else {
None
}
@@ -307,7 +307,7 @@ impl<'a> AsyncGeneratorExecutor<'a> {
) -> Expression<'a> {
let span = wrapper_function.span;
let body = wrapper_function.body.take().unwrap();
let params = wrapper_function.params.take_in_box(ctx.ast);
let params = wrapper_function.params.take_in_box(ctx);
let id = wrapper_function.id.take();
let has_function_id = id.is_some();
@@ -406,7 +406,7 @@ impl<'a> AsyncGeneratorExecutor<'a> {
}
// Construct the IIFE
let callee = Expression::FunctionExpression(wrapper_function.take_in_box(ctx.ast));
let callee = Expression::FunctionExpression(wrapper_function.take_in_box(ctx));
ctx.ast.expression_call_with_pure(span, callee, NONE, ctx.ast.vec(), false, true)
}
@@ -490,19 +490,19 @@ impl<'a> AsyncGeneratorExecutor<'a> {
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
let arrow_span = arrow.span;
let mut body = arrow.body.take_in_box(ctx.ast);
let mut body = arrow.body.take_in_box(ctx);
// If the arrow's expression is true, we need to wrap the only one expression with return statement.
if arrow.expression {
let statement = body.statements.first_mut().unwrap();
let expression = match statement {
Statement::ExpressionStatement(es) => es.expression.take_in(ctx.ast),
Statement::ExpressionStatement(es) => es.expression.take_in(ctx),
_ => unreachable!(),
};
*statement = ctx.ast.statement_return(expression.span(), Some(expression));
}
let params = arrow.params.take_in_box(ctx.ast);
let params = arrow.params.take_in_box(ctx);
let generator_function_id = arrow.scope_id();
ctx.scoping_mut().scope_flags_mut(generator_function_id).remove(ScopeFlags::Arrow);
let function_name = Self::infer_function_name_from_parent_node(ctx);
@@ -129,7 +129,7 @@ impl<'a> AsyncGeneratorFunctions<'a> {
}
left @ match_assignment_target!(ForStatementLeft) => {
// for await (i of test), for await ({ i } of test)
let target = left.to_assignment_target_mut().take_in(ctx.ast);
let target = left.to_assignment_target_mut().take_in(ctx);
let expression = ctx.ast.expression_assignment(
SPAN,
AssignmentOperator::Assign,
@@ -146,12 +146,12 @@ impl<'a> AsyncGeneratorFunctions<'a> {
let stmt_body = &mut stmt.body;
match stmt_body {
Statement::BlockStatement(block) if block.body.is_empty() => {}
_ => statements.push(stmt_body.take_in(ctx.ast)),
_ => statements.push(stmt_body.take_in(ctx)),
}
statements
};
let iterator = stmt.right.take_in(ctx.ast);
let iterator = stmt.right.take_in(ctx);
let iterator =
helper_call_expr(Helper::AsyncIterator, ctx.ast.vec1(Argument::from(iterator)), ctx);
Self::build_for_await(
@@ -172,7 +172,7 @@ impl<'a> AsyncGeneratorFunctions<'a> {
}
expr.argument.as_mut().map(|argument| {
let argument = Argument::from(argument.take_in(ctx.ast));
let argument = Argument::from(argument.take_in(ctx));
let arguments = ctx.ast.vec1(argument);
let mut argument = helper_call_expr(Helper::AsyncIterator, arguments, ctx);
let arguments = ctx.ast.vec1(Argument::from(argument));
@@ -206,7 +206,7 @@ impl<'a> AsyncGeneratorFunctions<'a> {
return None;
}
let mut argument = expr.argument.take_in(ctx.ast);
let mut argument = expr.argument.take_in(ctx);
let arguments = ctx.ast.vec1(Argument::from(argument));
argument = helper_call_expr(Helper::AwaitAsyncGenerator, arguments, ctx);
@@ -239,7 +239,7 @@ impl<'a> ObjectRestSpread<'a> {
expressions.push(ctx.ast.expression_assignment(
SPAN,
op,
assign_expr.left.take_in(ctx.ast),
assign_expr.left.take_in(ctx),
reference_builder.create_read_expression(ctx),
));
@@ -380,7 +380,7 @@ impl<'a> ObjectRestSpread<'a> {
let mut exprs = vec![];
Self::recursive_walk_assignment_target(&mut assign_expr.left, &mut decls, &mut exprs, ctx);
Self::insert_var_declaration_before_containing_statement(decls, ctx);
let mut expressions = ctx.ast.vec1(expr.take_in(ctx.ast));
let mut expressions = ctx.ast.vec1(expr.take_in(ctx));
expressions.extend(exprs);
*expr = ctx.ast.expression_sequence(SPAN, expressions);
}
@@ -456,7 +456,7 @@ impl<'a> ObjectRestSpread<'a> {
exprs.push(ctx.ast.expression_assignment(
SPAN,
AssignmentOperator::Assign,
pat.take_in(ctx.ast),
pat.take_in(ctx),
bound_identifier.create_read_expression(ctx),
));
*pat = bound_identifier.create_spanned_write_target(SPAN, ctx);
@@ -506,7 +506,7 @@ impl<'a> ObjectRestSpread<'a> {
for prop in obj_expr.properties.drain(..) {
if let ObjectPropertyKind::SpreadProperty(mut spread_prop) = prop {
Self::make_object_spread(&mut call_expr, &mut props, ctx);
let arg = spread_prop.argument.take_in(ctx.ast);
let arg = spread_prop.argument.take_in(ctx);
call_expr.as_mut().unwrap().arguments.push(Argument::from(arg));
} else {
props.push(prop);
@@ -672,7 +672,7 @@ impl<'a> ObjectRestSpread<'a> {
return;
}
let target = left.to_assignment_target_mut();
let assign_left = target.take_in(ctx.ast);
let assign_left = target.take_in(ctx);
let flags = SymbolFlags::FunctionScopedVariable;
let bound_identifier = ctx.generate_uid("ref", ctx.current_hoist_scope_id(), flags);
let id = bound_identifier.create_binding_pattern(ctx);
@@ -705,7 +705,7 @@ impl<'a> ObjectRestSpread<'a> {
(empty_stmt.span, ctx.ast.vec())
} else {
let span = stmt.span();
(span, ctx.ast.vec1(stmt.take_in(ctx.ast)))
(span, ctx.ast.vec1(stmt.take_in(ctx)))
};
*stmt = ctx.ast.statement_block_with_scope_id(span, stmts, scope_id);
scope_id
@@ -1197,7 +1197,7 @@ impl<'a> ReferenceBuilder<'a> {
force_create_binding: bool,
ctx: &mut TraverseCtx<'a>,
) -> Self {
let expr = expr.take_in(ctx.ast);
let expr = expr.take_in(ctx);
let binding;
let maybe_bound_identifier;
match &expr {
@@ -53,7 +53,7 @@ impl<'a> Traverse<'a, TransformState<'a>> for ExportNamespaceFrom {
let mut new_statements = ctx.ast.vec_with_capacity(program.body.len());
for stmt in program.body.take_in(ctx.ast) {
for stmt in program.body.take_in(ctx) {
match stmt {
Statement::ExportAllDeclaration(export_all) if export_all.exported.is_some() => {
// Transform `export * as ns from "mod"` to:
@@ -54,9 +54,7 @@ impl<'a> Traverse<'a, TransformState<'a>> for NullishCoalescingOperator {
}
// Take ownership of the `LogicalExpression`
let Expression::LogicalExpression(logical_expr) = expr.take_in(ctx.ast) else {
unreachable!()
};
let Expression::LogicalExpression(logical_expr) = expr.take_in(ctx) else { unreachable!() };
*expr = self.transform_logical_expression(logical_expr, ctx);
}
@@ -259,7 +259,7 @@ impl<'a> OptionalChaining<'a> {
expr: &mut Expression<'a>,
ctx: &TraverseCtx<'a>,
) -> Expression<'a> {
let Expression::ChainExpression(chain_expr) = expr.take_in(ctx.ast) else { unreachable!() };
let Expression::ChainExpression(chain_expr) = expr.take_in(ctx) else { unreachable!() };
match chain_expr.unbox().expression {
element @ match_member_expression!(ChainElement) => {
Expression::from(element.into_member_expression())
@@ -284,7 +284,7 @@ impl<'a> OptionalChaining<'a> {
// To insert the temp binding in the correct scope, we wrap the expression with
// an arrow function. During the chain expression transformation, the temp binding
// will be inserted into the arrow function's body.
wrap_expression_in_arrow_function_iife(expr.take_in(ctx.ast), ctx)
wrap_expression_in_arrow_function_iife(expr.take_in(ctx), ctx)
} else {
self.transform_chain_expression_impl(false, expr, ctx)
}
@@ -298,7 +298,7 @@ impl<'a> OptionalChaining<'a> {
) {
*expr = if self.is_inside_function_parameter {
// Same as the above `transform_chain_expression` explanation
wrap_expression_in_arrow_function_iife(expr.take_in(ctx.ast), ctx)
wrap_expression_in_arrow_function_iife(expr.take_in(ctx), ctx)
} else {
// Unfortunately no way to get compiler to see that this branch is provably unreachable.
// We don't want to inline this function, to keep `enter_expression` as small as possible.
@@ -376,7 +376,7 @@ impl<'a> OptionalChaining<'a> {
let binding = VarDeclarationsStore::create_uid_var_based_on_node(object, ctx);
*object = Self::create_assignment_expression(
binding.create_write_target(ctx),
object.take_in(ctx.ast),
object.take_in(ctx),
ctx,
);
binding.create_read_expression(ctx)
@@ -491,7 +491,7 @@ impl<'a> OptionalChaining<'a> {
&& self.should_specify_context(ident, ctx)
{
// `foo$bar(...)` -> `foo$bar.call(context, ...)`
let callee = callee.take_in(ctx.ast);
let callee = callee.take_in(ctx);
let property = ctx.ast.identifier_name(SPAN, "call");
let member =
ctx.ast.member_expression_static(SPAN, callee, property, false);
@@ -537,7 +537,7 @@ impl<'a> OptionalChaining<'a> {
if ident.name == "eval" {
// `eval?.()` is an indirect eval call transformed to `(0,eval)()`
let zero = ctx.ast.number_0();
let original_callee = expr.take_in(ctx.ast);
let original_callee = expr.take_in(ctx);
let expressions = ctx.ast.vec_from_array([zero, original_callee]);
*expr = ctx.ast.expression_sequence(SPAN, expressions);
}
@@ -653,7 +653,7 @@ impl<'a> OptionalChaining<'a> {
// `(_foo = foo)`
*object = Self::create_assignment_expression(
binding.create_write_target(ctx),
object.take_in(ctx.ast),
object.take_in(ctx),
ctx,
);
binding.to_maybe_bound_identifier()
@@ -125,7 +125,7 @@ impl<'a> LogicalAssignmentOperators {
let span = assignment_expr.span;
let assign_op = AssignmentOperator::Assign;
let right = assignment_expr.right.take_in(ctx.ast);
let right = assignment_expr.right.take_in(ctx);
let right = ctx.ast.expression_assignment(SPAN, assign_op, assign_target, right);
let logical_expr = ctx.ast.expression_logical(span, left_expr, operator, right);
@@ -153,7 +153,7 @@ impl<'a> LogicalAssignmentOperators {
static_expr: &mut StaticMemberExpression<'a>,
ctx: &mut TraverseCtx<'a>,
) -> (Expression<'a>, AssignmentTarget<'a>) {
let object = static_expr.object.take_in(ctx.ast);
let object = static_expr.object.take_in(ctx);
let (object, object_ref) = duplicate_expression(object, true, ctx);
let left_expr = Expression::from(ctx.ast.member_expression_static(
@@ -180,10 +180,10 @@ impl<'a> LogicalAssignmentOperators {
computed_expr: &mut ComputedMemberExpression<'a>,
ctx: &mut TraverseCtx<'a>,
) -> (Expression<'a>, AssignmentTarget<'a>) {
let object = computed_expr.object.take_in(ctx.ast);
let object = computed_expr.object.take_in(ctx);
let (object, object_ref) = duplicate_expression(object, true, ctx);
let expression = computed_expr.expression.take_in(ctx.ast);
let expression = computed_expr.expression.take_in(ctx);
let (expression, expression_ref) = duplicate_expression(expression, true, ctx);
let left_expr = Expression::from(ctx.ast.member_expression_computed(
@@ -718,7 +718,7 @@ impl<'a> ClassProperties<'a> {
}
// `_Class = class {}`
let class_expr = expr.take_in(ctx.ast);
let class_expr = expr.take_in(ctx);
let assignment = create_assignment(binding, class_expr, SPAN, ctx);
if exprs.is_empty() && self.insert_after_exprs.is_empty() {
@@ -747,7 +747,7 @@ impl<'a> ClassProperties<'a> {
return;
}
let class_expr = expr.take_in(ctx.ast);
let class_expr = expr.take_in(ctx);
exprs.push(class_expr);
}
@@ -36,7 +36,7 @@ impl<'a> ClassProperties<'a> {
// 3. At least one property satisfying the above is after this method,
// or class contains a static block which is being transformed
// (static blocks are always evaluated after computed keys, regardless of order)
let original_key = key.take_in(ctx.ast);
let original_key = key.take_in(ctx);
let (assignment, temp_var) = create_computed_key_temp_var(original_key, ctx);
self.insert_before.push(assignment);
method.key = PropertyKey::from(temp_var);
@@ -64,7 +64,7 @@ impl<'a> ClassProperties<'a> {
is_static: bool,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
let original_key = key.take_in(ctx.ast);
let original_key = key.take_in(ctx);
if key_needs_temp_var(&original_key, ctx) {
let (assignment, ident) = create_computed_key_temp_var(original_key, ctx);
if is_static {
@@ -103,7 +103,7 @@ impl<'a> ClassProperties<'a> {
};
if key_needs_temp_var(key, ctx) {
self.insert_before.push(key.take_in(ctx.ast));
self.insert_before.push(key.take_in(ctx));
}
}
@@ -158,7 +158,7 @@ impl<'a> ClassProperties<'a> {
}
// Extract assignment from computed key and insert before class
let assignment = prop.key.take_in(ctx.ast).into_expression();
let assignment = prop.key.take_in(ctx).into_expression();
self.insert_before.push(assignment);
}
}
@@ -577,7 +577,7 @@ impl<'a> ConstructorParamsSuperReplacer<'a, '_> {
});
let ctx = &mut *self.ctx;
let super_call = expr.take_in(ctx.ast);
let super_call = expr.take_in(ctx);
*expr = ctx.ast.expression_call(
span,
Expression::from(ctx.ast.member_expression_static(
@@ -62,7 +62,7 @@ impl<'a> ClassProperties<'a> {
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
let span = field_expr.span;
let object = field_expr.object.take_in(ctx.ast);
let object = field_expr.object.take_in(ctx);
let resolved = if is_assignment {
match self.classes_stack.find_writable_private_prop(&field_expr.field) {
Some(prop) => prop,
@@ -266,7 +266,7 @@ impl<'a> ClassProperties<'a> {
// `object.#prop(arg)` -> `_classPrivateFieldLooseBase(object, _prop)[_prop](arg)`
let prop_binding = self.classes_stack.find_private_prop(&field_expr.field).prop_binding;
let object = field_expr.object.take_in(ctx.ast);
let object = field_expr.object.take_in(ctx);
call_expr.callee = Expression::from(Self::create_private_field_member_expr_loose(
object,
prop_binding,
@@ -332,7 +332,7 @@ impl<'a> ClassProperties<'a> {
let span = field_expr.span;
// `(object.#method)()`
// ^^^^^^^^^^^^^^^^ is a parenthesized expression
let object = field_expr.object.get_inner_expression_mut().take_in(ctx.ast);
let object = field_expr.object.get_inner_expression_mut().take_in(ctx);
let Some(ResolvedPrivateProp {
prop_binding,
@@ -494,7 +494,7 @@ impl<'a> ClassProperties<'a> {
if self.private_fields_as_properties {
// `object.#prop = value` -> `_classPrivateFieldLooseBase(object, _prop)[_prop] = value`
// Same for all other assignment operators e.g. `+=`, `&&=`, `??=`.
let object = field_expr.object.take_in(ctx.ast);
let object = field_expr.object.take_in(ctx);
let replacement = Self::create_private_field_member_expr_loose(
object,
// At least one of `get_binding` or `set_binding` is always present
@@ -630,7 +630,7 @@ impl<'a> ClassProperties<'a> {
if let Some(operator) = operator.to_binary_operator() {
// `Class.#prop += value` -> `_prop._ = _prop._ + value`
let value = assign_expr.right.take_in(ctx.ast);
let value = assign_expr.right.take_in(ctx);
assign_expr.operator = AssignmentOperator::Assign;
assign_expr.right = ctx.ast.expression_binary(SPAN, prop_obj, operator, value);
} else if let Some(operator) = operator.to_logical_operator() {
@@ -638,7 +638,7 @@ impl<'a> ClassProperties<'a> {
let span = assign_expr.span;
assign_expr.span = SPAN;
assign_expr.operator = AssignmentOperator::Assign;
let right = expr.take_in(ctx.ast);
let right = expr.take_in(ctx);
*expr = ctx.ast.expression_logical(span, prop_obj, operator, right);
} else {
// The above covers all types of `AssignmentOperator`
@@ -660,7 +660,7 @@ impl<'a> ClassProperties<'a> {
let object = field_expr.object.into_inner_expression();
let class_ident = class_binding.create_read_expression(ctx);
let value = assign_expr.right.take_in(ctx.ast);
let value = assign_expr.right.take_in(ctx);
if operator == AssignmentOperator::Assign {
// Replace right side of assignment with `_assertClassBrand(Class, object, _prop)`
@@ -717,7 +717,7 @@ impl<'a> ClassProperties<'a> {
assign_expr.operator = AssignmentOperator::Assign;
assign_expr.right =
self.create_assert_class_brand(class_ident2, object2, value, SPAN, ctx);
let right = expr.take_in(ctx.ast);
let right = expr.take_in(ctx);
// `_assertClassBrand(Class, object, _prop)._ && (_prop._ = _assertClassBrand(Class, object, value))`
*expr = ctx.ast.expression_logical(span, left, operator, right);
} else {
@@ -749,7 +749,7 @@ impl<'a> ClassProperties<'a> {
class_binding: Option<&BoundIdentifier<'a>>,
ctx: &mut TraverseCtx<'a>,
) {
let assign_expr = match expr.take_in(ctx.ast) {
let assign_expr = match expr.take_in(ctx) {
Expression::AssignmentExpression(assign_expr) => assign_expr.unbox(),
_ => unreachable!(),
};
@@ -921,7 +921,7 @@ impl<'a> ClassProperties<'a> {
if self.private_fields_as_properties {
let prop_binding = self.classes_stack.find_private_prop(&field_expr.field).prop_binding;
// `object.#prop++` -> `_classPrivateFieldLooseBase(object, _prop)[_prop]++`
let object = field_expr.object.take_in(ctx.ast);
let object = field_expr.object.take_in(ctx);
let replacement = Self::create_private_field_member_expr_loose(
object,
prop_binding,
@@ -946,7 +946,7 @@ impl<'a> ClassProperties<'a> {
// TODO(improve-on-babel): Could avoid `move_expression` here and replace `update_expr.argument` instead.
// Only doing this first to match the order Babel creates temp vars.
let object = field_expr.object.get_inner_expression_mut().take_in(ctx.ast);
let object = field_expr.object.get_inner_expression_mut().take_in(ctx);
if is_static && !is_method {
// Unwrap is safe because `is_method` is false, then private prop is always have a `get_binding`
@@ -1018,7 +1018,7 @@ impl<'a> ClassProperties<'a> {
let UpdateExpression { span, prefix, .. } = **update_expr;
update_expr.span = SPAN;
update_expr.argument = temp_binding.create_read_write_simple_target(ctx);
let update_expr = expr.take_in(ctx.ast);
let update_expr = expr.take_in(ctx);
if prefix {
// Source = `++object.#prop` (prefix `++`)
@@ -1114,7 +1114,7 @@ impl<'a> ClassProperties<'a> {
let UpdateExpression { span, prefix, .. } = **update_expr;
update_expr.span = SPAN;
update_expr.argument = temp_binding.create_read_write_simple_target(ctx);
let update_expr = expr.take_in(ctx.ast);
let update_expr = expr.take_in(ctx);
if prefix {
// Source = `++object.#prop` (prefix `++`)
@@ -1367,7 +1367,7 @@ impl<'a> ClassProperties<'a> {
// `o?.Foo.#self.self?.self.unicorn;` -> `(result ? void 0 : object)?.self.unicorn`
// ^^^^^^^^^^^^^^^^^ the object has transformed, if the current member is optional,
// then we need to wrap it to a conditional expression
let owned_object = object.take_in(ctx.ast);
let owned_object = object.take_in(ctx);
*object = Self::wrap_conditional_check(result, owned_object, ctx);
None
} else {
@@ -1389,7 +1389,7 @@ impl<'a> ClassProperties<'a> {
// `Foo.bar.#m?.();` -> `_assertClassBrand(Foo, _Foo$bar = Foo.bar, _m)._?.call(_Foo$bar);`
// ^^^^ only the private field is optional
// Move out parenthesis and typescript syntax
call_expr.callee = callee.take_in(ctx.ast);
call_expr.callee = callee.take_in(ctx);
self.transform_call_expression_impl(call_expr, ctx);
return result;
}
@@ -1407,9 +1407,9 @@ impl<'a> ClassProperties<'a> {
// TODO(improve-on-babel): Consider remove this logic, because it seems no runtime behavior change.
let result = result?;
let object = callee.to_member_expression_mut().object_mut();
let (assignment, context) = self.duplicate_object(object.take_in(ctx.ast), ctx);
let (assignment, context) = self.duplicate_object(object.take_in(ctx), ctx);
*object = assignment;
let callee = call_expr.callee.take_in(ctx.ast);
let callee = call_expr.callee.take_in(ctx);
let callee = Self::wrap_conditional_check(result, callee, ctx);
Self::substitute_callee_and_insert_context(call_expr, callee, context, ctx);
@@ -1430,7 +1430,7 @@ impl<'a> ClassProperties<'a> {
object: &mut Expression<'a>,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
let mut owned_object = object.get_inner_expression_mut().take_in(ctx.ast);
let mut owned_object = object.get_inner_expression_mut().take_in(ctx);
let owned_object = if let Some(result) =
self.transform_chain_element_recursively(&mut owned_object, ctx)
@@ -1460,7 +1460,7 @@ impl<'a> ClassProperties<'a> {
expr: &mut Expression<'a>,
ctx: &TraverseCtx<'a>,
) -> Expression<'a> {
let Expression::ChainExpression(chain_expr) = expr.take_in(ctx.ast) else { unreachable!() };
let Expression::ChainExpression(chain_expr) = expr.take_in(ctx) else { unreachable!() };
match chain_expr.unbox().expression {
element @ match_member_expression!(ChainElement) => {
Expression::from(element.into_member_expression())
@@ -1562,8 +1562,8 @@ impl<'a> ClassProperties<'a> {
if is_optional_callee {
// `o?.Foo.#self?.getSelf?.().#x;` -> `(_ref$getSelf = (_ref2 = _ref = o === null || o === void 0 ?
// ^^ is optional void 0 : babelHelpers.assertClassBrand(Foo, o.Foo, _self)._)`
*object = Self::wrap_conditional_check(result, object.take_in(ctx.ast), ctx);
let (assignment, context) = self.duplicate_object(object.take_in(ctx.ast), ctx);
*object = Self::wrap_conditional_check(result, object.take_in(ctx), ctx);
let (assignment, context) = self.duplicate_object(object.take_in(ctx), ctx);
*object = assignment;
context
} else {
@@ -1572,9 +1572,9 @@ impl<'a> ClassProperties<'a> {
// ^^^^^^^^^^^^^^^^^^^^^^ to make sure get `getSelf` call has a proper context, we need to assign
// the parent of callee (i.e `o?.Foo.#self`) to a temp variable,
// and then use it as a first argument of `_ref.call`.
let (assignment, context) = self.duplicate_object(object.take_in(ctx.ast), ctx);
let (assignment, context) = self.duplicate_object(object.take_in(ctx), ctx);
*object = assignment;
*callee = Self::wrap_conditional_check(result, callee.take_in(ctx.ast), ctx);
*callee = Self::wrap_conditional_check(result, callee.take_in(ctx), ctx);
context
}
} else {
@@ -1582,14 +1582,14 @@ impl<'a> ClassProperties<'a> {
// ^^^^^^^^^^^^^^^^ this is a optional function call, to make sure it has a proper context,
// we also need to assign `Foo?.bar()` to a temp variable, and then use
// it as a first argument of `_Foo$bar$zoo`.
let (assignment, context) = self.duplicate_object(object.take_in(ctx.ast), ctx);
let (assignment, context) = self.duplicate_object(object.take_in(ctx), ctx);
*object = assignment;
context
};
// After the below transformation, the `callee` will be a temp variable.
let result = self.transform_expression_to_wrap_nullish_check(callee, ctx);
let owned_callee = callee.take_in(ctx.ast);
let owned_callee = callee.take_in(ctx);
Self::substitute_callee_and_insert_context(call, owned_callee, context, ctx);
result
}
@@ -1687,7 +1687,7 @@ impl<'a> ClassProperties<'a> {
{
// We still need this unary expr, but it needs to be used as the alternative of the conditional
unary_expr.argument = chain_expr;
expr.take_in(ctx.ast)
expr.take_in(ctx)
},
);
}
@@ -1747,7 +1747,7 @@ impl<'a> ClassProperties<'a> {
// But this is not needed, so we omit it.
let prop_binding = self.classes_stack.find_private_prop(&field_expr.field).prop_binding;
let object = field_expr.object.take_in(ctx.ast);
let object = field_expr.object.take_in(ctx);
let replacement = Self::create_private_field_member_expr_loose(
object,
prop_binding,
@@ -1836,7 +1836,7 @@ impl<'a> ClassProperties<'a> {
expr: &mut Expression<'a>,
ctx: &mut TraverseCtx<'a>,
) {
let Expression::PrivateInExpression(private_in) = expr.take_in(ctx.ast) else {
let Expression::PrivateInExpression(private_in) = expr.take_in(ctx) else {
unreachable!();
};
@@ -52,7 +52,7 @@ impl<'a> ClassProperties<'a> {
return None;
};
let mut function = value.take_in_box(ctx.ast);
let mut function = value.take_in_box(ctx);
let resolved_private_prop = if *kind == MethodDefinitionKind::Set {
self.classes_stack.find_writable_private_prop(ident)
@@ -86,7 +86,7 @@ impl<'a> ClassProperties<'a> {
let outer_scope_id = ctx.current_scope_id();
ctx.scoping_mut().change_scope_parent_id(scope_id, Some(outer_scope_id));
wrap_statements_in_arrow_function_iife(stmts.take_in(ctx.ast), scope_id, block.span, ctx)
wrap_statements_in_arrow_function_iife(stmts.take_in(ctx), scope_id, block.span, ctx)
}
fn convert_static_block_with_single_expression_to_expression(
@@ -99,7 +99,7 @@ impl<'a> ClassProperties<'a> {
let mut replacer = StaticVisitor::new(make_sloppy_mode, true, self, ctx);
replacer.visit_expression(expr);
expr.take_in(ctx.ast)
expr.take_in(ctx)
}
/// Replace reference to class name with reference to temp var for class.
@@ -92,7 +92,7 @@ impl<'a> ClassPropertiesSuperConverter<'a, '_> {
is_callee: bool,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
let property = member.expression.take_in(ctx.ast);
let property = member.expression.take_in(ctx);
self.create_super_prop_get(member.span, property, is_callee, ctx)
}
@@ -207,7 +207,7 @@ impl<'a> ClassPropertiesSuperConverter<'a, '_> {
expr: &mut Expression<'a>,
ctx: &mut TraverseCtx<'a>,
) {
let Expression::AssignmentExpression(assign_expr) = expr.take_in(ctx.ast) else {
let Expression::AssignmentExpression(assign_expr) = expr.take_in(ctx) else {
unreachable!()
};
let AssignmentExpression { span, operator, right: value, left, .. } = assign_expr.unbox();
@@ -235,7 +235,7 @@ impl<'a> ClassPropertiesSuperConverter<'a, '_> {
expr: &mut Expression<'a>,
ctx: &mut TraverseCtx<'a>,
) {
let Expression::AssignmentExpression(assign_expr) = expr.take_in(ctx.ast) else {
let Expression::AssignmentExpression(assign_expr) = expr.take_in(ctx) else {
unreachable!()
};
let AssignmentExpression { span, operator, right: value, left, .. } = assign_expr.unbox();
@@ -370,7 +370,7 @@ impl<'a> ClassPropertiesSuperConverter<'a, '_> {
expr: &mut Expression<'a>,
ctx: &mut TraverseCtx<'a>,
) {
let Expression::UpdateExpression(mut update_expr) = expr.take_in(ctx.ast) else {
let Expression::UpdateExpression(mut update_expr) = expr.take_in(ctx) else {
unreachable!()
};
let SimpleAssignmentTarget::StaticMemberExpression(member) = &mut update_expr.argument
@@ -433,7 +433,7 @@ impl<'a> ClassPropertiesSuperConverter<'a, '_> {
expr: &mut Expression<'a>,
ctx: &mut TraverseCtx<'a>,
) {
let Expression::UpdateExpression(mut update_expr) = expr.take_in(ctx.ast) else {
let Expression::UpdateExpression(mut update_expr) = expr.take_in(ctx) else {
unreachable!()
};
let SimpleAssignmentTarget::ComputedMemberExpression(member) = &mut update_expr.argument
@@ -443,7 +443,7 @@ impl<'a> ClassPropertiesSuperConverter<'a, '_> {
let temp_var_name_base = get_var_name_from_node(member.as_ref());
let property = member.expression.get_inner_expression_mut().take_in(ctx.ast);
let property = member.expression.get_inner_expression_mut().take_in(ctx);
*expr = self.transform_super_update_expression_impl(
&temp_var_name_base,
@@ -162,7 +162,7 @@ impl ClassStaticBlock {
// Always strict mode since we're in a class.
*ctx.scoping_mut().scope_flags_mut(scope_id) =
ScopeFlags::Function | ScopeFlags::Arrow | ScopeFlags::StrictMode;
wrap_statements_in_arrow_function_iife(stmts.take_in(ctx.ast), scope_id, block.span, ctx)
wrap_statements_in_arrow_function_iife(stmts.take_in(ctx), scope_id, block.span, ctx)
}
/// Convert static block to expression which will be value of private field,
@@ -173,7 +173,7 @@ impl ClassStaticBlock {
scope_id: ScopeId,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
let expr = expr.take_in(ctx.ast);
let expr = expr.take_in(ctx);
// Remove the scope for the static block from the scope chain
ctx.remove_scope_for_expression(scope_id, &expr);
@@ -134,7 +134,7 @@ impl<'a> Traverse<'a, TransformState<'a>> for ExplicitResourceManagement<'a> {
for_of_init_symbol_id,
);
let old_body = for_of_stmt.body.take_in(ctx.ast);
let old_body = for_of_stmt.body.take_in(ctx);
let new_body = ctx.ast.vec_from_array([using_stmt, old_body]);
for_of_stmt.body = ctx.ast.statement_block_with_scope_id(SPAN, new_body, scope_id);
return;
@@ -161,7 +161,7 @@ impl<'a> Traverse<'a, TransformState<'a>> for ExplicitResourceManagement<'a> {
for_of_init_symbol_id,
);
let old_body = for_of_stmt.body.take_in(ctx.ast);
let old_body = for_of_stmt.body.take_in(ctx);
let new_body = ctx.ast.vec_from_array([using_stmt, old_body]);
for_of_stmt.body = ctx.ast.statement_block_with_scope_id(SPAN, new_body, scope_id);
@@ -364,7 +364,7 @@ impl<'a> Traverse<'a, TransformState<'a>> for ExplicitResourceManagement<'a> {
return;
}
let program_body = program.body.take_in(ctx.ast);
let program_body = program.body.take_in(ctx);
let (mut program_body, inner_block): (
ArenaVec<'a, Statement<'a>>,
@@ -471,7 +471,7 @@ impl<'a> Traverse<'a, TransformState<'a>> for ExplicitResourceManagement<'a> {
return (program_body, inner_block);
}
let export_specifiers = match decl.take_in(ctx.ast) {
let export_specifiers = match decl.take_in(ctx) {
Declaration::ClassDeclaration(class_decl) => {
let class_binding = class_decl.id.as_ref().unwrap();
let class_binding_name = class_binding.name;
@@ -724,7 +724,7 @@ impl<'a> ExplicitResourceManagement<'a> {
)),
false,
)),
stmt.take_in(ctx.ast),
stmt.take_in(ctx),
]);
ctx.ast.block_statement_with_scope_id(SPAN, vec, block_stmt_sid)
@@ -819,7 +819,7 @@ impl<'a> ExplicitResourceManagement<'a> {
let using_ctx = using_ctx?;
let mut stmts = stmts.take_in(ctx.ast);
let mut stmts = stmts.take_in(ctx);
// `var _usingCtx = babelHelpers.usingCtx();`
let callee = helper_load(Helper::UsingCtx, ctx);
+1 -1
View File
@@ -526,7 +526,7 @@ impl<'a> Traverse<'a, TransformState<'a>> for JsxImpl<'a> {
if !expr.is_jsx() {
return;
}
*expr = match expr.take_in(ctx.ast) {
*expr = match expr.take_in(ctx) {
Expression::JSXElement(e) => self.transform_jsx_element(e, ctx),
Expression::JSXFragment(e) => self.transform_jsx(e.span, None, e.unbox().children, ctx),
_ => unreachable!(),
+3 -3
View File
@@ -148,7 +148,7 @@ impl<'a> Traverse<'a, TransformState<'a>> for ReactRefresh<'a> {
self.used_in_jsx_bindings = UsedInJSXBindingsCollector::collect(program, ctx);
let mut new_statements = ctx.ast.vec_with_capacity(program.body.len() * 2);
for mut statement in program.body.take_in(ctx.ast) {
for mut statement in program.body.take_in(ctx) {
let next_statement = self.process_statement(&mut statement, ctx);
new_statements.push(statement);
if let Some(assignment_expression) = next_statement {
@@ -258,7 +258,7 @@ impl<'a> Traverse<'a, TransformState<'a>> for ReactRefresh<'a> {
}
let span = expr.span();
arguments.insert(0, Argument::from(expr.take_in(ctx.ast)));
arguments.insert(0, Argument::from(expr.take_in(ctx)));
*expr = ctx.ast.expression_call(
span,
binding.create_read_expression(ctx),
@@ -532,7 +532,7 @@ impl<'a> ReactRefresh<'a> {
SPAN,
AssignmentOperator::Assign,
self.create_registration(ctx.ast.str(inferred_name), ctx),
expr.take_in(ctx.ast),
expr.take_in(ctx),
);
}
+1 -1
View File
@@ -645,7 +645,7 @@ impl<'a> Traverse<'a, TransformState<'a>> for TransformerImpl<'a> {
let Statement::ExpressionStatement(expr_stmt) = stmt else {
continue;
};
let expression = Some(expr_stmt.expression.take_in(ctx.ast));
let expression = Some(expr_stmt.expression.take_in(ctx));
*stmt = ctx.ast.statement_return(SPAN, expression);
return;
}
@@ -411,7 +411,7 @@ impl<'a> StyledComponents<'a> {
quasi: TemplateLiteral { span: quasi_span, quasis, expressions, .. },
type_arguments,
..
} = expr.take_in(ctx.ast);
} = expr.take_in(ctx);
let quasis_elements = ctx.ast.vec_from_iter(quasis.into_iter().map(|quasi| {
ArrayExpressionElement::from(ctx.ast.expression_string_literal(
@@ -455,7 +455,7 @@ impl<'a> StyledComponents<'a> {
self.add_properties(&mut properties, ctx);
let object = ctx.ast.alloc_object_expression(SPAN, properties);
let arguments = ctx.ast.vec1(Argument::ObjectExpression(object));
let object = expr.take_in(ctx.ast);
let object = expr.take_in(ctx);
let property = ctx.ast.identifier_name(SPAN, "withConfig");
let callee =
Expression::from(ctx.ast.member_expression_static(SPAN, object, property, false));
@@ -83,7 +83,7 @@ impl<'a> TaggedTemplateTransform {
return;
}
let Expression::TaggedTemplateExpression(tagged) = expr.take_in(ctx.ast) else {
let Expression::TaggedTemplateExpression(tagged) = expr.take_in(ctx) else {
unreachable!();
};
@@ -190,7 +190,7 @@ impl<'a> Traverse<'a, TransformState<'a>> for TypeScriptAnnotations<'a> {
fn enter_chain_element(&mut self, element: &mut ChainElement<'a>, ctx: &mut TraverseCtx<'a>) {
if let ChainElement::TSNonNullExpression(e) = element {
*element = match e.expression.get_inner_expression_mut().take_in(ctx.ast) {
*element = match e.expression.get_inner_expression_mut().take_in(ctx) {
Expression::CallExpression(call_expr) => ChainElement::CallExpression(call_expr),
expr @ match_member_expression!(Expression) => {
ChainElement::from(expr.into_member_expression())
@@ -249,7 +249,7 @@ impl<'a> Traverse<'a, TransformState<'a>> for TypeScriptAnnotations<'a> {
fn enter_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
if expr.is_typescript_syntax() {
let inner_expr = expr.get_inner_expression_mut();
*expr = inner_expr.take_in(ctx.ast);
*expr = inner_expr.take_in(ctx);
}
}
@@ -262,7 +262,7 @@ impl<'a> Traverse<'a, TransformState<'a>> for TypeScriptAnnotations<'a> {
match expr.get_inner_expression_mut() {
// `foo!++` to `foo++`
inner_expr @ Expression::Identifier(_) => {
let inner_expr = inner_expr.take_in(ctx.ast);
let inner_expr = inner_expr.take_in(ctx);
let Expression::Identifier(ident) = inner_expr else {
unreachable!();
};
@@ -270,7 +270,7 @@ impl<'a> Traverse<'a, TransformState<'a>> for TypeScriptAnnotations<'a> {
}
// `foo.bar!++` to `foo.bar++`
inner_expr @ match_member_expression!(Expression) => {
let inner_expr = inner_expr.take_in(ctx.ast);
let inner_expr = inner_expr.take_in(ctx);
let member_expr = inner_expr.into_member_expression();
*target = SimpleAssignmentTarget::from(member_expr);
}
@@ -290,7 +290,7 @@ impl<'a> Traverse<'a, TransformState<'a>> for TypeScriptAnnotations<'a> {
if let Some(expr) = target.get_expression_mut() {
let inner_expr = expr.get_inner_expression_mut();
if inner_expr.is_member_expression() {
let inner_expr = inner_expr.take_in(ctx.ast);
let inner_expr = inner_expr.take_in(ctx);
let member_expr = inner_expr.into_member_expression();
*target = AssignmentTarget::from(member_expr);
}
@@ -412,7 +412,7 @@ impl<'a> Traverse<'a, TransformState<'a>> for TypeScriptAnnotations<'a> {
_ => None,
};
if let Some(span) = consequent_span {
let consequent = stmt.consequent.take_in(ctx.ast);
let consequent = stmt.consequent.take_in(ctx);
stmt.consequent = Self::create_block_with_statement(consequent, span, ctx);
}
@@ -146,7 +146,7 @@ impl<'a> TypeScript<'a> {
// When `remove_class_fields_without_initializer` is true, the property without initializer
// would be removed in the `transform_class_on_exit`. We need to make sure the computed key
// keeps and is evaluated in the same order as the original class field in static block.
computed_key_assignments.push(key.take_in(ctx.ast));
computed_key_assignments.push(key.take_in(ctx));
}
}
}
@@ -449,12 +449,12 @@ impl<'a> TypeScript<'a> {
// `class C { 'x' = true; 123 = false; }`
// No temp var is created for these.
let new_key = if key_needs_temp_var(key, ctx) {
let taken_key = key.take_in(ctx.ast);
let taken_key = key.take_in(ctx);
let (assignment, ident) = create_computed_key_temp_var(taken_key, ctx);
computed_key_assignments.push(assignment);
ident
} else {
key.take_in(ctx.ast)
key.take_in(ctx)
};
ctx.ast.member_expression_computed(
@@ -523,7 +523,7 @@ impl<'a> TypeScript<'a> {
if let Some(key) = key.as_expression_mut() {
// If the key is already an expression, we need to create a new expression sequence
// to insert the assignments into.
let original_key = key.take_in(ctx.ast);
let original_key = key.take_in(ctx);
let new_key = ctx.ast.expression_sequence(
SPAN,
ctx.ast.vec_from_iter(
@@ -321,7 +321,7 @@ impl<'a> TypeScriptEnum {
let mut prev_member_name = None;
for member in members.take_in(ctx.ast) {
for member in members.take_in(ctx) {
let member_span = member.span;
let member_name = member.id.static_name();
@@ -79,7 +79,7 @@ impl<'a> TypeScriptModule {
};
let left = AssignmentTarget::from(SimpleAssignmentTarget::from(module_exports));
let right = export_assignment.expression.take_in(ctx.ast);
let right = export_assignment.expression.take_in(ctx);
let assignment_expr =
ctx.ast.expression_assignment(SPAN, AssignmentOperator::Assign, left, right);
ctx.ast.statement_expression(SPAN, assignment_expr)
@@ -42,7 +42,7 @@ impl<'a> Traverse<'a, TransformState<'a>> for TypeScriptNamespace {
// pass-through statements.
let mut new_stmts = ctx.ast.vec_with_capacity(program.body.len());
for stmt in program.body.take_in(ctx.ast) {
for stmt in program.body.take_in(ctx) {
match stmt {
Statement::TSModuleDeclaration(decl) => {
if !self.allow_namespaces {
@@ -467,7 +467,7 @@ impl<'a> TypeScriptNamespace {
false,
))
.into(),
init.take_in(ctx.ast),
init.take_in(ctx),
),
);
}
@@ -245,7 +245,7 @@ impl<'a> ModuleRunnerTransform<'a> {
/// Transform `import(source, ...arguments)` to `__vite_ssr_dynamic_import__(source, ...arguments)`.
#[inline]
fn transform_dynamic_import(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
let Expression::ImportExpression(import_expr) = expr.take_in(ctx.ast) else {
let Expression::ImportExpression(import_expr) = expr.take_in(ctx) else {
unreachable!();
};
@@ -268,7 +268,7 @@ impl<'a> VisitMut<'a> for ReplaceGlobalDefines<'a> {
// leaving an invalid `ChainExpression` with no optional elements.
// Unwrap it to a plain expression to produce a valid AST.
if matches!(expr, Expression::ChainExpression(_)) {
Self::unwrap_chain_expression_if_no_optional(self.allocator, expr);
self.unwrap_chain_expression_if_no_optional(expr);
}
}
@@ -692,7 +692,7 @@ impl<'a> ReplaceGlobalDefines<'a> {
/// If `expr` is a `ChainExpression` whose chain no longer contains any
/// `optional: true` markers (because a define replacement removed them),
/// unwrap it to a plain expression.
fn unwrap_chain_expression_if_no_optional(allocator: &'a Allocator, expr: &mut Expression<'a>) {
fn unwrap_chain_expression_if_no_optional(&self, expr: &mut Expression<'a>) {
let Expression::ChainExpression(chain) = &*expr else { return };
// Check the chain element's optional flag and get the first object/callee to walk.
@@ -740,7 +740,7 @@ impl<'a> ReplaceGlobalDefines<'a> {
}
// No optional markers remain — unwrap the chain to a plain expression.
let chain_expr = expr.take_in(allocator);
let chain_expr = expr.take_in(&self.allocator);
let Expression::ChainExpression(chain) = chain_expr else { unreachable!() };
*expr = Expression::from(chain.unbox().expression);
}
+8 -1
View File
@@ -1,4 +1,4 @@
use oxc_allocator::{Allocator, Box as ArenaBox, Vec as ArenaVec};
use oxc_allocator::{Allocator, Box as ArenaBox, GetAllocator, Vec as ArenaVec};
use oxc_ast::{
AstBuilder,
ast::{Expression, IdentifierReference, Statement},
@@ -709,3 +709,10 @@ impl<'a, State> TraverseCtx<'a, State> {
self.scoping.set_current_block_scope_id(scope_id);
}
}
impl<'a, State> GetAllocator<'a> for TraverseCtx<'a, State> {
#[inline]
fn allocator(&self) -> &'a Allocator {
self.ast.allocator()
}
}