fix `unsafe` `evaluate` of `function` property (#2927)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sat, 17 Feb 2018 13:33:36 +0000 (21:33 +0800)
committerGitHub <noreply@github.com>
Sat, 17 Feb 2018 13:33:36 +0000 (21:33 +0800)
fixes #2926

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

index 0824830..f8e9f91 100644 (file)
@@ -2232,6 +2232,7 @@ merge(Compressor.prototype, {
             "slice",
         ].concat(object_fns),
         Boolean: object_fns,
+        Function: object_fns,
         Number: [
             "toExponential",
             "toFixed",
@@ -2340,10 +2341,10 @@ merge(Compressor.prototype, {
         });
         def(AST_Function, function(compressor) {
             if (compressor.option("unsafe")) {
-                var node = this;
                 var fn = function() {};
+                fn.node = this;
                 fn.toString = function() {
-                    return node.print_to_string();
+                    return this.node.print_to_string();
                 };
                 return fn;
             }
@@ -2523,6 +2524,14 @@ merge(Compressor.prototype, {
                 } else {
                     val = exp._eval(compressor, depth + 1);
                     if (!val || val === exp || !HOP(val, key)) return this;
+                    if (typeof val == "function") switch (key) {
+                      case "name":
+                        return val.node.name ? val.node.name.name : "";
+                      case "length":
+                        return val.node.argnames.length;
+                      default:
+                        return this;
+                    }
                 }
                 return val[key];
             }
index 2294ca0..614020e 100644 (file)
@@ -1502,3 +1502,36 @@ issue_2919: {
         console.log("function(){}");
     }
 }
+
+issue_2926_1: {
+    options = {
+        evaluate: true,
+        reduce_vars: true,
+        unsafe: true,
+    }
+    input: {
+        (function f(a) {
+            console.log(f.name.length, f.length);
+        })();
+    }
+    expect: {
+        (function f(a) {
+            console.log(1, 1);
+        })();
+    }
+    expect_stdout: "1 1"
+}
+
+issue_2926_2: {
+    options = {
+        evaluate: true,
+        unsafe: true,
+    }
+    input: {
+        console.log(typeof function() {}.valueOf());
+    }
+    expect: {
+        console.log("function");
+    }
+    expect_stdout: "function"
+}