aboutsummaryrefslogtreecommitdiff
path: root/lib/compress.js
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2017-05-31 03:38:00 +0800
committerGitHub <noreply@github.com>2017-05-31 03:38:00 +0800
commite9645e017f297e06506cc139922ff012fb763139 (patch)
tree0e2510c7a6aae20844829a6510ca6a2c6d95930d /lib/compress.js
parent55b5f2a8aa90a69e523c0a53ca92fcef45e5b209 (diff)
downloadtracifyjs-e9645e017f297e06506cc139922ff012fb763139.tar.gz
tracifyjs-e9645e017f297e06506cc139922ff012fb763139.zip
introduce `unsafe_Func` (#2033)
Separate flag for #203 functionality.
Diffstat (limited to 'lib/compress.js')
-rw-r--r--lib/compress.js115
1 files changed, 58 insertions, 57 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 374d14d4..32a4d603 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -81,6 +81,7 @@ function Compressor(options, false_by_default) {
toplevel : !!(options && options["top_retain"]),
unsafe : false,
unsafe_comps : false,
+ unsafe_Func : false,
unsafe_math : false,
unsafe_proto : false,
unsafe_regexp : false,
@@ -2973,63 +2974,6 @@ merge(Compressor.prototype, {
operator: "!"
}).optimize(compressor);
break;
- case "Function":
- // new Function() => function(){}
- if (self.args.length == 0) return make_node(AST_Function, self, {
- argnames: [],
- body: []
- });
- if (all(self.args, function(x){ return x 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);
- var mangle = { ie8: compressor.option("ie8") };
- ast.figure_out_scope(mangle);
- var comp = new Compressor(compressor.options);
- ast = ast.transform(comp);
- ast.figure_out_scope(mangle);
- ast.mangle_names();
- var fun;
- try {
- ast.walk(new TreeWalker(function(node){
- if (node instanceof AST_Lambda) {
- fun = node;
- throw ast;
- }
- }));
- } catch(ex) {
- if (ex !== ast) throw ex;
- };
- if (!fun) return self;
- 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);
- throw ex;
- }
- }
- }
- break;
}
}
else if (exp instanceof AST_Dot && exp.property == "toString" && self.args.length == 0) {
@@ -3112,6 +3056,63 @@ merge(Compressor.prototype, {
}
}
}
+ if (compressor.option("unsafe_Func")
+ && exp instanceof AST_SymbolRef
+ && exp.undeclared()
+ && exp.name == "Function") {
+ // new Function() => function(){}
+ if (self.args.length == 0) return make_node(AST_Function, self, {
+ argnames: [],
+ body: []
+ });
+ if (all(self.args, function(x) {
+ return x 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 = "NaN(function(" + self.args.slice(0, -1).map(function(arg) {
+ return arg.value;
+ }).join(",") + "){" + self.args[self.args.length - 1].value + "})";
+ var ast = parse(code);
+ var mangle = { ie8: compressor.option("ie8") };
+ ast.figure_out_scope(mangle);
+ var comp = new Compressor(compressor.options);
+ ast = ast.transform(comp);
+ ast.figure_out_scope(mangle);
+ ast.mangle_names();
+ var fun;
+ ast.walk(new TreeWalker(function(node) {
+ if (fun) return true;
+ if (node instanceof AST_Lambda) {
+ fun = node;
+ return true;
+ }
+ }));
+ 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 {
+ throw ex;
+ }
+ }
+ }
+ }
if (exp instanceof AST_Function) {
if (exp.body[0] instanceof AST_Return) {
var value = exp.body[0].value;