[Pkg-javascript-commits] [uglifyjs] 313/491: account for side-effects in conditional call inversion (#2562)

Jonas Smedegaard dr at jones.dk
Wed Feb 14 19:51:48 UTC 2018


This is an automated email from the git hooks/post-receive script.

js pushed a commit to annotated tag debian/3.3.10-1
in repository uglifyjs.

commit 3e34f62a1c48ab45db34cfb08d8dd2118c5780f0
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date:   Fri Dec 8 01:15:31 2017 +0800

    account for side-effects in conditional call inversion (#2562)
    
    fixes #2560
---
 lib/compress.js               |  31 +++++++---
 test/compress/conditionals.js | 128 +++++++++++++++++++++++++++++++++++-------
 2 files changed, 132 insertions(+), 27 deletions(-)

diff --git a/lib/compress.js b/lib/compress.js
index 4195ab2..e59dce6 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -4652,18 +4652,22 @@ merge(Compressor.prototype, {
             });
         }
         // x ? y(a) : y(b) --> y(x ? a : b)
+        var arg_index;
         if (consequent instanceof AST_Call
             && alternative.TYPE === consequent.TYPE
-            && consequent.args.length == 1
-            && alternative.args.length == 1
+            && consequent.args.length > 0
+            && consequent.args.length == alternative.args.length
             && consequent.expression.equivalent_to(alternative.expression)
-            && !consequent.expression.has_side_effects(compressor)) {
-            consequent.args[0] = make_node(AST_Conditional, self, {
+            && !self.condition.has_side_effects(compressor)
+            && !consequent.expression.has_side_effects(compressor)
+            && typeof (arg_index = single_arg_diff()) == "number") {
+            var node = consequent.clone();
+            node.args[arg_index] = make_node(AST_Conditional, self, {
                 condition: self.condition,
-                consequent: consequent.args[0],
-                alternative: alternative.args[0]
+                consequent: consequent.args[arg_index],
+                alternative: alternative.args[arg_index]
             });
-            return consequent;
+            return node;
         }
         // x?y?z:a:a --> x&&y?z:a
         if (consequent instanceof AST_Conditional
@@ -4760,6 +4764,19 @@ merge(Compressor.prototype, {
                     && node.expression instanceof AST_Constant
                     && node.expression.getValue());
         }
+
+        function single_arg_diff() {
+            var a = consequent.args;
+            var b = alternative.args;
+            for (var i = 0, len = a.length; i < len; i++) {
+                if (!a[i].equivalent_to(b[i])) {
+                    for (var j = i + 1; j < len; j++) {
+                        if (!a[j].equivalent_to(b[j])) return;
+                    }
+                    return i;
+                }
+            }
+        }
     });
 
     OPT(AST_Boolean, function(self, compressor){
diff --git a/test/compress/conditionals.js b/test/compress/conditionals.js
index 89c0526..143ece4 100644
--- a/test/compress/conditionals.js
+++ b/test/compress/conditionals.js
@@ -166,22 +166,24 @@ cond_1: {
         conditionals: true
     };
     input: {
-        var do_something; // if undeclared it's assumed to have side-effects
-        if (some_condition()) {
-            do_something(x);
-        } else {
-            do_something(y);
-        }
-        if (some_condition()) {
-            side_effects(x);
-        } else {
-            side_effects(y);
+        function foo(do_something, some_condition) {
+            if (some_condition) {
+                do_something(x);
+            } else {
+                do_something(y);
+            }
+            if (some_condition) {
+                side_effects(x);
+            } else {
+                side_effects(y);
+            }
         }
     }
     expect: {
-        var do_something;
-        do_something(some_condition() ? x : y);
-        some_condition() ? side_effects(x) : side_effects(y);
+        function foo(do_something, some_condition) {
+            do_something(some_condition ? x : y);
+            some_condition ? side_effects(x) : side_effects(y);
+        }
     }
 }
 
@@ -190,16 +192,18 @@ cond_2: {
         conditionals: true
     };
     input: {
-        var x, FooBar;
-        if (some_condition()) {
-            x = new FooBar(1);
-        } else {
-            x = new FooBar(2);
+        function foo(x, FooBar, some_condition) {
+            if (some_condition) {
+                x = new FooBar(1);
+            } else {
+                x = new FooBar(2);
+            }
         }
     }
     expect: {
-        var x, FooBar;
-        x = new FooBar(some_condition() ? 1 : 2);
+        function foo(x, FooBar, some_condition) {
+            x = new FooBar(some_condition ? 1 : 2);
+        }
     }
 }
 
@@ -605,6 +609,42 @@ cond_8c: {
     }
 }
 
+cond_9: {
+    options = {
+        conditionals: true,
+    }
+    input: {
+        function f(x, y) {
+            g() ? x(1) : x(2);
+            x ? (y || x)() : (y || x)();
+            x ? y(a, b) : y(d, b, c);
+            x ? y(a, b, c) : y(a, b, c);
+            x ? y(a, b, c) : y(a, b, f);
+            x ? y(a, b, c) : y(a, e, c);
+            x ? y(a, b, c) : y(a, e, f);
+            x ? y(a, b, c) : y(d, b, c);
+            x ? y(a, b, c) : y(d, b, f);
+            x ? y(a, b, c) : y(d, e, c);
+            x ? y(a, b, c) : y(d, e, f);
+        }
+    }
+    expect: {
+        function f(x, y) {
+            g() ? x(1) : x(2);
+            x, (y || x)();
+            x ? y(a, b) : y(d, b, c);
+            x, y(a, b, c);
+            y(a, b, x ? c : f);
+            y(a, x ? b : e, c);
+            x ? y(a, b, c) : y(a, e, f);
+            y(x ? a : d, b, c);
+            x ? y(a, b, c) : y(d, b, f);
+            x ? y(a, b, c) : y(d, e, c);
+            x ? y(a, b, c) : y(d, e, f);
+        }
+    }
+}
+
 ternary_boolean_consequent: {
     options = {
         collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
@@ -1115,3 +1155,51 @@ issue_2535_2: {
         "false",
     ]
 }
+
+issue_2560: {
+    options = {
+        conditionals: true,
+        inline: true,
+        reduce_funcs: true,
+        reduce_vars: true,
+        toplevel: true,
+        unused: true,
+    }
+    input: {
+        function log(x) {
+            console.log(x);
+        }
+        function foo() {
+            return log;
+        }
+        function bar() {
+            if (x !== (x = foo())) {
+                x(1);
+            } else {
+                x(2);
+            }
+        }
+        var x = function() {
+            console.log("init");
+        };
+        bar();
+        bar();
+    }
+    expect: {
+        function log(x) {
+            console.log(x);
+        }
+        function bar() {
+            x !== (x = log) ? x(1) : x(2);
+        }
+        var x = function() {
+            console.log("init");
+        };
+        bar();
+        bar();
+    }
+    expect_stdout: [
+        "1",
+        "2",
+    ]
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/uglifyjs.git



More information about the Pkg-javascript-commits mailing list