fix corner case in `inline` (#4726)
authorAlex Lam S.L <alexlamsl@gmail.com>
Wed, 3 Mar 2021 01:18:02 +0000 (01:18 +0000)
committerGitHub <noreply@github.com>
Wed, 3 Mar 2021 01:18:02 +0000 (09:18 +0800)
fixes #4725

lib/ast.js
lib/compress.js
test/compress/classes.js
test/compress/functions.js

index b035b5c..e46fb2e 100644 (file)
@@ -1684,6 +1684,8 @@ var AST_ObjectMethod = DEFNODE("ObjectMethod", null, {
     $documentation: "A key(){} object property",
     _validate: function() {
         if (!(this.value instanceof AST_LambdaExpression)) throw new Error("value must be AST_LambdaExpression");
+        if (is_arrow(this.value)) throw new Error("value cannot be AST_Arrow or AST_AsyncArrow");
+        if (this.value.name != null) throw new Error("name of class method's lambda must be null");
     },
 }, AST_ObjectKeyVal);
 
index 55ff50b..1b22d86 100644 (file)
@@ -5210,6 +5210,7 @@ merge(Compressor.prototype, {
     OPT(AST_Function, function(self, compressor) {
         drop_rest_farg(self, compressor);
         self.body = tighten_body(self.body, compressor);
+        var parent = compressor.parent();
         if (compressor.option("inline")) for (var i = 0; i < self.body.length; i++) {
             var stat = self.body[i];
             if (stat instanceof AST_Directive) continue;
@@ -5231,6 +5232,9 @@ merge(Compressor.prototype, {
                         return def.scope !== self;
                     })) break;
                 }
+                if (fn.name
+                    && (parent instanceof AST_ClassMethod || parent instanceof AST_ObjectMethod)
+                    && parent.value === compressor.self()) break;
                 if (fn.contains_this()) break;
                 var len = fn.argnames.length;
                 if (len > 0 && compressor.option("inline") < 2) break;
@@ -5251,7 +5255,7 @@ merge(Compressor.prototype, {
                     if (call.args[j].has_side_effects(compressor)) break;
                 }
                 if (j < call.args.length) break;
-                if (len < self.argnames.length && !compressor.drop_fargs(self, compressor.parent())) {
+                if (len < self.argnames.length && !compressor.drop_fargs(self, parent)) {
                     if (!compressor.drop_fargs(fn, call)) break;
                     do {
                         fn.argnames.push(fn.make_var(AST_SymbolFunarg, fn, "argument_" + len));
index f073acd..82c6f30 100644 (file)
@@ -1172,3 +1172,57 @@ issue_4722_3: {
     expect_stdout: "PASS"
     node_version: ">=10"
 }
+
+issue_4725_1: {
+    options = {
+        inline: true,
+    }
+    input: {
+        "use strict";
+        console.log(typeof new class {
+            f() {
+                return function g() {
+                    return g;
+                }();
+            }
+        }().f());
+    }
+    expect: {
+        "use strict";
+        console.log(typeof new class {
+            f() {
+                return function g() {
+                    return g;
+                }();
+            }
+        }().f());
+    }
+    expect_stdout: "function"
+    node_version: ">=4"
+}
+
+issue_4725_2: {
+    options = {
+        inline: true,
+    }
+    input: {
+        "use strict";
+        new class {
+            f() {
+                return function() {
+                    while (console.log("PASS"));
+                }();
+            }
+        }().f();
+    }
+    expect: {
+        "use strict";
+        new class {
+            f() {
+                while (console.log("PASS"));
+            }
+        }().f();
+    }
+    expect_stdout: "PASS"
+    node_version: ">=4"
+}
index 44e41df..98dfc4d 100644 (file)
@@ -5698,3 +5698,57 @@ block_scope_4_compress: {
     }
     expect_stdout: "function"
 }
+
+issue_4725_1: {
+    options = {
+        inline: true,
+    }
+    input: {
+        var o = {
+            f() {
+                return function g() {
+                    return g;
+                }();
+            }
+        };
+        console.log(typeof o.f());
+    }
+    expect: {
+        var o = {
+            f() {
+                return function g() {
+                    return g;
+                }();
+            }
+        };
+        console.log(typeof o.f());
+    }
+    expect_stdout: "function"
+    node_version: ">=4"
+}
+
+issue_4725_2: {
+    options = {
+        inline: true,
+    }
+    input: {
+        var o = {
+            f() {
+                return function() {
+                    while (console.log("PASS"));
+                }();
+            }
+        };
+        o.f();
+    }
+    expect: {
+        var o = {
+            f() {
+                while (console.log("PASS"));
+            }
+        };
+        o.f();
+    }
+    expect_stdout: "PASS"
+    node_version: ">=4"
+}