diff --git a/crates/swc_ecma_minifier/src/compress/pure/misc.rs b/crates/swc_ecma_minifier/src/compress/pure/misc.rs index e0a1350e2f66..784bde6eca3b 100644 --- a/crates/swc_ecma_minifier/src/compress/pure/misc.rs +++ b/crates/swc_ecma_minifier/src/compress/pure/misc.rs @@ -364,6 +364,30 @@ impl Pure<'_> { } } + pub(super) fn optimize_opt_chain(&mut self, e: &mut Expr) { + let opt = match e { + Expr::OptChain(c) => c, + _ => return, + }; + + if let OptChainBase::Member(base) = &mut opt.base { + if match &*base.obj { + Expr::Lit(Lit::Null(..)) => false, + Expr::Lit(..) | Expr::Object(..) | Expr::Array(..) => true, + _ => false, + } { + self.changed = true; + report_change!("Optimized optional chaining expression where object is not null"); + + *e = Expr::Member(MemberExpr { + span: opt.span, + obj: base.obj.take(), + prop: base.prop.take(), + }); + } + } + } + /// new Array(...) -> Array(...) pub(super) fn optimize_builtin_object(&mut self, e: &mut Expr) { if !self.options.pristine_globals { diff --git a/crates/swc_ecma_minifier/src/compress/pure/mod.rs b/crates/swc_ecma_minifier/src/compress/pure/mod.rs index 80964824d481..bba00a7f2021 100644 --- a/crates/swc_ecma_minifier/src/compress/pure/mod.rs +++ b/crates/swc_ecma_minifier/src/compress/pure/mod.rs @@ -551,6 +551,12 @@ impl VisitMut for Pure<'_> { if e.is_seq() { debug_assert_valid(e); } + + self.optimize_opt_chain(e); + + if e.is_seq() { + debug_assert_valid(e); + } } fn visit_mut_expr_stmt(&mut self, s: &mut ExprStmt) { diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/6492/1/input.js b/crates/swc_ecma_minifier/tests/fixture/issues/6492/1/input.js new file mode 100644 index 000000000000..60f46f2d5cf0 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/issues/6492/1/input.js @@ -0,0 +1,3 @@ +const obj = { key: 42 }; +const val = obj?.[null || 'key'] +console.log('val', val) \ No newline at end of file diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/6492/1/output.js b/crates/swc_ecma_minifier/tests/fixture/issues/6492/1/output.js new file mode 100644 index 000000000000..cb25094fe820 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/issues/6492/1/output.js @@ -0,0 +1 @@ +console.log('val', 42); diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/6492/2/input.js b/crates/swc_ecma_minifier/tests/fixture/issues/6492/2/input.js new file mode 100644 index 000000000000..3e269620f6bd --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/issues/6492/2/input.js @@ -0,0 +1,3 @@ +const obj = { key: 42 }; +const val = obj?.key.toString() +console.log('val', val) \ No newline at end of file diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/6492/2/output.js b/crates/swc_ecma_minifier/tests/fixture/issues/6492/2/output.js new file mode 100644 index 000000000000..1d7e814233b4 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/issues/6492/2/output.js @@ -0,0 +1 @@ +console.log('val', "42"); diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/6492/3/input.js b/crates/swc_ecma_minifier/tests/fixture/issues/6492/3/input.js new file mode 100644 index 000000000000..3f96323743b0 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/issues/6492/3/input.js @@ -0,0 +1,3 @@ +const obj = { key: 42 }; +const val = obj?.key?.toString() +console.log('val', val) \ No newline at end of file diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/6492/3/output.js b/crates/swc_ecma_minifier/tests/fixture/issues/6492/3/output.js new file mode 100644 index 000000000000..1d7e814233b4 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/issues/6492/3/output.js @@ -0,0 +1 @@ +console.log('val', "42"); diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/6492/4/input.js b/crates/swc_ecma_minifier/tests/fixture/issues/6492/4/input.js new file mode 100644 index 000000000000..423b64232b85 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/issues/6492/4/input.js @@ -0,0 +1,3 @@ +const obj = { key: 42 }; +const val = obj.key?.toString() +console.log('val', val) \ No newline at end of file diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/6492/4/output.js b/crates/swc_ecma_minifier/tests/fixture/issues/6492/4/output.js new file mode 100644 index 000000000000..1d7e814233b4 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/issues/6492/4/output.js @@ -0,0 +1 @@ +console.log('val', "42");