enhance `merge_vars` (#5194)
authorAlex Lam S.L <alexlamsl@gmail.com>
Wed, 24 Nov 2021 10:21:50 +0000 (10:21 +0000)
committeralexlamsl <alexlamsl@gmail.com>
Wed, 24 Nov 2021 11:08:40 +0000 (19:08 +0800)
closes #5182

lib/compress.js
test/compress/collapse_vars.js
test/compress/drop-unused.js
test/compress/functions.js
test/compress/hoist_vars.js
test/compress/merge_vars.js

index b28ac5e..d17c945 100644 (file)
@@ -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);
index 16d8dc3..a5b51dc 100644 (file)
@@ -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: [
index eae53cd..7873f4f 100644 (file)
@@ -2916,7 +2916,7 @@ issue_4133: {
         console.log(a);
     }
     expect: {
-        var b = 1;
+        var a = 1;
         console.log(0);
     }
     expect_stdout: "0"
index fc3e7e2..8cf776f 100644 (file)
@@ -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);
         })();
     }
index fde3639..59fa6bb 100644 (file)
@@ -256,8 +256,9 @@ issue_4736: {
     expect: {
         (function() {
             (function() {
+                var b = 1 << 30;
                 0,
-                console.log(1073741824);
+                console.log(b);
             })();
         })();
     }
index 83bdf4f..9f89efe 100644 (file)
@@ -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"
+}