diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2021-05-01 14:37:52 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-01 21:37:52 +0800 |
commit | 16411dcb8721e9901271db74c3409e720c2f8ec5 (patch) | |
tree | d7ee3aa3fcf0790e77662ee45918d78bb533fce5 /lib/compress.js | |
parent | 8bbfaacdae0b63987652766b9f3a327ff6d06231 (diff) | |
download | tracifyjs-16411dcb8721e9901271db74c3409e720c2f8ec5.tar.gz tracifyjs-16411dcb8721e9901271db74c3409e720c2f8ec5.zip |
enhance `collapse_vars` (#4885)
Diffstat (limited to 'lib/compress.js')
-rw-r--r-- | lib/compress.js | 69 |
1 files changed, 38 insertions, 31 deletions
diff --git a/lib/compress.js b/lib/compress.js index 26bcbc72..9201d890 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -1902,6 +1902,7 @@ merge(Compressor.prototype, { hit_stack = candidates.pop(); var hit_index = 0; var candidate = hit_stack[hit_stack.length - 1]; + var remaining; var value_def = null; var stop_after = null; var stop_if_hit = null; @@ -1944,25 +1945,22 @@ merge(Compressor.prototype, { statements[i].transform(scanner); } if (value_def) { - var def = lhs.definition(); - var referenced = def.references.length - def.replaced; - if (candidate instanceof AST_Assign) referenced--; - if (!replaced || referenced > replaced) { + if (!replaced || remaining > replaced) { candidates.push(hit_stack); force_single = true; continue; } + var def = lhs.definition(); abort = false; hit_index = 0; hit = funarg; for (var i = stat_index; !abort && i < statements.length; i++) { if (!statements[i].transform(multi_replacer)) statements.splice(i--, 1); } - if (candidate !== hit_stack[hit_stack.length - 1]) { - replaced = false; - } else if (candidate instanceof AST_VarDef) { - replaced = !compressor.exposed(def) && def.references.length == def.replaced; - } + replaced = candidate instanceof AST_VarDef + && candidate === hit_stack[hit_stack.length - 1] + && def.references.length == def.replaced + && !compressor.exposed(def); value_def.last_ref = false; value_def.single_use = false; } @@ -2252,7 +2250,7 @@ merge(Compressor.prototype, { if (!arg) continue; var candidate = make_node(AST_VarDef, sym, { name: sym, - value: arg + value: arg, }); candidate.name_index = i; candidate.arg_index = value ? len + i : i; @@ -2268,12 +2266,11 @@ merge(Compressor.prototype, { extract_candidates(node, unused); }); } else if (expr instanceof AST_Assign) { - if (!(expr.left instanceof AST_Destructured)) candidates.push(hit_stack.slice()); - extract_candidates(expr.left); + var lhs = expr.left; + if (!(lhs instanceof AST_Destructured)) candidates.push(hit_stack.slice()); + extract_candidates(lhs); extract_candidates(expr.right); - if (expr.left instanceof AST_SymbolRef) { - assignments[expr.left.name] = (assignments[expr.left.name] || 0) + 1; - } + if (lhs instanceof AST_SymbolRef) assignments[lhs.name] = (assignments[lhs.name] || 0) + 1; } else if (expr instanceof AST_Await) { extract_candidates(expr.expression, unused); } else if (expr instanceof AST_Binary) { @@ -2555,6 +2552,7 @@ merge(Compressor.prototype, { force_single = false; return; } + if (remaining < 1) return; var value = rhs instanceof AST_Assign && rhs.operator == "=" ? rhs.left : rhs; if (!(value instanceof AST_SymbolRef)) return; var def = value.definition(); @@ -2577,32 +2575,41 @@ merge(Compressor.prototype, { function get_lhs(expr) { if (expr instanceof AST_Assign) { - var def, lhs = expr.left; - if (expr.operator == "=" - && lhs instanceof AST_SymbolRef - && (def = lhs.definition()).references[0] === lhs - && !(scope.uses_arguments && is_funarg(def)) - && !compressor.exposed(def)) { - var referenced = def.references.length - def.replaced; - if (referenced > 1) mangleable_var(expr.right); - } + var lhs = expr.left; + if (expr.operator != "=") return lhs; + if (!(lhs instanceof AST_SymbolRef)) return lhs; + var def = lhs.definition(); + if (scope.uses_arguments && is_funarg(def)) return lhs; + if (compressor.exposed(def)) return lhs; + remaining = def.references.length - def.replaced - (assignments[def.name] || 0); + if (def.fixed && lhs.fixed) remaining = Math.min(remaining, def.references.filter(function(ref) { + return ref.fixed === lhs.fixed; + }).length - 1); + mangleable_var(expr.right); return lhs; } if (expr instanceof AST_Binary) return expr.right.left; if (expr instanceof AST_Unary) return expr.expression; if (expr instanceof AST_VarDef) { - var def = expr.name.definition(); + var lhs = expr.name; + var def = lhs.definition(); if (def.const_redefs) return; - if (!member(expr.name, def.orig)) return; + if (!member(lhs, def.orig)) return; if (scope.uses_arguments && is_funarg(def)) return; var declared = def.orig.length - def.eliminated - (declare_only[def.name] || 0); - var referenced = def.references.length - def.replaced - (assignments[def.name] || 0); - if (declared > 1 && !(expr.name instanceof AST_SymbolFunarg)) { + remaining = def.references.length - def.replaced - (assignments[def.name] || 0); + if (def.fixed) remaining = Math.min(remaining, def.references.filter(function(ref) { + if (!ref.fixed) return true; + if (!ref.fixed.assigns) return true; + var assign = ref.fixed.assigns[0]; + return assign === lhs || get_rvalue(assign) === expr.value; + }).length); + if (declared > 1 && !(lhs instanceof AST_SymbolFunarg)) { mangleable_var(expr.value); - return make_node(AST_SymbolRef, expr.name, expr.name); + return make_node(AST_SymbolRef, lhs, lhs); } - if (mangleable_var(expr.value) || referenced == 1 && !compressor.exposed(def)) { - return make_node(AST_SymbolRef, expr.name, expr.name); + if (mangleable_var(expr.value) || remaining == 1 && !compressor.exposed(def)) { + return make_node(AST_SymbolRef, lhs, lhs); } return; } |