feat(oxc_transformer): replace_global_define for assignmentTarget (#7505)

related esbuild test:

d34e79e2a9/internal/bundler_tests/bundler_default_test.go (L5430-L5497)
This commit is contained in:
IWANABETHATGUY 2024-11-27 13:22:51 +00:00 committed by Boshen
parent 4d157c583b
commit a23ce152af
No known key found for this signature in database
GPG key ID: 67715A371E534061
2 changed files with 90 additions and 10 deletions

View file

@ -227,6 +227,14 @@ impl<'a> Traverse<'a> for ReplaceGlobalDefines<'a> {
self.replace_identifier_defines(expr, ctx);
self.replace_dot_defines(expr, ctx);
}
fn enter_assignment_expression(
&mut self,
node: &mut AssignmentExpression<'a>,
ctx: &mut TraverseCtx<'a>,
) {
self.replace_define_with_assignment_expr(node, ctx);
}
}
impl<'a> ReplaceGlobalDefines<'a> {
@ -255,16 +263,8 @@ impl<'a> ReplaceGlobalDefines<'a> {
fn replace_identifier_defines(&self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
match expr {
Expression::Identifier(ident) => {
if !ident.is_global_reference(ctx.symbols()) {
return;
}
for (key, value) in &self.config.0.identifier.identifier_defines {
if ident.name.as_str() == key {
let value = self.parse_value(value);
*expr = value;
break;
}
if let Some(new_expr) = self.replace_identifier_define_impl(ident, ctx) {
*expr = new_expr;
}
}
Expression::ThisExpression(_)
@ -283,6 +283,50 @@ impl<'a> ReplaceGlobalDefines<'a> {
}
}
fn replace_identifier_define_impl(
&self,
ident: &mut oxc_allocator::Box<'_, IdentifierReference<'_>>,
ctx: &mut TraverseCtx<'a>,
) -> Option<Expression<'a>> {
if !ident.is_global_reference(ctx.symbols()) {
return None;
}
for (key, value) in &self.config.0.identifier.identifier_defines {
if ident.name.as_str() == key {
let value = self.parse_value(value);
return Some(value);
}
}
None
}
fn replace_define_with_assignment_expr(
&mut self,
node: &mut AssignmentExpression<'a>,
ctx: &mut TraverseCtx<'a>,
) {
let new_left = node
.left
.as_simple_assignment_target_mut()
.and_then(|item| match item {
SimpleAssignmentTarget::ComputedMemberExpression(ref mut computed_member_expr) => {
self.replace_dot_computed_member_expr(ctx, computed_member_expr)
}
SimpleAssignmentTarget::StaticMemberExpression(ref mut member) => {
self.replace_dot_static_member_expr(ctx, member)
}
SimpleAssignmentTarget::AssignmentTargetIdentifier(ident) => {
self.replace_identifier_define_impl(ident, ctx)
}
_ => None,
})
.and_then(assignment_target_from_expr);
if let Some(new_left) = new_left {
node.left = new_left;
}
}
fn replace_dot_defines(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
match expr {
Expression::ChainExpression(chain) => {
@ -595,3 +639,16 @@ fn destructing_dot_define_optimizer<'ast>(
const fn should_replace_this_expr(scope_flags: ScopeFlags) -> bool {
!scope_flags.contains(ScopeFlags::Function) || scope_flags.contains(ScopeFlags::Arrow)
}
fn assignment_target_from_expr(expr: Expression) -> Option<AssignmentTarget> {
match expr {
Expression::ComputedMemberExpression(expr) => {
Some(AssignmentTarget::ComputedMemberExpression(expr))
}
Expression::StaticMemberExpression(expr) => {
Some(AssignmentTarget::StaticMemberExpression(expr))
}
Expression::Identifier(ident) => Some(AssignmentTarget::AssignmentTargetIdentifier(ident)),
_ => None,
}
}

View file

@ -182,3 +182,26 @@ fn this_expr() {
config,
);
}
#[test]
fn assignment_target() {
let config = ReplaceGlobalDefinesConfig::new(&[
("d", "ident"),
("e.f", "ident"),
("g", "dot.chain"),
("h.i", "dot.chain"),
])
.unwrap();
test(
r"
console.log(
[a = 0, b.c = 0, b['c'] = 0],
[d = 0, e.f = 0, e['f'] = 0],
[g = 0, h.i = 0, h['i'] = 0],
)
",
"console.log([a = 0,b.c = 0,b['c'] = 0], [ident = 0,ident = 0,ident = 0], [dot.chain = 0,dot.chain = 0,dot.chain = 0\n]);",
config.clone(),
);
}