perf(isolated_declarations): use ReplaceWith instead of TakeIn (#24016)

Replace `take_in` with `replace_with` in as many places as possible in isolated declarations. See #24012 for explanation of the advantage of `replace_with`.
This commit is contained in:
overlookmotel committed 2026-07-05 14:44:09 +00:00
1 parent ff10855dce
commit a4db73113e
4 files changed
+22 -34

No files matched your search

@@ -1,36 +1,24 @@
use oxc_allocator::{Allocator, GetAllocator, TakeIn};
use oxc_allocator::ReplaceWith;
use oxc_ast::ast::BindingPattern;
use oxc_ast_visit::{VisitMut, walk_mut::walk_binding_pattern};
use crate::IsolatedDeclarations;
pub struct FormalParameterBindingPattern;
pub struct FormalParameterBindingPattern<'a> {
allocator: &'a Allocator,
}
impl<'a> VisitMut<'a> for FormalParameterBindingPattern<'a> {
impl<'a> VisitMut<'a> for FormalParameterBindingPattern {
fn visit_binding_pattern(&mut self, pattern: &mut BindingPattern<'a>) {
if let BindingPattern::AssignmentPattern(_) = pattern {
// Take the `BindingPattern`, not the `AssignmentPattern` because `BindingPattern::take_in`
// performs less allocations. Compiler removes the unreachable branch here.
let old_pattern = pattern.take_in(&self.allocator);
if let BindingPattern::AssignmentPattern(assignment) = old_pattern {
*pattern = assignment.unbox().left;
} else {
unreachable!();
}
if matches!(pattern, BindingPattern::AssignmentPattern(_)) {
pattern.replace_with(|pattern| {
let BindingPattern::AssignmentPattern(assignment) = pattern else { unreachable!() };
assignment.unbox().left
});
}
walk_binding_pattern(self, pattern);
}
}
impl<'a> FormalParameterBindingPattern<'a> {
pub fn remove_assignments_from_kind(
transformer: &IsolatedDeclarations<'a>,
pattern: &mut BindingPattern<'a>,
) {
let mut visitor = FormalParameterBindingPattern { allocator: transformer.allocator() };
visitor.visit_binding_pattern(pattern);
impl FormalParameterBindingPattern {
pub fn remove_assignments_from_kind(pattern: &mut BindingPattern<'_>) {
FormalParameterBindingPattern.visit_binding_pattern(pattern);
}
}
@@ -60,7 +60,7 @@ impl<'a> IsolatedDeclarations<'a> {
param.pattern.clone_in(self.allocator())
};
FormalParameterBindingPattern::remove_assignments_from_kind(self, &mut pattern);
FormalParameterBindingPattern::remove_assignments_from_kind(&mut pattern);
if is_assignment_pattern
|| param.type_annotation.is_none()
@@ -180,10 +180,7 @@ impl<'a> IsolatedDeclarations<'a> {
let rest = params.rest.as_ref().map(|rest| {
let mut rest = rest.clone_in(self.allocator());
FormalParameterBindingPattern::remove_assignments_from_kind(
self,
&mut rest.rest.argument,
);
FormalParameterBindingPattern::remove_assignments_from_kind(&mut rest.rest.argument);
rest
});
+2 -2
View File
@@ -228,7 +228,7 @@ impl<'a> IsolatedDeclarations<'a> {
if let Some(body) =
decl.body.as_mut().and_then(|body| body.as_module_block_mut())
{
self.strip_export_keyword(&mut body.body);
Self::strip_export_keyword(&mut body.body);
}
// We need to visit the module declaration to collect all references
@@ -435,7 +435,7 @@ impl<'a> IsolatedDeclarations<'a> {
} else if self.scope.is_ts_module_block() {
// If we are in a module block and we don't need to add `export {}`, in that case we need to remove `export` keyword from all ExportNamedDeclaration
// <https://github.com/microsoft/TypeScript/blob/a709f9899c2a544b6de65a0f2623ecbbe1394eab/src/compiler/transformers/declarations.ts#L1556-L1563>
self.strip_export_keyword(&mut new_stmts);
Self::strip_export_keyword(&mut new_stmts);
}
new_stmts
@@ -1,4 +1,4 @@
use oxc_allocator::{ArenaBox, ArenaVec, CloneIn, GetAllocator, TakeIn};
use oxc_allocator::{ArenaBox, ArenaVec, CloneIn, GetAllocator, ReplaceWith};
use oxc_ast::{ast::*, builder::NONE};
use oxc_span::{GetSpan, SPAN};
use oxc_str::Str;
@@ -182,12 +182,15 @@ impl<'a> IsolatedDeclarations<'a> {
/// const a = 1;
/// function b() {}
/// ```
pub(crate) fn strip_export_keyword(&self, stmts: &mut ArenaVec<'a, Statement<'a>>) {
pub(crate) fn strip_export_keyword(stmts: &mut ArenaVec<'a, Statement<'a>>) {
stmts.iter_mut().for_each(|stmt| {
if let Statement::ExportNamedDeclaration(decl) = stmt
&& let Some(declaration) = &mut decl.declaration
&& decl.declaration.is_some()
{
*stmt = Statement::from(declaration.take_in(self));
stmt.replace_with(|stmt| {
let Statement::ExportNamedDeclaration(decl) = stmt else { unreachable!() };
Statement::from(decl.unbox().declaration.unwrap())
});
}
});
}