fix corner case in `awaits` & `inline` (#5259)
authorAlex Lam S.L <alexlamsl@gmail.com>
Mon, 3 Jan 2022 12:57:24 +0000 (12:57 +0000)
committerGitHub <noreply@github.com>
Mon, 3 Jan 2022 12:57:24 +0000 (20:57 +0800)
fixes #5258

lib/compress.js
test/compress/awaits.js

index d5dc723..308a711 100644 (file)
@@ -5414,7 +5414,6 @@ Compressor.prototype.compress = function(node) {
         def(AST_Node, return_true);
 
         def(AST_Constant, return_false);
-        def(AST_Destructured, return_true);
         def(AST_EmptyStatement, return_false);
         def(AST_Lambda, return_false);
         def(AST_ObjectIdentity, return_false);
@@ -5448,6 +5447,9 @@ Compressor.prototype.compress = function(node) {
             }
             return this.left.may_throw(compressor);
         });
+        def(AST_Await, function(compressor) {
+            return this.expression.may_throw(compressor);
+        });
         def(AST_Binary, function(compressor) {
             return this.left.may_throw(compressor)
                 || this.right.may_throw(compressor)
@@ -5484,6 +5486,12 @@ Compressor.prototype.compress = function(node) {
             return !this.optional && this.expression.may_throw_on_access(compressor)
                 || this.expression.may_throw(compressor);
         });
+        def(AST_ForEnumeration, function(compressor) {
+            if (this.init.may_throw(compressor)) return true;
+            var obj = this.object.tail_node();
+            if (!(obj instanceof AST_Array || obj.is_string(compressor))) return true;
+            return this.body.may_throw(compressor);
+        });
         def(AST_If, function(compressor) {
             return this.condition.may_throw(compressor)
                 || this.body && this.body.may_throw(compressor)
@@ -12931,7 +12939,11 @@ Compressor.prototype.compress = function(node) {
                 defined.set("arguments", true);
             }
             var async = is_async(fn);
-            if (async && !(compressor.option("awaits") && is_async(scope))) return;
+            if (async) {
+                if (!compressor.option("awaits")) return;
+                if (!is_async(scope)) return;
+                if (call.may_throw(compressor)) return;
+            }
             var names = scope.var_names();
             if (in_loop) in_loop = [];
             if (!fn.variables.all(function(def, name) {
index 9dd9be2..96750dc 100644 (file)
@@ -2605,3 +2605,59 @@ issue_5250: {
     ]
     node_version: ">=8"
 }
+
+issue_5258_1: {
+    options = {
+        awaits: true,
+        inline: true,
+    }
+    input: {
+        (async function() {
+            (async function() {
+                throw "FAIL";
+            })();
+            return "PASS";
+        })().catch(console.log).then(console.log);
+    }
+    expect: {
+        (async function() {
+            (async function() {
+                throw "FAIL";
+            })();
+            return "PASS";
+        })().catch(console.log).then(console.log);
+    }
+    expect_stdout: "PASS"
+    node_version: ">=8"
+}
+
+issue_5258_2: {
+    options = {
+        awaits: true,
+        inline: true,
+    }
+    input: {
+        function f() {
+            throw "FAIL";
+        }
+        (async function() {
+            (async function() {
+                f();
+            })();
+            return "PASS";
+        })().catch(console.log).then(console.log);
+    }
+    expect: {
+        function f() {
+            throw "FAIL";
+        }
+        (async function() {
+            (async function() {
+                f();
+            })();
+            return "PASS";
+        })().catch(console.log).then(console.log);
+    }
+    expect_stdout: "PASS"
+    node_version: ">=8"
+}