Compress code passed to `new Function` if it's a constant.
authorMihai Bazon <mihai@bazon.net>
Tue, 14 May 2013 07:47:06 +0000 (10:47 +0300)
committerMihai Bazon <mihai@bazon.net>
Tue, 14 May 2013 07:47:06 +0000 (10:47 +0300)
Only for `--unsafe`.

Close #203

lib/compress.js
lib/transform.js

index 24cdc02..56fb685 100644 (file)
@@ -1589,6 +1589,45 @@ merge(Compressor.prototype, {
                         operator: "+",
                         right: make_node(AST_String, self, { value: "" })
                     });
+                  case "Function":
+                    if (self.args[self.args.length - 1] instanceof AST_String) {
+                        // quite a corner-case, but we can handle it:
+                        //   https://github.com/mishoo/UglifyJS2/issues/203
+                        // if the code argument is a constant, then we can minify it.
+                        try {
+                            var code = "(function(" + self.args.slice(0, -1).map(function(arg){
+                                return arg.value;
+                            }).join(",") + "){" + self.args[self.args.length - 1].value + "})()";
+                            var ast = parse(code);
+                            ast.figure_out_scope();
+                            var comp = new Compressor(compressor.options);
+                            ast = ast.transform(comp);
+                            ast.figure_out_scope();
+                            ast.mangle_names();
+                            var fun = ast.body[0].body.expression;
+                            var args = fun.argnames.map(function(arg, i){
+                                return make_node(AST_String, self.args[i], {
+                                    value: arg.print_to_string()
+                                });
+                            });
+                            var code = OutputStream();
+                            AST_BlockStatement.prototype._codegen.call(fun, fun, code);
+                            code = code.toString().replace(/^\{|\}$/g, "");
+                            args.push(make_node(AST_String, self.args[self.args.length - 1], {
+                                value: code
+                            }));
+                            self.args = args;
+                            return self;
+                        } catch(ex) {
+                            if (ex instanceof JS_Parse_Error) {
+                                compressor.warn("Error parsing code passed to new Function [{file}:{line},{col}]", self.args[self.args.length - 1].start);
+                                compressor.warn(ex.toString());
+                            } else {
+                                console.log(ex);
+                            }
+                        }
+                    }
+                    break;
                 }
             }
             else if (exp instanceof AST_Dot && exp.property == "toString" && self.args.length == 0) {
index 8b4fd9f..7a61e5f 100644 (file)
@@ -44,7 +44,6 @@
 "use strict";
 
 // Tree transformer helpers.
-// XXX: eventually I should refactor the compressor to use this infrastructure.
 
 function TreeTransformer(before, after) {
     TreeWalker.call(this);