fix corner case in `evaluate` (#4553)
authorAlex Lam S.L <alexlamsl@gmail.com>
Wed, 13 Jan 2021 14:17:24 +0000 (14:17 +0000)
committerGitHub <noreply@github.com>
Wed, 13 Jan 2021 14:17:24 +0000 (22:17 +0800)
fixes #4552

lib/compress.js
test/compress/evaluate.js

index 80dd7ea..f0ed677 100644 (file)
@@ -4244,7 +4244,7 @@ merge(Compressor.prototype, {
         def(AST_Call, function(compressor, ignore_side_effects, cached, depth) {
             var exp = this.expression;
             var fn = exp instanceof AST_SymbolRef ? exp.fixed_value() : exp;
-            if (fn instanceof AST_Defun || fn instanceof AST_Function) {
+            if (fn instanceof AST_Arrow || fn instanceof AST_Defun || fn instanceof AST_Function) {
                 if (fn.evaluating) return this;
                 if (fn.name && fn.name.definition().recursive_refs > 0) return this;
                 if (this.is_expr_pure(compressor)) return this;
@@ -4264,8 +4264,9 @@ merge(Compressor.prototype, {
                 var stat = fn.first_statement();
                 if (!(stat instanceof AST_Return)) {
                     if (ignore_side_effects) {
+                        fn.walk(scan_modified);
                         var found = false;
-                        fn.walk(new TreeWalker(function(node) {
+                        walk_body(fn, new TreeWalker(function(node) {
                             if (found) return true;
                             if (node instanceof AST_Return) {
                                 if (node.value && node.value._eval(compressor, true, cached, depth) !== undefined) {
@@ -8245,7 +8246,7 @@ merge(Compressor.prototype, {
             if (compressor.option("side_effects")
                 && can_drop
                 && all(fn.body, is_empty)
-                && (fn === exp ? fn_name_unused(fn, compressor) : !fn.rest && !has_default && !has_destructured)
+                && (fn === exp ? fn_name_unused(fn, compressor) : !has_default && !has_destructured && !fn.rest)
                 && !(is_arrow(fn) && fn.value)) {
                 return make_sequence(self, convert_args()).optimize(compressor);
             }
@@ -8288,7 +8289,7 @@ merge(Compressor.prototype, {
 
         function convert_args(value) {
             var args = self.args.slice();
-            var destructured = fn.rest || has_default > 1 || has_destructured;
+            var destructured = has_default > 1 || has_destructured || fn.rest;
             if (destructured || has_spread) args = [ make_node(AST_Array, self, { elements: args }) ];
             if (destructured) {
                 var tt = new TreeTransformer(function(node, descend) {
index 73c982f..2b1bbc0 100644 (file)
@@ -3142,3 +3142,36 @@ issue_4480: {
     }
     expect_stdout: "PASS"
 }
+
+issue_4552: {
+    options = {
+        evaluate: true,
+        keep_fnames: true,
+        reduce_vars: true,
+        toplevel: true,
+        unused: true,
+    }
+    input: {
+        var a = function f(b) {
+            return function() {
+                b++;
+                try {
+                    return b;
+                } catch (e) {}
+            }();
+        }();
+        console.log(a);
+    }
+    expect: {
+        var a = function f(b) {
+            return function() {
+                b++;
+                try {
+                    return b;
+                } catch (e) {}
+            }();
+        }();
+        console.log(a);
+    }
+    expect_stdout: "NaN"
+}