enhance `unsafe` `evaluate` (#2037)
authorAlex Lam S.L <alexlamsl@gmail.com>
Wed, 31 May 2017 16:56:28 +0000 (00:56 +0800)
committerGitHub <noreply@github.com>
Wed, 31 May 2017 16:56:28 +0000 (00:56 +0800)
lib/compress.js
test/compress/evaluate.js

index 32a4d60..a928d7b 100644 (file)
@@ -1665,6 +1665,26 @@ merge(Compressor.prototype, {
             }
             throw def;
         });
+        def(AST_Call, function(compressor){
+            var exp = this.expression;
+            if (compressor.option("unsafe") && exp instanceof AST_PropAccess) {
+                var key = exp.property;
+                if (key instanceof AST_Node) {
+                    key = ev(key, compressor);
+                }
+                var val = ev(exp.expression, compressor);
+                var fn = val[key];
+                if (typeof fn == "function") {
+                    return fn.apply(val, this.args.map(function(arg) {
+                        return ev(arg, compressor);
+                    }));
+                }
+            }
+            throw def;
+        });
+        def(AST_New, function(compressor){
+            throw def;
+        });
     })(function(node, func){
         node.DEFMETHOD("_eval", func);
     });
@@ -3144,6 +3164,11 @@ merge(Compressor.prototype, {
             && is_iife_call(self)) {
             return self.negate(compressor, true);
         }
+        var ev = self.evaluate(compressor);
+        if (ev !== self) {
+            ev = make_node_from_constant(ev, self).optimize(compressor);
+            return best_of(compressor, ev, self);
+        }
         return self;
     });
 
index a1e3d0b..020d7cf 100644 (file)
@@ -1037,3 +1037,31 @@ issue_1964_2: {
     }
     expect_stdout: "b"
 }
+
+array_slice_index: {
+    options = {
+        evaluate: true,
+        unsafe: true,
+    }
+    input: {
+        console.log([1,2,3].slice(1)[1]);
+    }
+    expect: {
+        console.log(3);
+    }
+    expect_stdout: "3"
+}
+
+string_charCodeAt: {
+    options = {
+        evaluate: true,
+        unsafe: true,
+    }
+    input: {
+        console.log("foo".charCodeAt("bar".length));
+    }
+    expect: {
+        console.log(NaN);
+    }
+    expect_stdout: "NaN"
+}