[Pkg-javascript-commits] [uglifyjs] 109/228: fix `AST_Node.optimize()` (#1602)

Jonas Smedegaard dr at jones.dk
Sat Apr 15 14:25:21 UTC 2017


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

js pushed a commit to branch master
in repository uglifyjs.

commit 8223b2e0db4cc41d467d9b94b05511a36c320184
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date:   Wed Mar 15 18:44:13 2017 +0800

    fix `AST_Node.optimize()` (#1602)
    
    Liberal use of `Compressor.transform()` and `AST_Node.optimize()` presents an issue for look-up operations like `TreeWalker.in_boolean_context()` and `TreeWalker.parent()`.
    
    This is an incremental fix such that `AST_Node.optimize()` would now contain the correct stack information when called correctly.
---
 lib/compress.js            |  69 +++++++++++-------------
 lib/utils.js               |   4 +-
 test/compress/transform.js | 129 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 164 insertions(+), 38 deletions(-)

diff --git a/lib/compress.js b/lib/compress.js
index ab4c3c2..59a9668 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -152,13 +152,14 @@ merge(Compressor.prototype, {
             was_scope = true;
         }
         descend(node, this);
-        node = node.optimize(this);
-        if (was_scope && node instanceof AST_Scope) {
-            node.drop_unused(this);
-            descend(node, this);
+        descend(node, this);
+        var opt = node.optimize(this);
+        if (was_scope && opt instanceof AST_Scope) {
+            opt.drop_unused(this);
+            descend(opt, this);
         }
-        node._squeezed = true;
-        return node;
+        if (opt === node) opt._squeezed = true;
+        return opt;
     }
 });
 
@@ -171,8 +172,7 @@ merge(Compressor.prototype, {
             if (compressor.has_directive("use asm")) return self;
             var opt = optimizer(self, compressor);
             opt._optimized = true;
-            if (opt === self) return opt;
-            return opt.transform(compressor);
+            return opt;
         });
     };
 
@@ -914,7 +914,7 @@ merge(Compressor.prototype, {
                     if (stat instanceof AST_LoopControl) {
                         var lct = compressor.loopcontrol_target(stat.label);
                         if ((stat instanceof AST_Break
-                             && lct instanceof AST_BlockStatement
+                             && !(lct instanceof AST_IterationStatement)
                              && loop_body(lct) === self) || (stat instanceof AST_Continue
                                                              && loop_body(lct) === self)) {
                             if (stat.label) {
@@ -1646,8 +1646,8 @@ merge(Compressor.prototype, {
         return thing && thing.aborts();
     };
     (function(def){
-        def(AST_Statement, function(){ return null });
-        def(AST_Jump, function(){ return this });
+        def(AST_Statement, return_null);
+        def(AST_Jump, return_this);
         function block_aborts(){
             var n = this.body.length;
             return n > 0 && aborts(this.body[n - 1]);
@@ -2077,14 +2077,6 @@ merge(Compressor.prototype, {
     // drop_side_effect_free()
     // remove side-effect-free parts which only affects return value
     (function(def){
-        function return_this() {
-            return this;
-        }
-
-        function return_null() {
-            return null;
-        }
-
         // Drop side-effect-free elements from an array of expressions.
         // Returns an array of expressions with side-effects or null
         // if all elements were dropped. Note: original array may be
@@ -2358,7 +2350,7 @@ merge(Compressor.prototype, {
                         extract_declarations_from_unreachable_code(compressor, self.alternative, a);
                     }
                     a.push(self.body);
-                    return make_node(AST_BlockStatement, self, { body: a }).transform(compressor);
+                    return make_node(AST_BlockStatement, self, { body: a }).optimize(compressor);
                 }
             } else {
                 compressor.warn("Condition always false [{file}:{line},{col}]", self.condition.start);
@@ -2366,7 +2358,7 @@ merge(Compressor.prototype, {
                     var a = [];
                     extract_declarations_from_unreachable_code(compressor, self.body, a);
                     if (self.alternative) a.push(self.alternative);
-                    return make_node(AST_BlockStatement, self, { body: a }).transform(compressor);
+                    return make_node(AST_BlockStatement, self, { body: a }).optimize(compressor);
                 }
             }
         }
@@ -2385,8 +2377,8 @@ merge(Compressor.prototype, {
         }
         if (is_empty(self.body) && is_empty(self.alternative)) {
             return make_node(AST_SimpleStatement, self.condition, {
-                body: self.condition
-            }).transform(compressor);
+                body: self.condition.clone()
+            }).optimize(compressor);
         }
         if (self.body instanceof AST_SimpleStatement
             && self.alternative instanceof AST_SimpleStatement) {
@@ -2396,7 +2388,7 @@ merge(Compressor.prototype, {
                     consequent  : statement_to_expression(self.body),
                     alternative : statement_to_expression(self.alternative)
                 })
-            }).transform(compressor);
+            }).optimize(compressor);
         }
         if (is_empty(self.alternative) && self.body instanceof AST_SimpleStatement) {
             if (self_condition_length === negated_length && !negated_is_best
@@ -2412,14 +2404,14 @@ merge(Compressor.prototype, {
                     left     : negated,
                     right    : statement_to_expression(self.body)
                 })
-            }).transform(compressor);
+            }).optimize(compressor);
             return make_node(AST_SimpleStatement, self, {
                 body: make_node(AST_Binary, self, {
                     operator : "&&",
                     left     : self.condition,
                     right    : statement_to_expression(self.body)
                 })
-            }).transform(compressor);
+            }).optimize(compressor);
         }
         if (self.body instanceof AST_EmptyStatement
             && self.alternative
@@ -2430,7 +2422,7 @@ merge(Compressor.prototype, {
                     left     : self.condition,
                     right    : statement_to_expression(self.alternative)
                 })
-            }).transform(compressor);
+            }).optimize(compressor);
         }
         if (self.body instanceof AST_Exit
             && self.alternative instanceof AST_Exit
@@ -2440,18 +2432,21 @@ merge(Compressor.prototype, {
                     condition   : self.condition,
                     consequent  : self.body.value || make_node(AST_Undefined, self.body),
                     alternative : self.alternative.value || make_node(AST_Undefined, self.alternative)
-                })
-            }).transform(compressor);
+                }).transform(compressor)
+            }).optimize(compressor);
         }
         if (self.body instanceof AST_If
             && !self.body.alternative
             && !self.alternative) {
-            self.condition = make_node(AST_Binary, self.condition, {
-                operator: "&&",
-                left: self.condition,
-                right: self.body.condition
-            }).transform(compressor);
-            self.body = self.body.body;
+            self = make_node(AST_If, self, {
+                condition: make_node(AST_Binary, self.condition, {
+                    operator: "&&",
+                    left: self.condition,
+                    right: self.body.condition
+                }),
+                body: self.body.body,
+                alternative: null
+            });
         }
         if (aborts(self.body)) {
             if (self.alternative) {
@@ -2459,7 +2454,7 @@ merge(Compressor.prototype, {
                 self.alternative = null;
                 return make_node(AST_BlockStatement, self, {
                     body: [ self, alt ]
-                }).transform(compressor);
+                }).optimize(compressor);
             }
         }
         if (aborts(self.alternative)) {
@@ -2469,7 +2464,7 @@ merge(Compressor.prototype, {
             self.alternative = null;
             return make_node(AST_BlockStatement, self, {
                 body: [ self, body ]
-            }).transform(compressor);
+            }).optimize(compressor);
         }
         return self;
     });
