mirror of
https://github.com/swc-project/swc.git
synced 2024-11-24 02:06:08 +03:00
fix(es/minifier): Respect pure_funcs
for tagged tpls (#8280)
**Related issue:** - Closes #8275.
This commit is contained in:
parent
2f6af92232
commit
1ccfc0762c
22
crates/swc/tests/fixture/issues-8xxx/8275/input/.swcrc
Normal file
22
crates/swc/tests/fixture/issues-8xxx/8275/input/.swcrc
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"jsc": {
|
||||
"parser": {
|
||||
"syntax": "ecmascript",
|
||||
"jsx": false
|
||||
},
|
||||
"target": "es2022",
|
||||
"loose": false,
|
||||
"minify": {
|
||||
"compress": {
|
||||
"pure_funcs": [
|
||||
"pure_html"
|
||||
]
|
||||
},
|
||||
"mangle": false
|
||||
}
|
||||
},
|
||||
"module": {
|
||||
"type": "es6"
|
||||
},
|
||||
"isModule": true
|
||||
}
|
15
crates/swc/tests/fixture/issues-8xxx/8275/input/1.js
Normal file
15
crates/swc/tests/fixture/issues-8xxx/8275/input/1.js
Normal file
@ -0,0 +1,15 @@
|
||||
/*#__PURE__*/
|
||||
function pure_html(strings, ...values) {
|
||||
return { strings, values };
|
||||
}
|
||||
|
||||
// ✅ This is tree-shaken from the minified output.
|
||||
const a = `<span>aaaa</span>`;
|
||||
|
||||
// ❌ This is not tree-shaken from the minified output,
|
||||
// despite the "html" function being declare using
|
||||
// `jsc.minify.compress.pure_funcs` configuration.
|
||||
const b = pure_html`<span>bbbb</span>`;
|
||||
|
||||
// ✅ This is not tree-shaken from the minified output.
|
||||
export const c = pure_html`<span>cccc</span>`;
|
6
crates/swc/tests/fixture/issues-8xxx/8275/output/1.js
Normal file
6
crates/swc/tests/fixture/issues-8xxx/8275/output/1.js
Normal file
@ -0,0 +1,6 @@
|
||||
export const c = (function(strings, ...values) {
|
||||
return {
|
||||
strings,
|
||||
values
|
||||
};
|
||||
})`<span>cccc</span>`;
|
@ -928,20 +928,35 @@ impl Pure<'_> {
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if let Expr::Call(CallExpr {
|
||||
callee: Callee::Expr(callee),
|
||||
args,
|
||||
..
|
||||
}) = e
|
||||
{
|
||||
if callee.is_pure_callee(&self.expr_ctx) {
|
||||
self.changed = true;
|
||||
report_change!("Dropping pure call as callee is pure");
|
||||
*e = self
|
||||
.make_ignored_expr(args.take().into_iter().map(|arg| arg.expr))
|
||||
.unwrap_or(Expr::Invalid(Invalid { span: DUMMY_SP }));
|
||||
return;
|
||||
match e {
|
||||
Expr::Call(CallExpr {
|
||||
callee: Callee::Expr(callee),
|
||||
args,
|
||||
..
|
||||
}) => {
|
||||
if callee.is_pure_callee(&self.expr_ctx) {
|
||||
self.changed = true;
|
||||
report_change!("Dropping pure call as callee is pure");
|
||||
*e = self
|
||||
.make_ignored_expr(args.take().into_iter().map(|arg| arg.expr))
|
||||
.unwrap_or(Expr::Invalid(Invalid { span: DUMMY_SP }));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Expr::TaggedTpl(TaggedTpl {
|
||||
tag: callee, tpl, ..
|
||||
}) => {
|
||||
if callee.is_pure_callee(&self.expr_ctx) {
|
||||
self.changed = true;
|
||||
report_change!("Dropping pure tag tpl as callee is pure");
|
||||
*e = self
|
||||
.make_ignored_expr(tpl.exprs.take().into_iter())
|
||||
.unwrap_or(Expr::Invalid(Invalid { span: DUMMY_SP }));
|
||||
return;
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
if self.options.unused {
|
||||
|
@ -58,6 +58,39 @@ struct InfoMarker<'a> {
|
||||
state: State,
|
||||
}
|
||||
|
||||
impl InfoMarker<'_> {
|
||||
fn is_pure_callee(&self, callee: &Expr) -> bool {
|
||||
match callee {
|
||||
Expr::Ident(callee) => {
|
||||
if self.pure_callee.contains(&callee.to_id()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Expr::Seq(callee) => {
|
||||
if has_pure(self.comments, callee.span) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
if let Some(pure_fns) = &self.pure_funcs {
|
||||
if let Expr::Ident(..) = callee {
|
||||
// Check for pure_funcs
|
||||
if Ident::within_ignored_ctxt(|| {
|
||||
//
|
||||
pure_fns.contains(&NodeIgnoringSpan::borrowed(callee))
|
||||
}) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
has_pure(self.comments, callee.span())
|
||||
}
|
||||
}
|
||||
|
||||
impl VisitMut for InfoMarker<'_> {
|
||||
noop_visit_mut_type!();
|
||||
|
||||
@ -71,19 +104,9 @@ impl VisitMut for InfoMarker<'_> {
|
||||
// We check callee in some cases because we move comments
|
||||
// See https://github.com/swc-project/swc/issues/7241
|
||||
if match &n.callee {
|
||||
Callee::Expr(e) => match &**e {
|
||||
Expr::Ident(callee) => self.pure_callee.contains(&callee.to_id()),
|
||||
_ => false,
|
||||
},
|
||||
Callee::Expr(e) => self.is_pure_callee(e),
|
||||
_ => false,
|
||||
} || has_pure(self.comments, n.span)
|
||||
|| match &n.callee {
|
||||
Callee::Expr(e) => match &**e {
|
||||
Expr::Seq(callee) => has_pure(self.comments, callee.span),
|
||||
_ => false,
|
||||
},
|
||||
_ => false,
|
||||
}
|
||||
{
|
||||
if !n.span.is_dummy_ignoring_cmt() {
|
||||
n.span = n.span.apply_mark(self.marks.pure);
|
||||
@ -185,6 +208,16 @@ impl VisitMut for InfoMarker<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_mut_tagged_tpl(&mut self, n: &mut TaggedTpl) {
|
||||
n.visit_mut_children_with(self);
|
||||
|
||||
if has_pure(self.comments, n.span) || self.is_pure_callee(&n.tag) {
|
||||
if !n.span.is_dummy_ignoring_cmt() {
|
||||
n.span = n.span.apply_mark(self.marks.pure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_mut_var_decl(&mut self, n: &mut VarDecl) {
|
||||
n.visit_mut_children_with(self);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user