improve `unused` efficiency (#3813)
authorAlex Lam S.L <alexlamsl@gmail.com>
Thu, 23 Apr 2020 00:31:35 +0000 (01:31 +0100)
committerGitHub <noreply@github.com>
Thu, 23 Apr 2020 00:31:35 +0000 (08:31 +0800)
lib/compress.js
test/compress/directives.js
test/compress/issue-1034.js

index 2878385..7c2077b 100644 (file)
@@ -3984,16 +3984,6 @@ merge(Compressor.prototype, {
         return self;
     });
 
-    OPT(AST_Lambda, function(self, compressor) {
-        self.body = tighten_body(self.body, compressor);
-        if (compressor.option("side_effects")
-            && self.body.length == 1
-            && self.body[0] === compressor.has_directive("use strict")) {
-            self.body.length = 0;
-        }
-        return self;
-    });
-
     AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
         if (!compressor.option("unused")) return;
         if (compressor.has_directive("use asm")) return;
@@ -4153,31 +4143,33 @@ merge(Compressor.prototype, {
             }
             if (node instanceof AST_Call) calls_to_drop_args.push(node);
             if (scope !== self) return;
-            if (node instanceof AST_Function && node.name && drop_fn_name(node.name.definition())) {
-                unused_fn_names.push(node);
-            }
-            if (node instanceof AST_Lambda && !(node instanceof AST_Accessor)) {
-                var trim = compressor.drop_fargs(node, parent);
-                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) {
-                            log(sym, "Dropping unused function argument {name} [{file}:{line},{col}]", template(sym));
-                            a.pop();
-                        }
-                    } else {
-                        trim = false;
+            if (node instanceof AST_Lambda) {
+                if (drop_funcs && node !== self && node instanceof AST_Defun) {
+                    var def = node.name.definition();
+                    if (!(def.id in in_use_ids)) {
+                        log(node.name, "Dropping unused function {name} [{file}:{line},{col}]", template(node.name));
+                        def.eliminated++;
+                        return in_list ? List.skip : make_node(AST_EmptyStatement, node);
                     }
                 }
-                fns_with_marked_args.push(node);
-            }
-            if (drop_funcs && node instanceof AST_Defun && node !== self) {
-                var def = node.name.definition();
-                if (!(def.id in in_use_ids)) {
-                    log(node.name, "Dropping unused function {name} [{file}:{line},{col}]", template(node.name));
-                    def.eliminated++;
-                    return make_node(AST_EmptyStatement, node);
+                if (node instanceof AST_Function && node.name && drop_fn_name(node.name.definition())) {
+                    unused_fn_names.push(node);
+                }
+                if (!(node instanceof AST_Accessor)) {
+                    var trim = compressor.drop_fargs(node, parent);
+                    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) {
+                                log(sym, "Dropping unused function argument {name} [{file}:{line},{col}]", template(sym));
+                                a.pop();
+                            }
+                        } else {
+                            trim = false;
+                        }
+                    }
+                    fns_with_marked_args.push(node);
                 }
             }
             if (node instanceof AST_Definitions && !(parent instanceof AST_ForIn && parent.init === node)) {
@@ -4312,7 +4304,7 @@ merge(Compressor.prototype, {
                 // Certain combination of unused name + side effect leads to invalid AST:
                 //    https://github.com/mishoo/UglifyJS2/issues/1830
                 // We fix it at this stage by moving the label inwards, back to the `for`.
-                descend(node, this);
+                descend(node, tt);
                 if (node.body instanceof AST_BlockStatement) {
                     var block = node.body;
                     node.body = block.body.pop();
@@ -4324,7 +4316,7 @@ merge(Compressor.prototype, {
             if (node instanceof AST_Scope) {
                 var save_scope = scope;
                 scope = node;
-                descend(node, this);
+                descend(node, tt);
                 scope = save_scope;
                 return node;
             }
@@ -4376,6 +4368,12 @@ merge(Compressor.prototype, {
         });
         tt.push(compressor.parent());
         self.transform(tt);
+        if (self instanceof AST_Lambda
+            && self.body.length == 1
+            && self.body[0] instanceof AST_Directive
+            && self.body[0].value == "use strict") {
+            self.body.length = 0;
+        }
         unused_fn_names.forEach(function(fn) {
             fn.name = null;
         });
index 69ecfdc..6c85fde 100644 (file)
@@ -46,7 +46,7 @@ simple_statement_is_not_a_directive: {
 drop_lone_use_strict: {
     options = {
         directives: true,
-        side_effects: true,
+        unused: true,
     }
     input: {
         function f1() {
@@ -66,10 +66,8 @@ drop_lone_use_strict: {
         function f1() {
         }
         function f2() {
-            "use strict";
-            function f3() {
-            }
         }
+        (function() {})();
     }
 }
 
index 316d6a7..137aed8 100644 (file)
@@ -90,13 +90,13 @@ non_hoisted_function_after_return_2a: {
         "WARN: Declarations in unreachable code! [test/compress/issue-1034.js:7,16]",
         "WARN: Dropping unused variable a [test/compress/issue-1034.js:4,20]",
         "WARN: Dropping unused function nope [test/compress/issue-1034.js:11,21]",
-        "INFO: pass 0: last_count: Infinity, count: 37",
+        "INFO: pass 0: last_count: Infinity, count: 36",
         "WARN: Dropping unreachable code [test/compress/issue-1034.js:9,12]",
         "WARN: Declarations in unreachable code! [test/compress/issue-1034.js:9,12]",
         "WARN: Dropping unreachable code [test/compress/issue-1034.js:12,12]",
         "INFO: Dropping unused variable b [test/compress/issue-1034.js:7,20]",
         "INFO: Dropping unused variable c [test/compress/issue-1034.js:9,16]",
-        "INFO: pass 1: last_count: 37, count: 18",
+        "INFO: pass 1: last_count: 36, count: 18",
     ]
 }
 
@@ -248,13 +248,13 @@ non_hoisted_function_after_return_2a_strict: {
         "WARN: Declarations in unreachable code! [test/compress/issue-1034.js:8,16]",
         "WARN: Dropping unused variable a [test/compress/issue-1034.js:5,20]",
         "WARN: Dropping unused function nope [test/compress/issue-1034.js:12,21]",
-        "INFO: pass 0: last_count: Infinity, count: 48",
+        "INFO: pass 0: last_count: Infinity, count: 47",
         "WARN: Dropping unreachable code [test/compress/issue-1034.js:10,12]",
         "WARN: Declarations in unreachable code! [test/compress/issue-1034.js:10,12]",
         "WARN: Dropping unreachable code [test/compress/issue-1034.js:13,12]",
         "INFO: Dropping unused variable b [test/compress/issue-1034.js:8,20]",
         "INFO: Dropping unused variable c [test/compress/issue-1034.js:10,16]",
-        "INFO: pass 1: last_count: 48, count: 29",
+        "INFO: pass 1: last_count: 47, count: 29",
     ]
 }