From: Alex Lam S.L Date: Sat, 5 May 2018 05:17:50 +0000 (+0800) Subject: fix various corner cases (#3123) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=f37b91879f32b6ec9f99bc89350b3767119e3638;p=UglifyJS.git fix various corner cases (#3123) --- diff --git a/lib/compress.js b/lib/compress.js index 31747c92..bdce24bc 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -355,20 +355,18 @@ merge(Compressor.prototype, { } else { def.fixed = false; } - if (def.init instanceof AST_Defun && !all(def.references, same_defun_scope)) { + if (def.init instanceof AST_Defun && !all(def.references, function(ref) { + var scope = ref.scope; + do { + if (def.scope === scope) return true; + } while (scope instanceof AST_Function && (scope = scope.parent_scope)); + })) { tw.defun_ids[def.id] = undefined; } def.recursive_refs = 0; def.references = []; def.should_replace = undefined; def.single_use = undefined; - - function same_defun_scope(ref) { - var scope = ref.scope; - do { - if (def.scope === scope) return true; - } while (scope instanceof AST_Function && (scope = scope.parent_scope)); - } } function reset_variables(tw, compressor, scope) { @@ -384,11 +382,11 @@ merge(Compressor.prototype, { }); } - function walk_defun(tw, def) { - if (def.id in tw.defun_ids) return; + function mark_defun(tw, def) { + if (def.id in tw.defun_ids) return def.fixed; if (!tw.in_loop) { - tw.defun_ids[def.id] = true; - def.fixed.walk(tw); + tw.defun_ids[def.id] = tw.safe_ids; + return def.fixed; } else if (tw.defun_ids[def.id] !== false) { tw.defun_ids[def.id] = undefined; } @@ -397,7 +395,7 @@ merge(Compressor.prototype, { function walk_defuns(tw, scope) { scope.functions.each(function(def) { if (def.init instanceof AST_Defun && tw.defun_ids[def.id] === undefined) { - tw.defun_ids[def.id] = true; + tw.defun_ids[def.id] = tw.safe_ids; def.init.walk(tw); } }); @@ -536,11 +534,14 @@ merge(Compressor.prototype, { return true; }); def(AST_Call, function(tw, descend) { - descend(); var exp = this.expression; - if (exp instanceof AST_SymbolRef && exp.fixed_value() instanceof AST_Defun) { - walk_defun(tw, exp.definition()); - } + if (!(exp instanceof AST_SymbolRef)) return; + var def = exp.definition(); + if (!(def.fixed instanceof AST_Defun)) return; + var defun = mark_defun(tw, def); + if (!defun) return; + descend(); + defun.walk(tw); return true; }); def(AST_Case, function(tw) { @@ -570,7 +571,7 @@ merge(Compressor.prototype, { }); def(AST_Defun, function(tw, descend, compressor) { var id = this.name.definition().id; - if (!tw.defun_ids[id]) return true; + if (tw.defun_ids[id] !== tw.safe_ids) return true; tw.defun_ids[id] = false; this.inlined = false; push(tw); @@ -707,7 +708,8 @@ merge(Compressor.prototype, { var parent; if (d.fixed instanceof AST_Defun && !((parent = tw.parent()) instanceof AST_Call && parent.expression === this)) { - walk_defun(tw, d); + var defun = mark_defun(tw, d); + if (defun) defun.walk(tw); } }); def(AST_Toplevel, function(tw, descend, compressor) { @@ -1121,7 +1123,7 @@ merge(Compressor.prototype, { if (is_lhs(node, multi_replacer.parent())) return node; def.replaced++; value_def.replaced--; - return candidate.value; + return candidate.value.clone(); } // Skip (non-executed) functions and (leading) default case in switch statements if (node instanceof AST_Default || node instanceof AST_Scope) return node; diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js index 950ebd07..c915041f 100644 --- a/test/compress/collapse_vars.js +++ b/test/compress/collapse_vars.js @@ -4056,6 +4056,36 @@ replace_all_var: { expect_stdout: "PASS" } +replace_all_var_scope: { + rename = true; + options = { + collapse_vars: true, + unused: true, + } + mangle = {} + input: { + var a = 100, b = 10; + (function(r, a) { + switch (~a) { + case (b += a): + case a++: + } + })(--b, a); + console.log(a, b); + } + expect: { + var a = 100, b = 10; + (function(c, o) { + switch (~a) { + case (b += a): + case o++: + } + })(--b, a); + console.log(a, b); + } + expect_stdout: "100 109" +} + cascade_statement: { options = { collapse_vars: true, diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js index 1d6d1896..14b6a46f 100644 --- a/test/compress/reduce_vars.js +++ b/test/compress/reduce_vars.js @@ -5998,3 +5998,35 @@ issue_3113_5: { "1", ] } + +conditional_nested: { + options = { + evaluate: true, + reduce_vars: true, + } + input: { + var a = 1, b = 0; + (function f(c) { + function g() { + c && (c.a = 0); + c && (c.a = 0); + c && (c[b++] *= 0); + } + g(a-- && f(g(c = 42))); + })(); + console.log(b); + } + expect: { + var a = 1, b = 0; + (function f(c) { + function g() { + c && (c.a = 0); + c && (c.a = 0); + c && (c[b++] *= 0); + } + g(a-- && f(g(c = 42))); + })(); + console.log(b); + } + expect_stdout: "2" +}