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:
Donny/강동윤 2022-10-06 11:09:13 +09:00 committed by GitHub
parent ad58d5daf8
commit 36d467e7d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 119 additions and 11 deletions

View 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);

View File

@ -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,

View File

@ -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);

View File

@ -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 {

View File

@ -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);
"###,
);
}