enhance `inline`, `sequences` & `side_effects` (#4493)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sat, 2 Jan 2021 01:43:05 +0000 (01:43 +0000)
committerGitHub <noreply@github.com>
Sat, 2 Jan 2021 01:43:05 +0000 (09:43 +0800)
lib/compress.js
test/compress/async.js

index 5f8f373..0a46fb2 100644 (file)
@@ -8018,7 +8018,7 @@ merge(Compressor.prototype, {
             }
         }
         var fn = exp instanceof AST_SymbolRef ? exp.fixed_value() : exp;
-        var is_func = fn instanceof AST_Arrow || fn instanceof AST_Defun || fn instanceof AST_Function;
+        var is_func = fn instanceof AST_Lambda && (!is_async(fn) || compressor.parent() instanceof AST_Await);
         var stat = is_func && fn.first_statement();
         var has_default = false;
         var can_drop = is_func && all(fn.argnames, function(argname, index) {
@@ -8649,6 +8649,19 @@ merge(Compressor.prototype, {
             ? self : try_evaluate(compressor, self);
     });
 
+    OPT(AST_Await, function(self, compressor) {
+        if (compressor.option("sequences")) {
+            var seq = lift_sequence_in_expression(self, compressor);
+            if (seq !== self) return seq.optimize(compressor);
+        }
+        if (compressor.option("side_effects")) {
+            var exp = self.expression;
+            if (exp instanceof AST_Await) return exp;
+            if (exp instanceof AST_UnaryPrefix && exp.expression instanceof AST_Await) return exp;
+        }
+        return self;
+    });
+
     AST_Binary.DEFMETHOD("lift_sequences", function(compressor) {
         if (this.left instanceof AST_PropAccess) {
             if (!(this.left.expression instanceof AST_Sequence)) return this;
index 5d623bb..51aba26 100644 (file)
@@ -140,6 +140,182 @@ dont_inline: {
     node_version: ">=8"
 }
 
+inline_await_1: {
+    options = {
+        inline: true,
+        reduce_vars: true,
+        unused: true,
+    }
+    input: {
+        (async function() {
+            async function f() {
+                await 42;
+            }
+            return await f();
+        })();
+        console.log("PASS");
+    }
+    expect: {
+        (async function() {
+            return await void await 42;
+        })();
+        console.log("PASS");
+    }
+    expect_stdout: "PASS"
+    node_version: ">=8"
+}
+
+inline_await_1_trim: {
+    options = {
+        if_return: true,
+        inline: true,
+        reduce_vars: true,
+        side_effects: true,
+        unused: true,
+    }
+    input: {
+        (async function() {
+            async function f() {
+                await 42;
+            }
+            return await f();
+        })();
+        console.log("PASS");
+    }
+    expect: {
+        (async function() {
+            await 42;
+        })();
+        console.log("PASS");
+    }
+    expect_stdout: "PASS"
+    node_version: ">=8"
+}
+
+inline_await_2: {
+    options = {
+        inline: true,
+        reduce_vars: true,
+        unused: true,
+    }
+    input: {
+        (async function() {
+            async function f(a) {
+                await a;
+            }
+            return await f(console);
+        })();
+        console.log("PASS");
+    }
+    expect: {
+        (async function() {
+            return await void await console;
+        })();
+        console.log("PASS");
+    }
+    expect_stdout: "PASS"
+    node_version: ">=8"
+}
+
+inline_await_2_trim: {
+    options = {
+        if_return: true,
+        inline: true,
+        reduce_vars: true,
+        side_effects: true,
+        unused: true,
+    }
+    input: {
+        (async function() {
+            async function f(a) {
+                await a;
+            }
+            return await f(console);
+        })();
+        console.log("PASS");
+    }
+    expect: {
+        (async function() {
+            await console;
+        })();
+        console.log("PASS");
+    }
+    expect_stdout: "PASS"
+    node_version: ">=8"
+}
+
+inline_await_3: {
+    options = {
+        inline: true,
+        reduce_vars: true,
+        unused: true,
+    }
+    input: {
+        (async function() {
+            async function f(a, b) {
+                return await b(a);
+            }
+            return await f("PASS", console.log);
+        })();
+    }
+    expect: {
+        (async function() {
+            return await (a = "PASS", b = console.log, await b(a));
+            var a, b;
+        })();
+    }
+    expect_stdout: "PASS"
+    node_version: ">=8"
+}
+
+inline_await_3_trim: {
+    options = {
+        inline: true,
+        reduce_vars: true,
+        sequences: true,
+        side_effects: true,
+        unused: true,
+    }
+    input: {
+        (async function() {
+            async function f(a, b) {
+                return await b(a);
+            }
+            return await f("PASS", console.log);
+        })();
+    }
+    expect: {
+        (async function() {
+            return a = "PASS", b = console.log, await b(a);
+            var a, b;
+        })();
+    }
+    expect_stdout: "PASS"
+    node_version: ">=8"
+}
+
+await_unary: {
+    options = {
+        side_effects: true,
+    }
+    input: {
+        (async function() {
+            console.log("PASS");
+            await +[];
+            console.log("FAIL");
+        })();
+    }
+    expect: {
+        (async function() {
+            console.log("PASS");
+            await +[];
+            console.log("FAIL");
+        })();
+    }
+    expect_stdout: "PASS"
+    node_version: ">=8"
+}
+
 evaluate: {
     options = {
         evaluate: true,