improve handling of `switch` statements (#4114)
authorAlex Lam S.L <alexlamsl@gmail.com>
Wed, 16 Sep 2020 19:12:08 +0000 (20:12 +0100)
committerGitHub <noreply@github.com>
Wed, 16 Sep 2020 19:12:08 +0000 (03:12 +0800)
lib/ast.js
lib/compress.js
test/compress/reduce_vars.js

index 73f4696..a0d79a8 100644 (file)
@@ -631,6 +631,9 @@ var AST_Switch = DEFNODE("Switch", "expression", {
     },
     _validate: function() {
         must_be_expression(this, "expression");
+        this.body.forEach(function(node) {
+            if (!(node instanceof AST_SwitchBranch)) throw new Error("body must be AST_SwitchBranch[]");
+        });
     },
 }, AST_Block);
 
index e313905..f19832e 100644 (file)
@@ -672,15 +672,6 @@ merge(Compressor.prototype, {
                 exp.left.definition().bool_fn++;
             }
         });
-        def(AST_Case, function(tw) {
-            push(tw);
-            this.expression.walk(tw);
-            pop(tw);
-            push(tw);
-            walk_body(this, tw);
-            pop(tw);
-            return true;
-        });
         def(AST_Conditional, function(tw) {
             this.condition.walk(tw);
             push(tw);
@@ -691,12 +682,6 @@ merge(Compressor.prototype, {
             pop(tw);
             return true;
         });
-        def(AST_Default, function(tw, descend) {
-            push(tw);
-            descend();
-            pop(tw);
-            return true;
-        });
         def(AST_Defun, function(tw, descend, compressor) {
             var id = this.name.definition().id;
             if (tw.defun_visited[id]) return true;
@@ -822,6 +807,27 @@ merge(Compressor.prototype, {
             pop(tw);
             return true;
         });
+        def(AST_Switch, function(tw) {
+            this.expression.walk(tw);
+            var first = true;
+            this.body.forEach(function(branch) {
+                if (branch instanceof AST_Default) return;
+                branch.expression.walk(tw);
+                if (first) {
+                    first = false;
+                    push(tw);
+                }
+            })
+            if (!first) pop(tw);
+            walk_body(this, tw);
+            return true;
+        });
+        def(AST_SwitchBranch, function(tw) {
+            push(tw);
+            walk_body(this, tw);
+            pop(tw);
+            return true;
+        });
         def(AST_SymbolCatch, function() {
             this.definition().fixed = false;
         });
@@ -4311,7 +4317,7 @@ merge(Compressor.prototype, {
         if (!compressor.option("merge_vars")) return;
         var self = this, segment = null;
         var first = [], last = [], index = 0;
-        var declarations = Object.create(null);
+        var declarations = new Dictionary();
         var references = Object.create(null);
         var prev = Object.create(null);
         var tw = new TreeWalker(function(node, descend) {
@@ -4394,19 +4400,16 @@ merge(Compressor.prototype, {
             }
             if (node instanceof AST_Switch) {
                 node.expression.walk(tw);
-                var first = true;
+                var save = segment;
                 node.body.forEach(function(branch) {
                     if (branch instanceof AST_Default) return;
-                    if (!first) push();
                     branch.expression.walk(tw);
-                    if (!first) pop();
-                    first = false;
+                    if (save === segment) push();
                 });
+                segment = save;
                 node.body.forEach(function(branch) {
                     push();
-                    branch.body.forEach(function(stat) {
-                        stat.walk(tw);
-                    });
+                    walk_body(branch, tw);
                     pop();
                 });
                 return true;
@@ -4421,16 +4424,12 @@ merge(Compressor.prototype, {
             }
             if (node instanceof AST_Try) {
                 push();
-                node.body.forEach(function(stat) {
-                    stat.walk(tw);
-                });
+                walk_body(node, tw);
                 pop();
                 if (node.bcatch) {
                     references[node.bcatch.argname.definition().id] = false;
                     push();
-                    node.bcatch.body.forEach(function(stat) {
-                        stat.walk(tw);
-                    });
+                    walk_body(node.bcatch, tw);
                     pop();
                 }
                 if (node.bfinally) node.bfinally.walk(tw);
@@ -4448,9 +4447,7 @@ merge(Compressor.prototype, {
                     node.value.walk(tw);
                     mark(node.name, true);
                 } else {
-                    var id = node.name.definition().id;
-                    if (!(id in declarations)) declarations[id] = [];
-                    declarations[id].push(node.name);
+                    declarations.add(node.name.definition().id, node.name);
                 }
                 return true;
             }
@@ -4475,7 +4472,7 @@ merge(Compressor.prototype, {
                     continue;
                 }
                 var orig = [], refs = [];
-                if (id in declarations) declarations[id].forEach(function(sym) {
+                if (declarations.has(id)) declarations.get(id).forEach(function(sym) {
                     sym.thedef = def;
                     sym.name = def.name;
                     orig.push(sym);
index 34d358c..c911efe 100644 (file)
@@ -2176,6 +2176,7 @@ issue_1670_6: {
         keep_fargs: false,
         reduce_funcs: true,
         reduce_vars: true,
+        sequences: true,
         side_effects: true,
         switches: true,
         unused: true,
@@ -2193,10 +2194,9 @@ issue_1670_6: {
         })(1);
     }
     expect: {
-        (function(a) {
-            a = 1;
-            console.log(a);
-        })(1);
+        (function() {
+            console.log(1);
+        })();
     }
     expect_stdout: "1"
 }