inline Function() as code
- improve upon #203 - bail out on any local/global variable collisions
This commit is contained in:
parent
7f8d72d9d3
commit
32003fb54b
|
|
@ -2165,53 +2165,29 @@ merge(Compressor.prototype, {
|
|||
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);
|
||||
ast.figure_out_scope({ screw_ie8: compressor.option("screw_ie8") });
|
||||
var comp = new Compressor(compressor.options);
|
||||
ast = ast.transform(comp);
|
||||
ast.figure_out_scope({ screw_ie8: compressor.option("screw_ie8") });
|
||||
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;
|
||||
}
|
||||
// new Function("x", "return x") => function(x){return x}
|
||||
try {
|
||||
var args = self.args.map(function(arg) {
|
||||
if (!(arg instanceof AST_String)) throw self;
|
||||
return arg.value;
|
||||
});
|
||||
var code = args.pop();
|
||||
var ast = parse("(function(" + args.join() + "){" + code + "})");
|
||||
ast.figure_out_scope({ screw_ie8: compressor.option("screw_ie8") });
|
||||
var scope = compressor.find_parent(AST_Scope);
|
||||
ast.globals.each(function(g) {
|
||||
var def = scope.find_variable(g.name);
|
||||
if (def && !(def.scope instanceof AST_Toplevel)) throw self;
|
||||
});
|
||||
var fun = ast.body[0].body;
|
||||
fun.parent_scope = scope;
|
||||
return fun;
|
||||
} 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 if (ex !== self) {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -262,13 +262,6 @@ function makePredicate(words) {
|
|||
return new Function("str", f);
|
||||
};
|
||||
|
||||
function all(array, predicate) {
|
||||
for (var i = array.length; --i >= 0;)
|
||||
if (!predicate(array[i]))
|
||||
return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
function Dictionary() {
|
||||
this._values = Object.create(null);
|
||||
this._size = 0;
|
||||
|
|
|
|||
|
|
@ -6,3 +6,55 @@ non_ascii_function_identifier_name: {
|
|||
}
|
||||
expect_exact: "function fooλ(δλ){}function λ(δλ){}(function λ(δλ){})();"
|
||||
}
|
||||
|
||||
unsafe_eval: {
|
||||
options = {
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
var a = Function("x", "return x");
|
||||
|
||||
function e() {
|
||||
var a;
|
||||
return Function("return a");
|
||||
}
|
||||
|
||||
function f() {
|
||||
return Function("return a");
|
||||
}
|
||||
|
||||
function g(a) {
|
||||
return Function("b", "return [ a, b ]");
|
||||
}
|
||||
|
||||
function h(b) {
|
||||
return Function("b", "c", "return [ a, b, c ]");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a = function(x) {
|
||||
return x;
|
||||
};
|
||||
|
||||
function e() {
|
||||
var a;
|
||||
return Function("return a");
|
||||
}
|
||||
|
||||
function f() {
|
||||
return function() {
|
||||
return a;
|
||||
};
|
||||
}
|
||||
|
||||
function g(a) {
|
||||
return Function("b", "return [ a, b ]");
|
||||
}
|
||||
|
||||
function h(b) {
|
||||
return function(b, c) {
|
||||
return [ a, b, c ];
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user