fix variable substitution (#1816)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sun, 16 Apr 2017 09:25:39 +0000 (17:25 +0800)
committerGitHub <noreply@github.com>
Sun, 16 Apr 2017 09:25:39 +0000 (17:25 +0800)
- let `collapse_vars` take care of value containing any symbols
- improve overhead accounting

lib/compress.js
test/compress/issue-1656.js
test/compress/reduce_vars.js

index c8b15ff..6062be5 100644 (file)
@@ -3553,7 +3553,9 @@ merge(Compressor.prototype, {
                 return make_node(AST_Infinity, self).optimize(compressor);
             }
         }
-        if (compressor.option("evaluate") && compressor.option("reduce_vars")) {
+        if (compressor.option("evaluate")
+            && compressor.option("reduce_vars")
+            && is_lhs(self, compressor.parent()) !== self) {
             var d = self.definition();
             var fixed = self.fixed_value();
             if (fixed) {
@@ -3561,21 +3563,45 @@ merge(Compressor.prototype, {
                     var init = fixed.evaluate(compressor);
                     if (init !== fixed) {
                         init = make_node_from_constant(init, fixed);
-                        var value = best_of_expression(init.optimize(compressor), fixed).print_to_string().length;
+                        var value = init.optimize(compressor).print_to_string().length;
+                        var fn;
+                        if (has_symbol_ref(fixed)) {
+                            fn = function() {
+                                var result = init.optimize(compressor);
+                                return result === init ? result.clone(true) : result;
+                            };
+                        } else {
+                            value = Math.min(value, fixed.print_to_string().length);
+                            fn = function() {
+                                var result = best_of_expression(init.optimize(compressor), fixed);
+                                return result === init || result === fixed ? result.clone(true) : result;
+                            };
+                        }
                         var name = d.name.length;
-                        var freq = d.references.length;
-                        var overhead = d.global || !freq ? 0 : (name + 2 + value) / freq;
-                        d.should_replace = value <= name + overhead ? init : false;
+                        var overhead = 0;
+                        if (compressor.option("unused") && (!d.global || compressor.option("toplevel"))) {
+                            overhead = (name + 2 + value) / d.references.length;
+                        }
+                        d.should_replace = value <= name + overhead ? fn : false;
                     } else {
                         d.should_replace = false;
                     }
                 }
                 if (d.should_replace) {
-                    return best_of_expression(d.should_replace.optimize(compressor), fixed).clone(true);
+                    return d.should_replace();
                 }
             }
         }
         return self;
+
+        function has_symbol_ref(value) {
+            var found;
+            value.walk(new TreeWalker(function(node) {
+                if (node instanceof AST_SymbolRef) found = true;
+                if (found) return true;
+            }));
+            return found;
+        }
     });
 
     function is_atomic(lhs, self) {
index 8b683a2..c4c8f86 100644 (file)
@@ -35,11 +35,11 @@ f7: {
         console.log(a, b);
     }
     expect_exact: [
-        "var a = 100, b = 10;",
+        "var b = 10;",
         "",
         "!function() {",
-        "    for (;b = a, !1; ) ;",
-        "}(), console.log(a, b);",
+        "    for (;b = 100, !1; ) ;",
+        "}(), console.log(100, b);",
     ]
     expect_stdout: true
 }
index b6f711a..7621dd4 100644 (file)
@@ -1995,3 +1995,55 @@ catch_var: {
     }
     expect_stdout: "true"
 }
+
+issue_1814_1: {
+    options = {
+        evaluate: true,
+        reduce_vars: true,
+        unused: true,
+    }
+    input: {
+        const a = 42;
+        !function() {
+            var b = a;
+            !function(a) {
+                console.log(a++, b);
+            }(0);
+        }();
+    }
+    expect: {
+        const a = 42;
+        !function() {
+            !function(a) {
+                console.log(a++, 42);
+            }(0);
+        }();
+    }
+    expect_stdout: "0 42"
+}
+
+issue_1814_2: {
+    options = {
+        evaluate: true,
+        reduce_vars: true,
+        unused: true,
+    }
+    input: {
+        const a = "32";
+        !function() {
+            var b = a + 1;
+            !function(a) {
+                console.log(a++, b);
+            }(0);
+        }();
+    }
+    expect: {
+        const a = "32";
+        !function() {
+            !function(a) {
+                console.log(a++, "321");
+            }(0);
+        }();
+    }
+    expect_stdout: "0 '321'"
+}