mirror of
https://github.com/swc-project/swc.git
synced 2024-11-24 18:28:13 +03:00
fix(es/minifier): Fix analysis of var declaration after usage (#6043)
**Description:** `var_initialized` should be `true` even if the declaration of variable comes after its usage. **Related issue:** - Closes https://github.com/swc-project/swc/issues/6039.
This commit is contained in:
parent
ad58d5daf8
commit
36d467e7d7
26
crates/swc/tests/exec/issues-6xxx/6039/1/exec.js
Normal file
26
crates/swc/tests/exec/issues-6xxx/6039/1/exec.js
Normal file
@ -0,0 +1,26 @@
|
||||
function foo() {
|
||||
let walker = 0;
|
||||
|
||||
let arr = [];
|
||||
|
||||
function bar(defaultValue) {
|
||||
const myIndex = walker;
|
||||
walker += 1;
|
||||
|
||||
console.log({ arr });
|
||||
|
||||
if (arr.length < myIndex + 1) {
|
||||
arr[myIndex] = defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
return bar;
|
||||
}
|
||||
|
||||
const bar = foo();
|
||||
|
||||
bar(null);
|
||||
bar(null);
|
||||
bar(null);
|
||||
bar(null);
|
||||
bar(null);
|
@ -157,6 +157,8 @@ impl Storage for ProgramData {
|
||||
if v.used_in_non_child_fn {
|
||||
v.is_fn_local = false;
|
||||
}
|
||||
|
||||
v.var_initialized |= has_init;
|
||||
})
|
||||
.or_insert_with(|| VarUsageInfo {
|
||||
is_fn_local: true,
|
||||
|
@ -34,6 +34,23 @@ impl VisitMut for PrecompressOptimizer {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_mut_pat_or_expr(&mut self, n: &mut PatOrExpr) {
|
||||
n.visit_mut_children_with(self);
|
||||
|
||||
match n {
|
||||
PatOrExpr::Expr(e) => {
|
||||
if let Expr::Ident(i) = &**e {
|
||||
*n = PatOrExpr::Pat(i.clone().into())
|
||||
}
|
||||
}
|
||||
PatOrExpr::Pat(p) => {
|
||||
if let Pat::Expr(e) = &mut **p {
|
||||
*n = PatOrExpr::Expr(e.take());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_mut_stmts(&mut self, n: &mut Vec<Stmt>) {
|
||||
self.maybe_par(*HEAVY_TASK_PARALLELS, n, |v, n| {
|
||||
n.visit_mut_with(v);
|
||||
|
@ -186,16 +186,16 @@ impl CharFreq {
|
||||
return;
|
||||
}
|
||||
|
||||
#[cfg(feature = "debug")]
|
||||
{
|
||||
let considered = s
|
||||
.chars()
|
||||
.filter(|&c| Ident::is_valid_continue(c))
|
||||
.collect::<String>();
|
||||
if !considered.is_empty() {
|
||||
tracing::debug!("Scanning: `{}` with delta {}", considered, delta);
|
||||
}
|
||||
}
|
||||
// #[cfg(feature = "debug")]
|
||||
// {
|
||||
// let considered = s
|
||||
// .chars()
|
||||
// .filter(|&c| Ident::is_valid_continue(c))
|
||||
// .collect::<String>();
|
||||
// if !considered.is_empty() {
|
||||
// tracing::debug!("Scanning: `{}` with delta {}", considered, delta);
|
||||
// }
|
||||
// }
|
||||
|
||||
for &c in s.as_bytes() {
|
||||
match c {
|
||||
|
@ -10140,3 +10140,66 @@ fn issue_6051() {
|
||||
"###,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_6039_1() {
|
||||
run_default_exec_test(
|
||||
r###"
|
||||
function foo() {
|
||||
let walker = 0;
|
||||
|
||||
let arr = [];
|
||||
|
||||
function bar(defaultValue) {
|
||||
const myIndex = walker;
|
||||
walker += 1;
|
||||
|
||||
console.log({ arr });
|
||||
|
||||
if (arr.length < myIndex + 1) {
|
||||
arr[myIndex] = defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
return bar;
|
||||
}
|
||||
|
||||
const bar = foo();
|
||||
|
||||
bar(null);
|
||||
bar(null);
|
||||
bar(null);
|
||||
bar(null);
|
||||
bar(null);
|
||||
"###,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_6039_2() {
|
||||
run_default_exec_test(
|
||||
r###"
|
||||
var foo = function foo() {
|
||||
var walker = 0;
|
||||
var arr = [];
|
||||
function bar(defaultValue) {
|
||||
var myIndex = walker;
|
||||
walker += 1;
|
||||
console.log({
|
||||
arr: arr
|
||||
});
|
||||
if (arr.length < myIndex + 1) {
|
||||
arr[myIndex] = defaultValue;
|
||||
}
|
||||
}
|
||||
return bar;
|
||||
};
|
||||
var bar = foo();
|
||||
bar(null);
|
||||
bar(null);
|
||||
bar(null);
|
||||
bar(null);
|
||||
bar(null);
|
||||
"###,
|
||||
);
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
({}.x = 10);
|
||||
10;
|
||||
|
Loading…
Reference in New Issue
Block a user