enhance `collapse_vars` around lazy operations (#2369)
authorAlex Lam S.L <alexlamsl@gmail.com>
Wed, 18 Oct 2017 20:52:00 +0000 (04:52 +0800)
committerGitHub <noreply@github.com>
Wed, 18 Oct 2017 20:52:00 +0000 (04:52 +0800)
lib/compress.js
test/compress/collapse_vars.js

index b89e0df..374456a 100644 (file)
@@ -778,6 +778,7 @@ merge(Compressor.prototype, {
                     // Locate symbols which may execute code outside of scanning range
                     var lvalues = get_lvalues(candidate);
                     if (lhs instanceof AST_SymbolRef) lvalues[lhs.name] = false;
+                    var one_off = lhs instanceof AST_Symbol && lhs.definition().references.length == 1;
                     var side_effects = value_has_side_effects(candidate);
                     var hit = candidate.name instanceof AST_SymbolFunarg;
                     var abort = false, replaced = false;
@@ -844,11 +845,11 @@ merge(Compressor.prototype, {
                                    || side_effects && !references_in_scope(node.definition()))
                             || (sym = lhs_or_def(node))
                                 && (sym instanceof AST_PropAccess || sym.name in lvalues)
-                            || parent instanceof AST_Binary && lazy_op(parent.operator)
-                            || parent instanceof AST_Case
-                            || parent instanceof AST_Conditional
-                            || parent instanceof AST_For
-                            || parent instanceof AST_If) {
+                            || (side_effects || !one_off)
+                                && (parent instanceof AST_Binary && lazy_op(parent.operator)
+                                    || parent instanceof AST_Case
+                                    || parent instanceof AST_Conditional
+                                    || parent instanceof AST_If)) {
                             if (!(node instanceof AST_Scope)) descend(node, tt);
                             abort = true;
                             return node;
index 13fff97..52b2ddf 100644 (file)
@@ -2951,3 +2951,68 @@ issue_2364_9: {
     }
     expect_stdout: "PASS"
 }
+
+pure_getters_chain: {
+    options = {
+        collapse_vars: true,
+        pure_getters: true,
+    }
+    input: {
+        function o(t, r) {
+            var a = t[1], s = t[2], o = t[3], i = t[5];
+            return a <= 23 && s <= 59 && o <= 59 && (!r || i);
+        }
+        console.log(o([ , 23, 59, 59, , 42], 1));
+    }
+    expect: {
+        function o(t, r) {
+            return t[1] <= 23 && t[2] <= 59 && t[3] <= 59 && (!r || t[5]);
+        }
+        console.log(o([ , 23, 59, 59, , 42], 1));
+    }
+    expect_stdout: "42"
+}
+
+conditional_1: {
+    options = {
+        collapse_vars: true,
+    }
+    input: {
+        function f(a, b) {
+            var c = "";
+            var d = b ? ">" : "<";
+            if (a) c += "=";
+            return c += d;
+        }
+        console.log(f(0, 0), f(0, 1), f(1, 0), f(1, 1));
+    }
+    expect: {
+        function f(a, b) {
+            var c = "";
+            if (a) c += "=";
+            return c += b ? ">" : "<";
+        }
+        console.log(f(0, 0), f(0, 1), f(1, 0), f(1, 1));
+    }
+    expect_stdout: "< > =< =>"
+}
+
+conditional_2: {
+    options = {
+        collapse_vars: true,
+    }
+    input: {
+        function f(a, b) {
+            var c = a + 1, d = a + 2;
+            return b ? c : d;
+        }
+        console.log(f(3, 0), f(4, 1));
+    }
+    expect: {
+        function f(a, b) {
+            return b ? a + 1 : a + 2;
+        }
+        console.log(f(3, 0), f(4, 1));
+    }
+    expect_stdout: "5 5"
+}