mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
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:
1 parent
bd74f9d35c
commit
36009ddf68
61 files changed
+436
-419
No files matched your search
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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!(),
|
||||
|
||||
@@ -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),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user