fix corner cases with `class` (#4822)
authorAlex Lam S.L <alexlamsl@gmail.com>
Wed, 24 Mar 2021 20:36:50 +0000 (20:36 +0000)
committerGitHub <noreply@github.com>
Wed, 24 Mar 2021 20:36:50 +0000 (04:36 +0800)
fixes #4821

lib/compress.js
test/compress/classes.js

index cc67bb2..423e134 100644 (file)
@@ -998,7 +998,7 @@ merge(Compressor.prototype, {
                 if (prop.key instanceof AST_Node) prop.key.walk(tw);
                 return prop.value;
             }).forEach(function(prop) {
-                if (prop.static) {
+                if (prop.static && (prop.value instanceof AST_Lambda || !prop.value.contains_this())) {
                     prop.value.walk(tw);
                 } else {
                     push(tw);
@@ -7380,10 +7380,18 @@ merge(Compressor.prototype, {
         });
         def(AST_Class, function(compressor, first_in_statement) {
             var exprs = [], values = [];
-            this.properties.forEach(function(prop) {
+            var props = this.properties;
+            for (var i = 0; i < props.length; i++) {
+                var prop = props[i];
                 if (prop.key instanceof AST_Node) exprs.push(prop.key);
-                if (prop instanceof AST_ClassField && prop.static && prop.value) values.push(prop.value);
-            });
+                if (prop instanceof AST_ClassField
+                    && prop.static
+                    && prop.value
+                    && !(prop.value instanceof AST_Lambda)) {
+                    if (prop.value.contains_this()) return this;
+                    values.push(prop.value);
+                }
+            }
             var base = this.extends;
             if (base) {
                 if (base instanceof AST_SymbolRef) base = base.fixed_value();
@@ -11392,7 +11400,7 @@ merge(Compressor.prototype, {
 
     AST_Arrow.DEFMETHOD("contains_this", return_false);
     AST_AsyncArrow.DEFMETHOD("contains_this", return_false);
-    AST_Scope.DEFMETHOD("contains_this", function() {
+    AST_Node.DEFMETHOD("contains_this", function() {
         var result;
         var self = this;
         self.walk(new TreeWalker(function(node) {
index 7a9dfc5..a940e70 100644 (file)
@@ -1296,3 +1296,51 @@ issue_4756: {
     ]
     node_version: ">=12"
 }
+
+issue_4821_1: {
+    options = {
+        reduce_vars: true,
+        toplevel: true,
+        unused: true,
+    }
+    input: {
+        var a;
+        class A {
+            static p = void (a = this);
+        }
+        console.log(typeof a);
+    }
+    expect: {
+        var a;
+        class A {
+            static p = void (a = this);
+        }
+        console.log(typeof a);
+    }
+    expect_stdout: "function"
+    node_version: ">=12"
+}
+
+issue_4821_2: {
+    options = {
+        side_effects: true,
+        toplevel: true,
+        unused: true,
+    }
+    input: {
+        var a;
+        class A {
+            static p = void (a = this);
+        }
+        console.log(typeof a);
+    }
+    expect: {
+        var a;
+        (class {
+            static p = void (a = this);
+        });
+        console.log(typeof a);
+    }
+    expect_stdout: "function"
+    node_version: ">=12"
+}