fix corner cases in `collapse_vars` (#4249)
authorAlex Lam S.L <alexlamsl@gmail.com>
Fri, 30 Oct 2020 02:04:23 +0000 (02:04 +0000)
committerGitHub <noreply@github.com>
Fri, 30 Oct 2020 02:04:23 +0000 (10:04 +0800)
fixes #4248

lib/compress.js
test/compress/collapse_vars.js
test/compress/const.js
test/compress/let.js

index 822e050..0b6ad85 100644 (file)
@@ -1556,12 +1556,17 @@ merge(Compressor.prototype, {
                 if (node instanceof AST_Defun) return funarg && lhs.name === node.name.name;
                 if (node instanceof AST_DWLoop) return true;
                 if (node instanceof AST_LoopControl) return true;
+                if (node instanceof AST_SymbolRef) {
+                    if (node.is_declared(compressor) ? node.fixed_value() || all(node.definition().orig, function(sym) {
+                        return !(sym instanceof AST_SymbolConst || sym instanceof AST_SymbolLet);
+                    }) : parent instanceof AST_Assign && parent.operator == "=" && parent.left === node) return false;
+                    if (!replace_all) return true;
+                    scan_rhs = false;
+                    return false;
+                }
                 if (node instanceof AST_Try) return true;
                 if (node instanceof AST_With) return true;
-                if (replace_all) return false;
-                return node instanceof AST_SymbolRef
-                    && !node.is_declared(compressor)
-                    && !(parent instanceof AST_Assign && parent.operator == "=" && parent.left === node);
+                return false;
             }
 
             function in_conditional(node, parent) {
@@ -1710,6 +1715,8 @@ merge(Compressor.prototype, {
                     extract_candidates(expr.condition);
                     extract_candidates(expr.consequent);
                     extract_candidates(expr.alternative);
+                } else if (expr instanceof AST_Definitions) {
+                    expr.definitions.forEach(extract_candidates);
                 } else if (expr instanceof AST_Dot) {
                     extract_candidates(expr.expression);
                 } else if (expr instanceof AST_DWLoop) {
@@ -1763,18 +1770,18 @@ merge(Compressor.prototype, {
                     } else {
                         extract_candidates(expr.expression);
                     }
-                } else if (expr instanceof AST_Var) {
-                    expr.definitions.forEach(extract_candidates);
                 } else if (expr instanceof AST_VarDef) {
-                    if (expr.value) {
-                        var def = expr.name.definition();
-                        if (def.references.length > def.replaced) {
-                            candidates.push(hit_stack.slice());
+                    if (expr.name instanceof AST_SymbolVar) {
+                        if (expr.value) {
+                            var def = expr.name.definition();
+                            if (def.references.length > def.replaced) {
+                                candidates.push(hit_stack.slice());
+                            }
+                        } else {
+                            declare_only[expr.name.name] = (declare_only[expr.name.name] || 0) + 1;
                         }
-                        extract_candidates(expr.value);
-                    } else {
-                        declare_only[expr.name.name] = (declare_only[expr.name.name] || 0) + 1;
                     }
+                    if (expr.value) extract_candidates(expr.value);
                 }
                 hit_stack.pop();
             }
index dea01b6..edf4795 100644 (file)
@@ -8577,3 +8577,28 @@ issue_4242: {
     }
     expect_stdout: "undefined"
 }
+
+issue_4248: {
+    options = {
+        collapse_vars: true,
+    }
+    input: {
+        var a = 0;
+        try {
+            a = 1;
+            b[1];
+        } catch (e) {
+            console.log(a);
+        }
+    }
+    expect: {
+        var a = 0;
+        try {
+            a = 1;
+            b[1];
+        } catch (e) {
+            console.log(a);
+        }
+    }
+    expect_stdout: "1"
+}
index 2f88975..896e8c3 100644 (file)
@@ -1104,3 +1104,34 @@ issue_4245: {
     }
     expect_stdout: true
 }
+
+issue_4248: {
+    options = {
+        collapse_vars: true,
+    }
+    input: {
+        var a = "FAIL";
+        try {
+            (function() {
+                a = "PASS";
+                b[a];
+                const b = 0;
+            })();
+        } catch (e) {
+            console.log(a);
+        }
+    }
+    expect: {
+        var a = "FAIL";
+        try {
+            (function() {
+                a = "PASS";
+                b[a];
+                const b = 0;
+            })();
+        } catch (e) {
+            console.log(a);
+        }
+    }
+    expect_stdout: "PASS"
+}
index deb4812..9a6fc94 100644 (file)
@@ -916,3 +916,37 @@ issue_4245: {
     expect_stdout: ReferenceError("a is not defined")
     node_version: ">=4"
 }
+
+issue_4248: {
+    options = {
+        collapse_vars: true,
+    }
+    input: {
+        var a = "FAIL";
+        try {
+            (function() {
+                "use strict";
+                a = "PASS";
+                b[a];
+                let b;
+            })();
+        } catch (e) {
+            console.log(a);
+        }
+    }
+    expect: {
+        var a = "FAIL";
+        try {
+            (function() {
+                "use strict";
+                a = "PASS";
+                b[a];
+                let b;
+            })();
+        } catch (e) {
+            console.log(a);
+        }
+    }
+    expect_stdout: "PASS"
+    node_version: ">=4"
+}