mirror of
https://github.com/swc-project/swc.git
synced 2024-12-23 13:51:19 +03:00
fix(es/minifier): Inline before cloning (#4338)
This commit is contained in:
parent
075c7ff79d
commit
4110fcb961
@ -89,14 +89,20 @@ where
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(Expr::Object(init)) = n.init.as_deref() {
|
||||
for prop in &init.props {
|
||||
if let Some(init) = n.init.as_deref() {
|
||||
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 {
|
||||
PropOrSpread::Spread(_) => continue,
|
||||
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 {
|
||||
Expr::Lit(..) => p.value.clone(),
|
||||
Expr::Fn(..) | Expr::Arrow(..) => {
|
||||
@ -117,7 +123,6 @@ where
|
||||
);
|
||||
self.simple_props
|
||||
.insert((name.to_id(), s.value.clone()), value);
|
||||
self.mode.store(name.to_id(), n.init.as_deref().unwrap());
|
||||
}
|
||||
PropName::Ident(i) => {
|
||||
trace_op!(
|
||||
@ -126,7 +131,6 @@ where
|
||||
);
|
||||
self.simple_props
|
||||
.insert((name.to_id(), i.sym.clone()), value);
|
||||
self.mode.store(name.to_id(), n.init.as_deref().unwrap());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -40,6 +40,8 @@ where
|
||||
return;
|
||||
}
|
||||
|
||||
self.vars.inline_with_multi_replacer(init);
|
||||
|
||||
// TODO: Check for side effect between original decl position and inlined
|
||||
// position
|
||||
|
||||
@ -435,6 +437,8 @@ where
|
||||
// Inline very simple functions.
|
||||
match decl {
|
||||
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 {
|
||||
Some(body) => {
|
||||
if !UsageFinder::find(&i, body)
|
||||
|
@ -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(
|
||||
&mut self,
|
||||
label: Option<Ident>,
|
||||
|
@ -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: [],
|
||||
},
|
||||
),
|
||||
],
|
||||
}
|
@ -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))
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
export function regexCheck(regex) {
|
||||
return function(code) {
|
||||
return null !== code && regex.test(String.fromCharCode(code));
|
||||
};
|
||||
}
|
@ -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: [],
|
||||
},
|
||||
),
|
||||
],
|
||||
}
|
@ -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'));
|
@ -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'));
|
Loading…
Reference in New Issue
Block a user