[Pkg-javascript-commits] [uglifyjs] 17/491: improve `unused` (#1832)

Jonas Smedegaard dr at jones.dk
Wed Feb 14 19:51:18 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 f05d4f7af3659a481b06449584fa63e3772322e2
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date:   Thu Apr 20 13:06:14 2017 +0800

    improve `unused` (#1832)
    
    - extract leading value with side-effects out of `var` statement
    - reduce scanning of `AST_Definitions` from 3 passes to just once
---
 lib/compress.js                | 166 ++++++++++++++++++-----------------------
 test/compress/collapse_vars.js |   6 +-
 test/compress/drop-unused.js   |   3 +-
 test/compress/reduce_vars.js   |  12 +--
 4 files changed, 82 insertions(+), 105 deletions(-)

diff --git a/lib/compress.js b/lib/compress.js
index 7fa2b52..772c622 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -1955,12 +1955,7 @@ merge(Compressor.prototype, {
                                 sym.__unused = true;
                                 if (trim) {
                                     a.pop();
-                                    compressor[sym.unreferenced() ? "warn" : "info"]("Dropping unused function argument {name} [{file}:{line},{col}]", {
-                                        name : sym.name,
-                                        file : sym.start.file,
-                                        line : sym.start.line,
-                                        col  : sym.start.col
-                                    });
+                                    compressor[sym.unreferenced() ? "warn" : "info"]("Dropping unused function argument {name} [{file}:{line},{col}]", template(sym));
                                 }
                             }
                             else {
@@ -1970,115 +1965,93 @@ merge(Compressor.prototype, {
                     }
                     if (drop_funcs && node instanceof AST_Defun && node !== self) {
                         if (!(node.name.definition().id in in_use_ids)) {
-                            compressor[node.name.unreferenced() ? "warn" : "info"]("Dropping unused function {name} [{file}:{line},{col}]", {
-                                name : node.name.name,
-                                file : node.name.start.file,
-                                line : node.name.start.line,
-                                col  : node.name.start.col
-                            });
+                            compressor[node.name.unreferenced() ? "warn" : "info"]("Dropping unused function {name} [{file}:{line},{col}]", template(node.name));
                             return make_node(AST_EmptyStatement, node);
                         }
                         return node;
                     }
                     if (drop_vars && node instanceof AST_Definitions && !(tt.parent() instanceof AST_ForIn)) {
-                        var def = node.definitions.filter(function(def){
-                            var w = {
-                                name : def.name.name,
-                                file : def.name.start.file,
-                                line : def.name.start.line,
-                                col  : def.name.start.col
-                            };
+                        // place uninitialized names at the start
+                        var body = [], head = [], tail = [];
+                        // for unused names whose initialization has
+                        // side effects, we can cascade the init. code
+                        // into the next one, or next statement.
+                        var side_effects = [];
+                        node.definitions.forEach(function(def) {
                             if (def.value) def.value = def.value.transform(tt);
                             var sym = def.name.definition();
                             if (sym.id in in_use_ids) {
                                 if (def.name instanceof AST_SymbolVar) {
                                     var var_defs = var_defs_by_id.get(sym.id);
                                     if (var_defs.length > 1 && !def.value) {
-                                        compressor.warn("Dropping duplicated definition of variable {name} [{file}:{line},{col}]", w);
+                                        compressor.warn("Dropping duplicated definition of variable {name} [{file}:{line},{col}]", template(def.name));
                                         var_defs.splice(var_defs.indexOf(def), 1);
-                                        return false;
+                                        return;
                                     }
                                 }
-                                return true;
-                            }
-                            if (sym.orig[0] instanceof AST_SymbolCatch) {
-                                def.value = def.value && def.value.drop_side_effect_free(compressor);
-                                return true;
-                            }
-                            if (def.value && (def._unused_side_effects = def.value.drop_side_effect_free(compressor))) {
-                                compressor.warn("Side effects in initialization of unused variable {name} [{file}:{line},{col}]", w);
-                                return true;
+                                if (def.value) {
+                                    if (side_effects.length > 0) {
+                                        if (tail.length > 0) {
+                                            merge_sequence(side_effects, def.value);
+                                            def.value = make_sequence(def.value, side_effects);
+                                        } else {
+                                            body.push(make_node(AST_SimpleStatement, node, {
+                                                body: make_sequence(node, side_effects)
+                                            }));
+                                        }
+                                        side_effects = [];
+                                    }
+                                    tail.push(def);
+                                } else {
+                                    head.push(def);
+                                }
+                            } else if (sym.orig[0] instanceof AST_SymbolCatch) {
+                                var value = def.value && def.value.drop_side_effect_free(compressor);
+                                if (value) merge_sequence(side_effects, value);
+                                def.value = null;
+                                head.push(def);
+                            } else {
+                                var value = def.value && def.value.drop_side_effect_free(compressor);
+                                if (value) {
+                                    compressor.warn("Side effects in initialization of unused variable {name} [{file}:{line},{col}]", template(def.name));
+                                    merge_sequence(side_effects, value);
+                                } else {
+                                    compressor[def.name.unreferenced() ? "warn" : "info"]("Dropping unused variable {name} [{file}:{line},{col}]", template(def.name));
+                                }
                             }
-                            compressor[def.name.unreferenced() ? "warn" : "info"]("Dropping unused variable {name} [{file}:{line},{col}]", w);
-                            return false;
                         });
-                        if (def.length == 1
-                            && def[0].value
-                            && !def[0]._unused_side_effects
-                            && def[0].name instanceof AST_SymbolVar) {
-                            var var_defs = var_defs_by_id.get(def[0].name.definition().id);
+                        if (head.length == 0 && tail.length == 1 && tail[0].name instanceof AST_SymbolVar) {
+                            var var_defs = var_defs_by_id.get(tail[0].name.definition().id);
                             if (var_defs.length > 1) {
-                                compressor.warn("Converting duplicated definition of variable {name} to assignment [{file}:{line},{col}]", {
-                                    name : def[0].name.name,
-                                    file : def[0].name.start.file,
-                                    line : def[0].name.start.line,
-                                    col  : def[0].name.start.col
-                                });
-                                var_defs.splice(var_defs.indexOf(def[0]), 1);
-                                return make_node(AST_SimpleStatement, node, {
-                                    body: make_node(AST_Assign, def[0], {
-                                        operator: "=",
-                                        left: make_node(AST_SymbolRef, def[0].name, def[0].name),
-                                        right: def[0].value
-                                    })
-                                });
+                                var def = tail.pop();
+                                compressor.warn("Converting duplicated definition of variable {name} to assignment [{file}:{line},{col}]", template(def.name));
+                                var_defs.splice(var_defs.indexOf(def), 1);
+                                side_effects.unshift(make_node(AST_Assign, def, {
+                                    operator: "=",
+                                    left: make_node(AST_SymbolRef, def.name, def.name),
+                                    right: def.value
+                                }));
                             }
                         }
-                        // place uninitialized names at the start
-                        def = mergeSort(def, function(a, b){
-                            if (!a.value && b.value) return -1;
-                            if (!b.value && a.value) return 1;
-                            return 0;
-                        });
-                        // for unused names whose initialization has
-                        // side effects, we can cascade the init. code
-                        // into the next one, or next statement.
-                        var side_effects = [];
-                        for (var i = 0; i < def.length;) {
-                            var x = def[i];
-                            if (x._unused_side_effects) {
-                                merge_sequence(side_effects, x._unused_side_effects);
-                                def.splice(i, 1);
-                            } else {
-                                if (side_effects.length > 0) {
-                                    merge_sequence(side_effects, x.value);
-                                    x.value = make_sequence(x.value, side_effects);
-                                    side_effects = [];
-                                }
-                                ++i;
-                            }
+                        if (head.length > 0 || tail.length > 0) {
+                            node.definitions = head.concat(tail);
+                            body.push(node);
                         }
                         if (side_effects.length > 0) {
-                            side_effects = make_node(AST_BlockStatement, node, {
-                                body: [ make_node(AST_SimpleStatement, node, {
-                                    body: make_sequence(node, side_effects)
-                                }) ]
-                            });
-                        } else {
-                            side_effects = null;
-                        }
-                        if (def.length == 0 && !side_effects) {
-                            return make_node(AST_EmptyStatement, node);
-                        }
-                        if (def.length == 0) {
-                            return in_list ? MAP.splice(side_effects.body) : side_effects;
+                            body.push(make_node(AST_SimpleStatement, node, {
+                                body: make_sequence(node, side_effects)
+                            }));
                         }
-                        node.definitions = def;
-                        if (side_effects) {
-                            side_effects.body.unshift(node);
-                            return in_list ? MAP.splice(side_effects.body) : side_effects;
+                        switch (body.length) {
+                          case 0:
+                            return in_list ? MAP.skip : make_node(AST_EmptyStatement, node);
+                          case 1:
+                            return body[0];
+                          default:
+                            return in_list ? MAP.splice(body) : make_node(AST_BlockStatement, node, {
+                                body: body
+                            });
                         }
-                        return node;
                     }
                     if (drop_vars && assign_as_unused
                         && node instanceof AST_Assign
@@ -2119,6 +2092,15 @@ merge(Compressor.prototype, {
                     }
                     if (node instanceof AST_Scope && node !== self)
                         return node;
+
+                    function template(sym) {
+                        return {
+                            name : sym.name,
+                            file : sym.start.file,
+                            line : sym.start.line,
+                            col  : sym.start.col
+                        };
+                    }
                 }
             );
             self.transform(tt);
diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js
index 94515a6..a4c1f9e 100644
--- a/test/compress/collapse_vars.js
+++ b/test/compress/collapse_vars.js
@@ -701,10 +701,10 @@ collapse_vars_lvalues_drop_assign: {
         function f2(x) { var z = x, a = ++z; return z += a; }
         function f3(x) { var a = (x -= 3); return x + a; }
         function f4(x) { var a = (x -= 3); return x + a; }
-        function f5(x) { var v = (e1(), e2()), c = v = --x; return x - c; }
+        function f5(x) { e1(); var v = e2(), c = v = --x; return x - c; }
         function f6(x) { e1(), e2(); return --x - x; }
-        function f7(x) { var c = (e1(), e2() - x); return x - c; }
-        function f8(x) { var v = (e1(), e2()); return x - (v - x); }
+        function f7(x) { e1(); var c = e2() - x; return x - c; }
+        function f8(x) { e1(); var v = e2(); return x - (v - x); }
         function f9(x) { e1(); return e2() - x - x; }
     }
 }
diff --git a/test/compress/drop-unused.js b/test/compress/drop-unused.js
index 8f0aa0b..7456f67 100644
--- a/test/compress/drop-unused.js
+++ b/test/compress/drop-unused.js
@@ -935,7 +935,8 @@ issue_1715_3: {
             try {
                 console;
             } catch (a) {
-                var a = x();
+                var a;
+                x();
             }
         }
         f();
diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js
index c5f2690..57e2389 100644
--- a/test/compress/reduce_vars.js
+++ b/test/compress/reduce_vars.js
@@ -53,9 +53,7 @@ reduce_vars: {
             console.log(-3);
             eval("console.log(a);");
         })(eval);
-        (function() {
-            return "yes";
-        })();
+        "yes";
         console.log(2);
     }
     expect_stdout: true
@@ -1699,9 +1697,7 @@ redefine_arguments_2: {
         console.log(function() {
             var arguments;
             return typeof arguments;
-        }(), function() {
-            return"number";
-        }(), function(x) {
+        }(), "number", function(x) {
             var arguments = x;
             return typeof arguments;
         }());
@@ -1810,9 +1806,7 @@ redefine_farg_2: {
         console.log(function(a) {
             var a;
             return typeof a;
-        }([]), function() {
-            return "number";
-        }(),function(a, b) {
+        }([]), "number",function(a, b) {
             var a = b;
             return typeof a;
         }([]));

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