diff --git a/lib/utils.js b/lib/utils.js
index da66354..fdb2047 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -126,9 +126,11 @@ function merge(obj, ext) {
     return count;
 };
 
-function noop() {};
+function noop() {}
 function return_false() { return false; }
 function return_true() { return true; }
+function return_this() { return this; }
+function return_null() { return null; }
 
 var MAP = (function(){
     function MAP(a, f, backwards) {
diff --git a/test/compress/transform.js b/test/compress/transform.js
new file mode 100644
index 0000000..7b616e4
--- /dev/null
+++ b/test/compress/transform.js
@@ -0,0 +1,129 @@
+booleans_evaluate: {
+    options = {
+        booleans: true,
+        evaluate: true,
+    }
+    input: {
+        console.log(typeof void 0 != "undefined");
+        console.log(1 == 1, 1 === 1)
+        console.log(1 != 1, 1 !== 1)
+    }
+    expect: {
+        console.log(!1);
+        console.log(!0, !0);
+        console.log(!1, !1);
+    }
+}
+
+booleans_global_defs: {
+    options = {
+        booleans: true,
+        evaluate: true,
+        global_defs: {
+            A: true,
+        },
+    }
+    input: {
+        console.log(A == 1);
+    }
+    expect: {
+        console.log(!0);
+    }
+}
+
+condition_evaluate: {
+    options = {
+        booleans: true,
+        dead_code: false,
+        evaluate: true,
+        loops: false,
+    }
+    input: {
+        while (1 === 2);
+        for (; 1 == true;);
+        if (void 0 == null);
+    }
+    expect: {
+        while (!1);
+        for (; !0;);
+        if (!0);
+    }
+}
+
+if_else_empty: {
+    options = {
+        conditionals: true,
+    }
+    input: {
+        if ({} ? a : b); else {}
+    }
+    expect: {
+        !{} ? b : a;
+    }
+}
+
+label_if_break: {
+    options = {
+        conditionals: true,
+        dead_code: true,
+        evaluate: true,
+    }
+    input: {
+        L: if (true) {
+            a;
+            break L;
+        }
+    }
+    expect: {
+        a;
+    }
+}
+
+while_if_break: {
+    options = {
+        conditionals: true,
+        loops: true,
+        sequences: true,
+    }
+    input: {
+        while (a) {
+            if (b) if(c) d;
+            if (e) break;
+        }
+    }
+    expect: {
+        for(; a && (b && c && d, !e););
+    }
+}
+
+if_return: {
+    options = {
+        booleans: true,
+        conditionals: true,
+        if_return: true,
+        sequences: true,
+    }
+    input: {
+        function f(w, x, y, z) {
+            if (x) return;
+            if (w) {
+                if (y) return;
+            } else if (z) return;
+            if (x == y) return true;
+
+            if (x) w();
+            if (y) z();
+            return true;
+        }
+    }
+    expect: {
+        function f(w, x, y, z) {
+            if (!x) {
+                if (w) {
+                    if (y) return;
+                } else if (z) return;
+                return x == y || (x && w(), y && z(), !0);
+            }
+        }
+    }
+}

-- 
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