[Pkg-javascript-commits] [uglifyjs] 336/491: handle `inline` of function arguments (#2590)

Jonas Smedegaard dr at jones.dk
Wed Feb 14 19:51:50 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 8f681b1d1721e931852be48720d26ba052eac96c
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date:   Fri Dec 15 13:28:30 2017 +0800

    handle `inline` of function arguments (#2590)
    
    fixes #2476
---
 lib/compress.js                | 92 ++++++++++++++++++++++++++++++++----------
 test/compress/collapse_vars.js | 48 ++++++++++------------
 test/compress/functions.js     | 39 ++++++++++++++----
 test/compress/hoist_props.js   |  8 ++--
 test/compress/reduce_vars.js   | 13 +++---
 test/mocha/glob.js             |  2 +-
 6 files changed, 137 insertions(+), 65 deletions(-)

diff --git a/lib/compress.js b/lib/compress.js
index 9b0a535..aaadcd1 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -2997,10 +2997,10 @@ merge(Compressor.prototype, {
         return self;
     });
 
-    AST_Scope.DEFMETHOD("make_var_name", function(prefix) {
-        var var_names = this.var_names;
+    AST_Scope.DEFMETHOD("var_names", function() {
+        var var_names = this._var_names;
         if (!var_names) {
-            this.var_names = var_names = Object.create(null);
+            this._var_names = var_names = Object.create(null);
             this.enclosed.forEach(function(def) {
                 var_names[def.name] = true;
             });
@@ -3008,6 +3008,11 @@ merge(Compressor.prototype, {
                 var_names[name] = true;
             });
         }
+        return var_names;
+    });
+
+    AST_Scope.DEFMETHOD("make_var_name", function(prefix) {
+        var var_names = this.var_names();
         prefix = prefix.replace(/[^a-z_$]+/ig, "_");
         var name = prefix;
         for (var i = 0; var_names[name]; i++) name = prefix + "$" + i;
@@ -3862,7 +3867,7 @@ merge(Compressor.prototype, {
             }
         }
         if (fn instanceof AST_Function) {
-            var def;
+            var def, scope, value;
             if (compressor.option("inline")
                 && !fn.uses_arguments
                 && !fn.uses_eval
@@ -3871,24 +3876,13 @@ merge(Compressor.prototype, {
                     : compressor.option("unused")
                         && (def = exp.definition()).references.length == 1
                         && !recursive_ref(compressor, def))
+                && !self.has_pure_annotation(compressor)
                 && !fn.contains_this()
-                && all(fn.argnames, function(arg) {
-                    return arg.__unused;
-                })
-                && !self.has_pure_annotation(compressor)) {
-                var value;
-                if (stat instanceof AST_Return) {
-                    value = stat.value;
-                } else if (stat instanceof AST_SimpleStatement) {
-                    value = make_node(AST_UnaryPrefix, stat, {
-                        operator: "void",
-                        expression: stat.body
-                    });
-                }
-                if (value) {
-                    var args = self.args.concat(value);
-                    return make_sequence(self, args).optimize(compressor);
-                }
+                && (scope = can_flatten_args(fn))
+                && (value = flatten_body(stat))) {
+                var expressions = flatten_args(fn, scope);
+                expressions.push(value);
+                return make_sequence(self, expressions).optimize(compressor);
             }
             if (compressor.option("side_effects") && all(fn.body, is_empty)) {
                 var args = self.args.concat(make_node(AST_Undefined, self));
@@ -3917,6 +3911,62 @@ merge(Compressor.prototype, {
             return best_of(compressor, ev, self);
         }
         return self;
+
+        function can_flatten_args(fn) {
+            var scope = compressor.find_parent(AST_Scope);
+            var safe_to_inject = compressor.toplevel.vars || !(scope instanceof AST_Toplevel);
+            return all(fn.argnames, function(arg) {
+                return arg.__unused || safe_to_inject && !scope.var_names()[arg.name];
+            }) && scope;
+        }
+
+        function flatten_args(fn, scope) {
+            var decls = [];
+            var expressions = [];
+            for (var len = fn.argnames.length, i = len; --i >= 0;) {
+                var name = fn.argnames[i];
+                var value = self.args[i];
+                if (name.__unused) {
+                    if (value || expressions.length) {
+                        expressions.unshift(value || make_node(AST_Undefined, self));
+                    }
+                } else {
+                    decls.unshift(make_node(AST_VarDef, name, {
+                        name: name,
+                        value: null
+                    }));
+                    var sym = make_node(AST_SymbolRef, name, name);
+                    name.definition().references.push(sym);
+                    expressions.unshift(make_node(AST_Assign, self, {
+                        operator: "=",
+                        left: sym,
+                        right: value || make_node(AST_Undefined, self)
+                    }));
+                }
+            }
+            for (i = len, len = self.args.length; i < len; i++) {
+                expressions.push(self.args[i]);
+            }
+            if (decls.length) {
+                for (i = 0; compressor.parent(i) !== scope;) i++;
+                i = scope.body.indexOf(compressor.parent(i - 1)) + 1;
+                scope.body.splice(i, 0, make_node(AST_Var, fn, {
+                    definitions: decls
+                }));
+            }
+            return expressions;
+        }
+
+        function flatten_body(stat) {
+            if (stat instanceof AST_Return) {
+                return stat.value;
+            } else if (stat instanceof AST_SimpleStatement) {
+                return make_node(AST_UnaryPrefix, stat, {
+                    operator: "void",
+                    expression: stat.body
+                });
+            }
+        }
     });
 
     OPT(AST_New, function(self, compressor){
diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js
index 39d6b64..1a48798 100644
--- a/test/compress/collapse_vars.js
+++ b/test/compress/collapse_vars.js
@@ -3317,15 +3317,14 @@ issue_2436_4: {
         }(o));
     }
     expect: {
-        console.log(function(c) {
-            return {
-                x: c.a,
-                y: c.b,
-            };
-        }({
+        console.log({
+            x: (c = {
             a: 1,
             b: 2,
-        }));
+        }).a,
+            y: c.b,
+        });
+        var c;
     }
     expect_stdout: true
 }
@@ -3448,12 +3447,11 @@ issue_2436_8: {
         }(o));
     }
     expect: {
-        console.log(function(c) {
-            return {
-                x: c.a,
-                y: c.b,
-            };
-        }(o));
+        console.log({
+            x: (c = o).a,
+            y: c.b,
+        });
+        var c;
     }
     expect_stdout: true
 }
@@ -3478,12 +3476,11 @@ issue_2436_9: {
     }
     expect: {
         var o = console;
-        console.log(function(c) {
-            return {
-                x: c.a,
-                y: c.b,
-            };
-        }(o));
+        console.log({
+            x: (c = o).a,
+            y: c.b,
+        });
+        var c;
     }
     expect_stdout: true
 }
@@ -3523,13 +3520,12 @@ issue_2436_10: {
             o = { b: 3 };
             return n;
         }
-        console.log(function(c) {
-            return [
-                c.a,
-                f(c.b),
-                c.b,
-            ];
-        }(o).join(" "));
+        console.log((c = o, [
+            c.a,
+            f(c.b),
+            c.b,
+        ]).join(" "));
+        var c;
     }
     expect_stdout: "1 2 2"
 }
diff --git a/test/compress/functions.js b/test/compress/functions.js
index c4281d5..a36509a 100644
--- a/test/compress/functions.js
+++ b/test/compress/functions.js
@@ -578,11 +578,10 @@ issue_2531_1: {
     }
     expect: {
         function outer() {
-            return function(value) {
-                return function() {
-                    return value;
-                };
-            }("Hello");
+            return value = "Hello", function() {
+                return value;
+            };
+            var value;
         }
         console.log("Greeting:", outer()());
     }
@@ -593,9 +592,10 @@ issue_2531_2: {
     options = {
         evaluate: true,
         inline: true,
-        passes: 2,
+        passes: 3,
         reduce_funcs: true,
         reduce_vars: true,
+        side_effects: true,
         unused: true,
     }
     input: {
@@ -627,9 +627,10 @@ issue_2531_3: {
     options = {
         evaluate: true,
         inline: true,
-        passes: 2,
+        passes: 3,
         reduce_funcs: true,
         reduce_vars: true,
+        side_effects: true,
         toplevel: true,
         unused: true,
     }
@@ -747,3 +748,27 @@ inline_loop_4: {
         };
     }
 }
+
+issue_2476: {
+    options = {
+        inline: true,
+        reduce_vars: true,
+        toplevel: true,
+        unused: true,
+    }
+    input: {
+        function foo(x, y, z) {
+            return x < y ? x * y + z : x * z - y;
+        }
+        for (var sum = 0, i = 0; i < 10; i++)
+            sum += foo(i, i + 1, 3 * i);
+        console.log(sum);
+    }
+    expect: {
+        for (var sum = 0, i = 0; i < 10; i++)
+            sum += (x = i, y = i + 1, z = 3 * i, x < y ? x * y + z : x * z - y);
+        var x, y, z;
+        console.log(sum);
+    }
+    expect_stdout: "465"
+}
diff --git a/test/compress/hoist_props.js b/test/compress/hoist_props.js
index a46033d..012a3fc 100644
--- a/test/compress/hoist_props.js
+++ b/test/compress/hoist_props.js
@@ -55,9 +55,8 @@ issue_2377_2: {
         console.log(obj.foo, obj.cube(3));
     }
     expect: {
-        console.log(1, function(x) {
-            return x * x * x;
-        }(3));
+        console.log(1, (x = 3, x * x * x));
+        var x;
     }
     expect_stdout: "1 27"
 }
@@ -67,9 +66,10 @@ issue_2377_3: {
         evaluate: true,
         inline: true,
         hoist_props: true,
-        passes: 3,
+        passes: 4,
         reduce_funcs: true,
         reduce_vars: true,
+        side_effects: true,
         toplevel: true,
         unused: true,
     }
diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js
index ff93079..9ed9c97 100644
--- a/test/compress/reduce_vars.js
+++ b/test/compress/reduce_vars.js
@@ -1396,7 +1396,7 @@ defun_inline_3: {
     options = {
         evaluate: true,
         inline: true,
-        passes: 2,
+        passes: 3,
         reduce_funcs: true,
         reduce_vars: true,
         side_effects: true,
@@ -2250,12 +2250,11 @@ redefine_farg_2: {
         console.log(f([]), g([]), h([]));
     }
     expect: {
-        console.log(function(a) {
-            return typeof a;
-        }([]), "number",function(a, b) {
+        console.log((a = [], typeof a), "number",function(a, b) {
             a = b;
             return typeof a;
         }([]));
+        var a;
     }
     expect_stdout: "object number undefined"
 }
@@ -2266,7 +2265,7 @@ redefine_farg_3: {
         evaluate: true,
         inline: true,
         keep_fargs: false,
-        passes: 2,
+        passes: 3,
         reduce_funcs: true,
         reduce_vars: true,
         sequences: true,
@@ -3107,6 +3106,7 @@ obj_var_2: {
 
 obj_arg_1: {
     options = {
+        collapse_vars: true,
         evaluate: true,
         inline: true,
         passes: 2,
@@ -3138,9 +3138,10 @@ obj_arg_1: {
 
 obj_arg_2: {
     options = {
+        collapse_vars: true,
         evaluate: true,
         inline: true,
-        passes: 2,
+        passes: 3,
         properties: true,
         reduce_funcs: true,
         reduce_vars: true,
diff --git a/test/mocha/glob.js b/test/mocha/glob.js
index eb5d477..b6f1e04 100644
--- a/test/mocha/glob.js
+++ b/test/mocha/glob.js
@@ -26,7 +26,7 @@ describe("bin/uglifyjs with input file globs", function() {
         });
     });
     it("bin/uglifyjs with multiple input file globs.", function(done) {
-        var command = uglifyjscmd + ' "test/input/issue-1242/???.es5" "test/input/issue-1242/*.js" -mc toplevel,passes=2';
+        var command = uglifyjscmd + ' "test/input/issue-1242/???.es5" "test/input/issue-1242/*.js" -mc toplevel,passes=3';
 
         exec(command, function(err, stdout) {
             if (err) throw err;

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