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;
|
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());
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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>,
|
||||||
|
@ -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