fix(es/minifier): Inline before cloning (#4338)

This commit is contained in:
Donny/강동윤 2022-04-15 20:01:29 +09:00 committed by GitHub
parent 075c7ff79d
commit 4110fcb961
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 501 additions and 6 deletions

View File

@ -89,14 +89,20 @@ where
return; return;
} }
if let Some(Expr::Object(init)) = n.init.as_deref() { if let Some(init) = n.init.as_deref() {
for prop in &init.props { self.mode.store(name.to_id(), init);
}
if let Some(Expr::Object(init)) = n.init.as_deref_mut() {
for prop in &mut init.props {
let prop = match prop { let prop = match prop {
PropOrSpread::Spread(_) => continue, PropOrSpread::Spread(_) => continue,
PropOrSpread::Prop(prop) => prop, PropOrSpread::Prop(prop) => prop,
}; };
if let Prop::KeyValue(p) = &**prop { if let Prop::KeyValue(p) = &mut **prop {
self.vars.inline_with_multi_replacer(&mut p.value);
let value = match &*p.value { let value = match &*p.value {
Expr::Lit(..) => p.value.clone(), Expr::Lit(..) => p.value.clone(),
Expr::Fn(..) | Expr::Arrow(..) => { Expr::Fn(..) | Expr::Arrow(..) => {
@ -117,7 +123,6 @@ where
); );
self.simple_props self.simple_props
.insert((name.to_id(), s.value.clone()), value); .insert((name.to_id(), s.value.clone()), value);
self.mode.store(name.to_id(), n.init.as_deref().unwrap());
} }
PropName::Ident(i) => { PropName::Ident(i) => {
trace_op!( trace_op!(
@ -126,7 +131,6 @@ where
); );
self.simple_props self.simple_props
.insert((name.to_id(), i.sym.clone()), value); .insert((name.to_id(), i.sym.clone()), value);
self.mode.store(name.to_id(), n.init.as_deref().unwrap());
} }
_ => {} _ => {}
} }

View File

@ -40,6 +40,8 @@ where
return; return;
} }
self.vars.inline_with_multi_replacer(init);
// TODO: Check for side effect between original decl position and inlined // TODO: Check for side effect between original decl position and inlined
// position // position
@ -435,6 +437,8 @@ where
// Inline very simple functions. // Inline very simple functions.
match decl { match decl {
Decl::Fn(f) if self.options.inline >= 2 && f.ident.sym != *"arguments" => { Decl::Fn(f) if self.options.inline >= 2 && f.ident.sym != *"arguments" => {
self.vars.inline_with_multi_replacer(&mut f.function.body);
match &f.function.body { match &f.function.body {
Some(body) => { Some(body) => {
if !UsageFinder::find(&i, body) if !UsageFinder::find(&i, body)

View File

@ -144,7 +144,7 @@ impl Pure<'_> {
} }
} }
/// Returns [Some] if the whole statement sohuld be replaced /// Returns [Some] if the whole statement should be replaced
fn drop_useless_continue_inner( fn drop_useless_continue_inner(
&mut self, &mut self,
label: Option<Ident>, label: Option<Ident>,

View File

@ -0,0 +1,194 @@
TestSnapshot {
vars: [
(
(
Atom('String' type=static),
#1,
),
VarUsageInfo {
inline_prevented: false,
ref_count: 1,
cond_init: false,
declared: false,
declared_count: 0,
declared_as_fn_param: false,
declared_as_fn_expr: false,
assign_count: 0,
mutation_by_call_count: 0,
usage_count: 1,
reassigned_with_assignment: false,
reassigned_with_var_decl: false,
mutated: false,
has_property_access: true,
has_property_mutation: false,
accessed_props: {},
exported: false,
used_above_decl: true,
is_fn_local: true,
used_by_nested_fn: true,
executed_multiple_time: false,
used_in_cond: false,
var_kind: None,
var_initialized: false,
declared_as_catch_param: false,
no_side_effect_for_member_access: false,
used_as_callee: false,
used_as_arg: false,
pure_fn: false,
infects: [],
},
),
(
(
Atom('check' type=inline),
#2,
),
VarUsageInfo {
inline_prevented: false,
ref_count: 1,
cond_init: false,
declared: true,
declared_count: 1,
declared_as_fn_param: false,
declared_as_fn_expr: false,
assign_count: 0,
mutation_by_call_count: 0,
usage_count: 1,
reassigned_with_assignment: false,
reassigned_with_var_decl: false,
mutated: false,
has_property_access: false,
has_property_mutation: false,
accessed_props: {},
exported: false,
used_above_decl: true,
is_fn_local: true,
used_by_nested_fn: true,
executed_multiple_time: false,
used_in_cond: false,
var_kind: None,
var_initialized: false,
declared_as_catch_param: false,
no_side_effect_for_member_access: false,
used_as_callee: false,
used_as_arg: false,
pure_fn: false,
infects: [],
},
),
(
(
Atom('code' type=inline),
#3,
),
VarUsageInfo {
inline_prevented: false,
ref_count: 2,
cond_init: false,
declared: true,
declared_count: 1,
declared_as_fn_param: true,
declared_as_fn_expr: false,
assign_count: 0,
mutation_by_call_count: 1,
usage_count: 2,
reassigned_with_assignment: false,
reassigned_with_var_decl: false,
mutated: true,
has_property_access: false,
has_property_mutation: false,
accessed_props: {},
exported: false,
used_above_decl: false,
is_fn_local: true,
used_by_nested_fn: true,
executed_multiple_time: false,
used_in_cond: false,
var_kind: None,
var_initialized: false,
declared_as_catch_param: false,
no_side_effect_for_member_access: false,
used_as_callee: false,
used_as_arg: true,
pure_fn: false,
infects: [],
},
),
(
(
Atom('regex' type=inline),
#2,
),
VarUsageInfo {
inline_prevented: false,
ref_count: 1,
cond_init: false,
declared: true,
declared_count: 1,
declared_as_fn_param: true,
declared_as_fn_expr: false,
assign_count: 0,
mutation_by_call_count: 0,
usage_count: 1,
reassigned_with_assignment: false,
reassigned_with_var_decl: false,
mutated: false,
has_property_access: true,
has_property_mutation: false,
accessed_props: {},
exported: false,
used_above_decl: false,
is_fn_local: false,
used_by_nested_fn: true,
executed_multiple_time: false,
used_in_cond: false,
var_kind: None,
var_initialized: false,
declared_as_catch_param: false,
no_side_effect_for_member_access: false,
used_as_callee: false,
used_as_arg: false,
pure_fn: false,
infects: [],
},
),
(
(
Atom('regexCheck' type=dynamic),
#1,
),
VarUsageInfo {
inline_prevented: true,
ref_count: 0,
cond_init: false,
declared: true,
declared_count: 1,
declared_as_fn_param: false,
declared_as_fn_expr: false,
assign_count: 0,
mutation_by_call_count: 0,
usage_count: 0,
reassigned_with_assignment: false,
reassigned_with_var_decl: false,
mutated: false,
has_property_access: false,
has_property_mutation: false,
accessed_props: {},
exported: false,
used_above_decl: false,
is_fn_local: true,
used_by_nested_fn: false,
executed_multiple_time: false,
used_in_cond: false,
var_kind: None,
var_initialized: true,
declared_as_catch_param: false,
no_side_effect_for_member_access: false,
used_as_callee: false,
used_as_arg: false,
pure_fn: false,
infects: [],
},
),
],
}

View File

@ -0,0 +1,19 @@
/**
* Create a code check from a regex.
*
* @param {RegExp} regex
* @returns {(code: Code) => code is number}
*/
export function regexCheck(regex) {
return check
/**
* Check whether a code matches the bound regex.
*
* @param {Code} code Character code
* @returns {code is number} Whether the character code matches the bound regex
*/
function check(code) {
return code !== null && regex.test(String.fromCharCode(code))
}
}

View File

@ -0,0 +1,5 @@
export function regexCheck(regex) {
return function(code) {
return null !== code && regex.test(String.fromCharCode(code));
};
}

View File

@ -0,0 +1,232 @@
TestSnapshot {
vars: [
(
(
Atom('String' type=static),
#1,
),
VarUsageInfo {
inline_prevented: false,
ref_count: 1,
cond_init: false,
declared: false,
declared_count: 0,
declared_as_fn_param: false,
declared_as_fn_expr: false,
assign_count: 0,
mutation_by_call_count: 0,
usage_count: 1,
reassigned_with_assignment: false,
reassigned_with_var_decl: false,
mutated: false,
has_property_access: true,
has_property_mutation: false,
accessed_props: {},
exported: false,
used_above_decl: true,
is_fn_local: true,
used_by_nested_fn: true,
executed_multiple_time: false,
used_in_cond: false,
var_kind: None,
var_initialized: false,
declared_as_catch_param: false,
no_side_effect_for_member_access: false,
used_as_callee: false,
used_as_arg: false,
pure_fn: false,
infects: [],
},
),
(
(
Atom('check' type=inline),
#2,
),
VarUsageInfo {
inline_prevented: false,
ref_count: 1,
cond_init: false,
declared: true,
declared_count: 1,
declared_as_fn_param: false,
declared_as_fn_expr: false,
assign_count: 0,
mutation_by_call_count: 0,
usage_count: 1,
reassigned_with_assignment: false,
reassigned_with_var_decl: false,
mutated: false,
has_property_access: false,
has_property_mutation: false,
accessed_props: {},
exported: false,
used_above_decl: true,
is_fn_local: true,
used_by_nested_fn: true,
executed_multiple_time: false,
used_in_cond: false,
var_kind: None,
var_initialized: false,
declared_as_catch_param: false,
no_side_effect_for_member_access: false,
used_as_callee: false,
used_as_arg: false,
pure_fn: false,
infects: [],
},
),
(
(
Atom('code' type=inline),
#3,
),
VarUsageInfo {
inline_prevented: false,
ref_count: 2,
cond_init: false,
declared: true,
declared_count: 1,
declared_as_fn_param: true,
declared_as_fn_expr: false,
assign_count: 0,
mutation_by_call_count: 1,
usage_count: 2,
reassigned_with_assignment: false,
reassigned_with_var_decl: false,
mutated: true,
has_property_access: false,
has_property_mutation: false,
accessed_props: {},
exported: false,
used_above_decl: false,
is_fn_local: true,
used_by_nested_fn: true,
executed_multiple_time: false,
used_in_cond: false,
var_kind: None,
var_initialized: false,
declared_as_catch_param: false,
no_side_effect_for_member_access: false,
used_as_callee: false,
used_as_arg: true,
pure_fn: false,
infects: [],
},
),
(
(
Atom('console' type=inline),
#1,
),
VarUsageInfo {
inline_prevented: false,
ref_count: 10,
cond_init: false,
declared: false,
declared_count: 0,
declared_as_fn_param: false,
declared_as_fn_expr: false,
assign_count: 0,
mutation_by_call_count: 0,
usage_count: 10,
reassigned_with_assignment: false,
reassigned_with_var_decl: false,
mutated: false,
has_property_access: true,
has_property_mutation: false,
accessed_props: {},
exported: false,
used_above_decl: true,
is_fn_local: true,
used_by_nested_fn: false,
executed_multiple_time: false,
used_in_cond: false,
var_kind: None,
var_initialized: false,
declared_as_catch_param: false,
no_side_effect_for_member_access: false,
used_as_callee: false,
used_as_arg: false,
pure_fn: false,
infects: [],
},
),
(
(
Atom('regex' type=inline),
#2,
),
VarUsageInfo {
inline_prevented: false,
ref_count: 1,
cond_init: false,
declared: true,
declared_count: 1,
declared_as_fn_param: true,
declared_as_fn_expr: false,
assign_count: 0,
mutation_by_call_count: 0,
usage_count: 1,
reassigned_with_assignment: false,
reassigned_with_var_decl: false,
mutated: false,
has_property_access: true,
has_property_mutation: false,
accessed_props: {},
exported: false,
used_above_decl: false,
is_fn_local: false,
used_by_nested_fn: true,
executed_multiple_time: false,
used_in_cond: false,
var_kind: None,
var_initialized: false,
declared_as_catch_param: false,
no_side_effect_for_member_access: false,
used_as_callee: false,
used_as_arg: false,
pure_fn: false,
infects: [],
},
),
(
(
Atom('regexCheck' type=dynamic),
#1,
),
VarUsageInfo {
inline_prevented: false,
ref_count: 10,
cond_init: false,
declared: true,
declared_count: 1,
declared_as_fn_param: false,
declared_as_fn_expr: false,
assign_count: 0,
mutation_by_call_count: 10,
usage_count: 10,
reassigned_with_assignment: false,
reassigned_with_var_decl: false,
mutated: true,
has_property_access: false,
has_property_mutation: false,
accessed_props: {},
exported: false,
used_above_decl: false,
is_fn_local: true,
used_by_nested_fn: false,
executed_multiple_time: false,
used_in_cond: false,
var_kind: None,
var_initialized: true,
declared_as_catch_param: false,
no_side_effect_for_member_access: false,
used_as_callee: true,
used_as_arg: false,
pure_fn: false,
infects: [],
},
),
],
}

View File

@ -0,0 +1,31 @@
/**
* Create a code check from a regex.
*
* @param {RegExp} regex
* @returns {(code: Code) => code is number}
*/
function regexCheck(regex) {
return check
/**
* Check whether a code matches the bound regex.
*
* @param {Code} code Character code
* @returns {code is number} Whether the character code matches the bound regex
*/
function check(code) {
return code !== null && regex.test(String.fromCharCode(code))
}
}
console.log(regexCheck('Foo'));
console.log(regexCheck('Foo'));
console.log(regexCheck('Foo'));
console.log(regexCheck('Foo'));
console.log(regexCheck('Foo'));
console.log(regexCheck('Foo'));
console.log(regexCheck('Foo'));
console.log(regexCheck('Foo'));
console.log(regexCheck('Foo'));
console.log(regexCheck('Foo'));

View File

@ -0,0 +1,6 @@
function regexCheck(regex) {
return function(code) {
return null !== code && regex.test(String.fromCharCode(code));
};
}
console.log(regexCheck('Foo')), console.log(regexCheck('Foo')), console.log(regexCheck('Foo')), console.log(regexCheck('Foo')), console.log(regexCheck('Foo')), console.log(regexCheck('Foo')), console.log(regexCheck('Foo')), console.log(regexCheck('Foo')), console.log(regexCheck('Foo')), console.log(regexCheck('Foo'));