[Pkg-javascript-commits] [uglifyjs] 99/228: fix & improve function argument compression (#1584)

Jonas Smedegaard dr at jones.dk
Sat Apr 15 14:25:20 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 b633706ce42576b7e2aa85a96c5691bde87e71ac
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date:   Thu Mar 9 19:11:05 2017 +0800

    fix & improve function argument compression (#1584)
    
    - one-use function call => IIFE should take `eval()` & `arguments` into account
    - if unused parameter cannot be eliminated, replace it with `0`
    
    fixes #1583
---
 lib/compress.js              |  46 ++++++++++++------
 test/compress/drop-unused.js |  30 ++++++++++++
 test/compress/reduce_vars.js | 108 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 171 insertions(+), 13 deletions(-)

diff --git a/lib/compress.js b/lib/compress.js
index f6b76ec..3964636 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -281,6 +281,9 @@ merge(Compressor.prototype, {
                 if (node instanceof AST_Function
                     && (iife = tw.parent()) instanceof AST_Call
                     && iife.expression === node) {
+                    // Virtually turn IIFE parameters into variable definitions:
+                    //   (function(a,b) {...})(c,d) => (function() {var a=c,b=d; ...})()
+                    // So existing transformation rules can work on them.
                     node.argnames.forEach(function(arg, i) {
                         var d = arg.definition();
                         d.fixed = iife.args[i] || make_node(AST_Undefined, iife);
@@ -1810,10 +1813,12 @@ merge(Compressor.prototype, {
                         node.name = null;
                     }
                     if (node instanceof AST_Lambda && !(node instanceof AST_Accessor)) {
-                        if (!compressor.option("keep_fargs")) {
-                            for (var a = node.argnames, i = a.length; --i >= 0;) {
-                                var sym = a[i];
-                                if (!(sym.definition().id in in_use_ids)) {
+                        var trim = !compressor.option("keep_fargs");
+                        for (var a = node.argnames, i = a.length; --i >= 0;) {
+                            var sym = a[i];
+                            if (!(sym.definition().id in in_use_ids)) {
+                                sym.__unused = true;
+                                if (trim) {
                                     a.pop();
                                     compressor.warn("Dropping unused function argument {name} [{file}:{line},{col}]", {
                                         name : sym.name,
@@ -1822,7 +1827,9 @@ merge(Compressor.prototype, {
                                         col  : sym.start.col
                                     });
                                 }
-                                else break;
+                            }
+                            else {
+                                trim = false;
                             }
                         }
                     }
@@ -2609,6 +2616,9 @@ merge(Compressor.prototype, {
                 exp = def.fixed;
                 if (compressor.option("unused")
                     && def.references.length == 1
+                    && !(def.scope.uses_arguments
+                        && def.orig[0] instanceof AST_SymbolFunarg)
+                    && !def.scope.uses_eval
                     && compressor.find_parent(AST_Scope) === def.scope) {
                     self.expression = exp;
                 }
@@ -2617,16 +2627,26 @@ merge(Compressor.prototype, {
         if (compressor.option("unused")
             && exp instanceof AST_Function
             && !exp.uses_arguments
-            && !exp.uses_eval
-            && self.args.length > exp.argnames.length) {
-            var end = exp.argnames.length;
-            for (var i = end, len = self.args.length; i < len; i++) {
-                var node = self.args[i].drop_side_effect_free(compressor);
-                if (node) {
-                    self.args[end++] = node;
+            && !exp.uses_eval) {
+            var pos = 0, last = 0;
+            for (var i = 0, len = self.args.length; i < len; i++) {
+                var trim = i >= exp.argnames.length;
+                if (trim || exp.argnames[i].__unused) {
+                    var node = self.args[i].drop_side_effect_free(compressor);
+                    if (node) {
+                        self.args[pos++] = node;
+                    } else if (!trim) {
+                        self.args[pos++] = make_node(AST_Number, self.args[i], {
+                            value: 0
+                        });
+                        continue;
+                    }
+                } else {
+                    self.args[pos++] = self.args[i];
                 }
+                last = pos;
             }
-            self.args.length = end;
+            self.args.length = last;
         }
         if (compressor.option("unsafe")) {
             if (exp instanceof AST_SymbolRef && exp.undeclared()) {
diff --git a/test/compress/drop-unused.js b/test/compress/drop-unused.js
index 728557a..9f3bf77 100644
--- a/test/compress/drop-unused.js
+++ b/test/compress/drop-unused.js
@@ -761,3 +761,33 @@ assign_chain: {
         }
     }
 }
+
+issue_1583: {
+    options = {
+        keep_fargs: true,
+        reduce_vars: true,
+        unused: true,
+    }
+    input: {
+        function m(t) {
+            (function(e) {
+                t = e();
+            })(function() {
+                return (function(a) {
+                    return a;
+                })(function(a) {});
+            });
+        }
+    }
+    expect: {
+        function m(t) {
+            (function(e) {
+                t = (function() {
+                    return (function(a) {
+                        return a;
+                    })(function(a) {});
+                })();
+            })();
+        }
+    }
+}
diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js
index 10dc9d9..734ce4e 100644
--- a/test/compress/reduce_vars.js
+++ b/test/compress/reduce_vars.js
@@ -1144,3 +1144,111 @@ double_reference: {
         }
     }
 }
+
+iife_arguments_1: {
+    options = {
+        reduce_vars: true,
+        unused: true,
+    }
+    input: {
+        (function(x) {
+            console.log(x() === arguments[0]);
+        })(function f() {
+            return f;
+        });
+    }
+    expect: {
+        (function(x) {
+            console.log(x() === arguments[0]);
+        })(function f() {
+            return f;
+        });
+    }
+}
+
+iife_arguments_2: {
+    options = {
+        reduce_vars: true,
+        unused: true,
+    }
+    input: {
+        (function() {
+            var x = function f() {
+                return f;
+            };
+            console.log(x() === arguments[0]);
+        })();
+    }
+    expect: {
+        (function() {
+            console.log(function f() {
+                return f;
+            }() === arguments[0]);
+        })();
+    }
+}
+
+iife_eval_1: {
+    options = {
+        reduce_vars: true,
+        unused: true,
+    }
+    input: {
+        (function(x) {
+            console.log(x() === eval("x"));
+        })(function f() {
+            return f;
+        });
+    }
+    expect: {
+        (function(x) {
+            console.log(x() === eval("x"));
+        })(function f() {
+            return f;
+        });
+    }
+}
+
+iife_eval_2: {
+    options = {
+        reduce_vars: true,
+        unused: true,
+    }
+    input: {
+        (function() {
+            var x = function f() {
+                return f;
+            };
+            console.log(x() === eval("x"));
+        })();
+    }
+    expect: {
+        (function() {
+            var x = function f() {
+                return f;
+            };
+            console.log(x() === eval("x"));
+        })();
+    }
+}
+
+iife_func_side_effects: {
+    options = {
+        reduce_vars: true,
+        unused: true,
+    }
+    input: {
+        (function(a, b, c) {
+            return b();
+        })(x(), function() {
+            return y();
+        }, z());
+    }
+    expect: {
+        (function(a, b, c) {
+            return function() {
+                return y();
+            }();
+        })(x(), 0, z());
+    }
+}

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