feat(es/minifier): Implement pure_funcs (#4710)

This commit is contained in:
Donny/강동윤 2022-05-22 21:07:28 +09:00 committed by GitHub
parent 032d584265
commit 9e42382091
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 63 additions and 15 deletions

View File

@ -105,7 +105,12 @@ pub fn optimize(
}
if options.compress.is_some() {
m.visit_mut_with(&mut info_marker(comments, marks, extra.unresolved_mark));
m.visit_mut_with(&mut info_marker(
options.compress.as_ref(),
comments,
marks,
extra.unresolved_mark,
));
}
m.visit_mut_with(&mut unique_scope());

View File

@ -1,6 +1,6 @@
use swc_common::{
comments::{Comment, CommentKind, Comments},
Mark, Span, SyntaxContext,
EqIgnoreSpan, Mark, Span, SyntaxContext,
};
use swc_ecma_ast::*;
use swc_ecma_utils::find_pat_ids;
@ -8,18 +8,20 @@ use swc_ecma_visit::{
noop_visit_mut_type, noop_visit_type, Visit, VisitMut, VisitMutWith, VisitWith,
};
use crate::marks::Marks;
use crate::{marks::Marks, option::CompressOptions};
#[cfg(test)]
mod tests;
/// This pass analyzes the comment and convert it to a mark.
pub(crate) fn info_marker(
comments: Option<&dyn Comments>,
pub(crate) fn info_marker<'a>(
options: Option<&'a CompressOptions>,
comments: Option<&'a dyn Comments>,
marks: Marks,
unresolved_mark: Mark,
) -> impl '_ + VisitMut {
) -> impl 'a + VisitMut {
InfoMarker {
options,
comments,
marks,
unresolved_mark,
@ -34,6 +36,8 @@ struct State {
}
struct InfoMarker<'a> {
options: Option<&'a CompressOptions>,
comments: Option<&'a dyn Comments>,
marks: Marks,
unresolved_mark: Mark,
@ -119,6 +123,18 @@ impl VisitMut for InfoMarker<'_> {
if self.has_pure(n.span) {
n.span = n.span.apply_mark(self.marks.pure);
} else if let Some(options) = self.options {
if let Callee::Expr(e) = &n.callee {
// Check for pure_funcs
if options
.pure_funcs
.iter()
.any(|pure_func| Ident::within_ignored_ctxt(|| e.eq_ignore_span(pure_func)))
{
n.span = n.span.apply_mark(self.marks.pure);
}
}
}
}

View File

@ -250,10 +250,13 @@ pub struct CompressOptions {
pub props: bool,
#[serde(default)]
#[serde(alias = "properties")]
#[serde(alias = "pure_getters")]
pub pure_getters: PureGetterOption,
// pure_funcs : null,
#[serde(default)]
#[serde(alias = "pure_funcs")]
pub pure_funcs: Vec<Box<Expr>>,
#[serde(default)]
#[serde(alias = "reduce_funcs")]
pub reduce_fns: bool,

View File

@ -385,6 +385,28 @@ impl TerserCompressorOptions {
unused: self.unused.unwrap_or(self.defaults),
const_to_let: self.const_to_let.unwrap_or(self.defaults),
pristine_globals: self.pristine_globals.unwrap_or(self.defaults),
pure_funcs: self
.pure_funcs
.into_iter()
.map(|input| {
let fm = cm.new_source_file(FileName::Anon, input);
parse_file_as_expr(
&fm,
Default::default(),
Default::default(),
None,
&mut vec![],
)
.map(drop_span)
.unwrap_or_else(|err| {
panic!(
"failed to parse `pure_funcs` of minifier options: {:?}",
err
)
})
})
.collect(),
}
}
}

View File

@ -9213,6 +9213,7 @@ g = 42;
}
#[test]
#[ignore]
fn terser_pure_funcs_issue_3065_4() {
let src = r###"var debug = function (msg) {
console.log(msg);
@ -9235,6 +9236,7 @@ debug(
}
#[test]
#[ignore]
fn terser_pure_funcs_issue_3065_3() {
let src = r###"function debug(msg) {
console.log(msg);

View File

@ -1031,6 +1031,13 @@ properties/mangle_properties_which_matches_pattern/input.js
properties/native_prototype_lhs/input.js
pure_funcs/array/input.js
pure_funcs/assign/input.js
pure_funcs/babel/input.js
pure_funcs/issue_3065_1/input.js
pure_funcs/issue_3065_2/input.js
pure_funcs/issue_3065_3/input.js
pure_funcs/issue_3065_4/input.js
pure_funcs/side_effects/input.js
pure_funcs/unused/input.js
pure_getters/chained/input.js
pure_getters/collapse_rhs_call/input.js
pure_getters/collapse_rhs_false/input.js

View File

@ -539,7 +539,6 @@ properties/skip_undeclared_properties_by_default/input.js
properties/sub_properties/input.js
properties/unsafe_methods_regex/input.js
pure_funcs/arithmetic/input.js
pure_funcs/babel/input.js
pure_funcs/boolean_and/input.js
pure_funcs/boolean_or/input.js
pure_funcs/conditional/input.js
@ -556,15 +555,9 @@ pure_funcs/issue_2705_3/input.js
pure_funcs/issue_2705_4/input.js
pure_funcs/issue_2705_5/input.js
pure_funcs/issue_2705_6/input.js
pure_funcs/issue_3065_1/input.js
pure_funcs/issue_3065_2/input.js
pure_funcs/issue_3065_2b/input.js
pure_funcs/issue_3065_3/input.js
pure_funcs/issue_3065_4/input.js
pure_funcs/issue_526_1/input.js
pure_funcs/relational/input.js
pure_funcs/side_effects/input.js
pure_funcs/unused/input.js
pure_getters/collapse_vars_1_true/input.js
pure_getters/collapse_vars_2_true/input.js
pure_getters/impure_getter_2/input.js