mirror of
https://github.com/danbulant/oxc
synced 2026-05-25 04:42:10 +00:00
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:
parent
4d157c583b
commit
a23ce152af
2 changed files with 90 additions and 10 deletions
|
|
@ -227,6 +227,14 @@ impl<'a> Traverse<'a> for ReplaceGlobalDefines<'a> {
|
||||||
self.replace_identifier_defines(expr, ctx);
|
self.replace_identifier_defines(expr, ctx);
|
||||||
self.replace_dot_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> {
|
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>) {
|
fn replace_identifier_defines(&self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||||
match expr {
|
match expr {
|
||||||
Expression::Identifier(ident) => {
|
Expression::Identifier(ident) => {
|
||||||
if !ident.is_global_reference(ctx.symbols()) {
|
if let Some(new_expr) = self.replace_identifier_define_impl(ident, ctx) {
|
||||||
return;
|
*expr = new_expr;
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expression::ThisExpression(_)
|
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>) {
|
fn replace_dot_defines(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||||
match expr {
|
match expr {
|
||||||
Expression::ChainExpression(chain) => {
|
Expression::ChainExpression(chain) => {
|
||||||
|
|
@ -595,3 +639,16 @@ fn destructing_dot_define_optimizer<'ast>(
|
||||||
const fn should_replace_this_expr(scope_flags: ScopeFlags) -> bool {
|
const fn should_replace_this_expr(scope_flags: ScopeFlags) -> bool {
|
||||||
!scope_flags.contains(ScopeFlags::Function) || scope_flags.contains(ScopeFlags::Arrow)
|
!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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -182,3 +182,26 @@ fn this_expr() {
|
||||||
config,
|
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(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue