From 0b6c185818fa77fff0661ef959e5c0bdf8b5100f Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Wed, 24 Nov 2021 10:21:50 +0000 Subject: [PATCH] enhance `merge_vars` (#5194) closes #5182 --- lib/compress.js | 7 +++- test/compress/collapse_vars.js | 6 ++-- test/compress/drop-unused.js | 2 +- test/compress/functions.js | 5 +-- test/compress/hoist_vars.js | 3 +- test/compress/merge_vars.js | 63 ++++++++++++++++++++++++++++++++-- 6 files changed, 75 insertions(+), 11 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index b28ac5e2..d17c9454 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -203,6 +203,7 @@ merge(Compressor.prototype, { if (this.option("expression")) { node.process_expression(true); } + var merge_vars = this.options.merge_vars; var passes = +this.options.passes || 1; var min_count = 1 / 0; var stopping = false; @@ -211,6 +212,7 @@ merge(Compressor.prototype, { node.figure_out_scope(mangle); if (pass > 0 || this.option("reduce_vars")) node.reset_opt_flags(this); + this.options.merge_vars = merge_vars && (stopping || pass == passes - 1); node = node.transform(this); if (passes > 1) { var count = 0; @@ -259,8 +261,8 @@ merge(Compressor.prototype, { descend(node, this); var opt = node.optimize(this); if (is_scope && opt === node && !this.has_directive("use asm") && !opt.pinned()) { - opt.merge_variables(this); opt.drop_unused(this); + if (opt.merge_variables(this)) opt.drop_unused(this); descend(opt, this); } if (opt === node) opt._squeezed = true; @@ -5994,6 +5996,7 @@ merge(Compressor.prototype, { }); tw.directives = Object.create(compressor.directives); self.walk(tw); + var changed = false; var merged = Object.create(null); while (first.length && last.length) { var head = first.pop(); @@ -6037,10 +6040,12 @@ merge(Compressor.prototype, { def.references = refs.concat(def.references); def.fixed = tail.definition.fixed && def.fixed; merged[id] = def; + changed = true; break; } while (last.length); if (skipped.length) last = last.concat(skipped); } + return changed; function push() { segment = Object.create(segment); diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js index 16d8dc3d..a5b51dc7 100644 --- a/test/compress/collapse_vars.js +++ b/test/compress/collapse_vars.js @@ -9522,7 +9522,7 @@ issue_5182: { hoist_props: true, inline: true, merge_vars: true, - passes: 3, + passes: 4, reduce_vars: true, sequences: true, side_effects: true, @@ -9555,8 +9555,8 @@ issue_5182: { console.log(obj.foo(1, 2), global.log("PASS")); } expect: { - var obj = console; - global.log = obj.log, + var con = console; + global.log = con.log, console.log((console.log("BAR:", 3), -1), global.log("PASS")); } expect_stdout: [ diff --git a/test/compress/drop-unused.js b/test/compress/drop-unused.js index eae53cdb..7873f4f4 100644 --- a/test/compress/drop-unused.js +++ b/test/compress/drop-unused.js @@ -2916,7 +2916,7 @@ issue_4133: { console.log(a); } expect: { - var b = 1; + var a = 1; console.log(0); } expect_stdout: "0" diff --git a/test/compress/functions.js b/test/compress/functions.js index fc3e7e2d..8cf776fa 100644 --- a/test/compress/functions.js +++ b/test/compress/functions.js @@ -4857,8 +4857,9 @@ issue_4155: { } expect: { (function() { - void console.log(b); - var b = function() {}; + var a; + void console.log(a); + function b() {} b && console.log(typeof b); })(); } diff --git a/test/compress/hoist_vars.js b/test/compress/hoist_vars.js index fde3639d..59fa6bbe 100644 --- a/test/compress/hoist_vars.js +++ b/test/compress/hoist_vars.js @@ -256,8 +256,9 @@ issue_4736: { expect: { (function() { (function() { + var b = 1 << 30; 0, - console.log(1073741824); + console.log(b); })(); })(); } diff --git a/test/compress/merge_vars.js b/test/compress/merge_vars.js index 83bdf4fa..9f89efe5 100644 --- a/test/compress/merge_vars.js +++ b/test/compress/merge_vars.js @@ -476,9 +476,9 @@ issue_4112: { try { throw 42; } catch (e) { - var a = e; - for (e in a); - a = function() {}; + var o = e; + for (e in o); + function a() {} console.log(typeof a); return a; } @@ -3377,3 +3377,60 @@ issue_4956_2: { } expect_stdout: "42" } + +issue_5182: { + options = { + arrows: true, + collapse_vars: true, + evaluate: true, + hoist_props: true, + inline: true, + merge_vars: true, + passes: 4, + reduce_vars: true, + sequences: true, + side_effects: true, + toplevel: true, + unused: true, + } + input: { + try { + var con = console; + } catch (x) {} + global.log = con.log; + var jump = function(x) { + console.log("JUMP:", x * 10); + return x + x; + }; + var jump2 = jump; + var run = function(x) { + console.log("RUN:", x * -10); + return x * x; + }; + var run2 = run; + var bar = (x, y) => { + console.log("BAR:", x + y); + return x - y; + }; + var bar2 = bar; + var obj = { + foo: bar2, + go: run2, + not_used: jump2, + }; + console.log(obj.foo(1, 2), global.log("PASS")); + } + expect: { + try { + var con = console; + } catch (x) {} + global.log = con.log, + console.log((console.log("BAR:", 3), -1), global.log("PASS")); + } + expect_stdout: [ + "BAR: 3", + "PASS", + "-1 undefined", + ] + node_version: ">=4" +}