Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08514030f4 | ||
|
|
694ca5d045 | ||
|
|
57fb58b263 | ||
|
|
18c1c9b38a | ||
|
|
5c1ae3662d | ||
|
|
cfebeb2f63 | ||
|
|
fc78423f1d |
125
lib/compress.js
125
lib/compress.js
@@ -48,51 +48,51 @@ function Compressor(options, false_by_default) {
|
||||
return new Compressor(options, false_by_default);
|
||||
TreeTransformer.call(this, this.before, this.after);
|
||||
this.options = defaults(options, {
|
||||
arguments : !false_by_default,
|
||||
booleans : !false_by_default,
|
||||
collapse_vars : !false_by_default,
|
||||
comparisons : !false_by_default,
|
||||
conditionals : !false_by_default,
|
||||
dead_code : !false_by_default,
|
||||
directives : !false_by_default,
|
||||
drop_console : false,
|
||||
drop_debugger : !false_by_default,
|
||||
evaluate : !false_by_default,
|
||||
expression : false,
|
||||
global_defs : false,
|
||||
hoist_funs : false,
|
||||
hoist_props : !false_by_default,
|
||||
hoist_vars : false,
|
||||
ie8 : false,
|
||||
if_return : !false_by_default,
|
||||
inline : !false_by_default,
|
||||
join_vars : !false_by_default,
|
||||
keep_fargs : true,
|
||||
keep_fnames : false,
|
||||
keep_infinity : false,
|
||||
loops : !false_by_default,
|
||||
negate_iife : !false_by_default,
|
||||
passes : 1,
|
||||
properties : !false_by_default,
|
||||
pure_getters : !false_by_default && "strict",
|
||||
pure_funcs : null,
|
||||
reduce_funcs : !false_by_default,
|
||||
reduce_vars : !false_by_default,
|
||||
sequences : !false_by_default,
|
||||
side_effects : !false_by_default,
|
||||
switches : !false_by_default,
|
||||
top_retain : null,
|
||||
toplevel : !!(options && options["top_retain"]),
|
||||
typeofs : !false_by_default,
|
||||
unsafe : false,
|
||||
unsafe_comps : false,
|
||||
unsafe_Function: false,
|
||||
unsafe_math : false,
|
||||
unsafe_proto : false,
|
||||
unsafe_regexp : false,
|
||||
arguments : !false_by_default,
|
||||
booleans : !false_by_default,
|
||||
collapse_vars : !false_by_default,
|
||||
comparisons : !false_by_default,
|
||||
conditionals : !false_by_default,
|
||||
dead_code : !false_by_default,
|
||||
directives : !false_by_default,
|
||||
drop_console : false,
|
||||
drop_debugger : !false_by_default,
|
||||
evaluate : !false_by_default,
|
||||
expression : false,
|
||||
global_defs : false,
|
||||
hoist_funs : false,
|
||||
hoist_props : !false_by_default,
|
||||
hoist_vars : false,
|
||||
ie8 : false,
|
||||
if_return : !false_by_default,
|
||||
inline : !false_by_default,
|
||||
join_vars : !false_by_default,
|
||||
keep_fargs : true,
|
||||
keep_fnames : false,
|
||||
keep_infinity : false,
|
||||
loops : !false_by_default,
|
||||
negate_iife : !false_by_default,
|
||||
passes : 1,
|
||||
properties : !false_by_default,
|
||||
pure_getters : !false_by_default && "strict",
|
||||
pure_funcs : null,
|
||||
reduce_funcs : !false_by_default,
|
||||
reduce_vars : !false_by_default,
|
||||
sequences : !false_by_default,
|
||||
side_effects : !false_by_default,
|
||||
switches : !false_by_default,
|
||||
top_retain : null,
|
||||
toplevel : !!(options && options["top_retain"]),
|
||||
typeofs : !false_by_default,
|
||||
unsafe : false,
|
||||
unsafe_comps : false,
|
||||
unsafe_Function : false,
|
||||
unsafe_math : false,
|
||||
unsafe_proto : false,
|
||||
unsafe_regexp : false,
|
||||
unsafe_undefined: false,
|
||||
unused : !false_by_default,
|
||||
warnings : false,
|
||||
unused : !false_by_default,
|
||||
warnings : false,
|
||||
}, true);
|
||||
var global_defs = this.options["global_defs"];
|
||||
if (typeof global_defs == "object") for (var key in global_defs) {
|
||||
@@ -450,8 +450,7 @@ merge(Compressor.prototype, {
|
||||
return value instanceof AST_Node && def.fixed.parent_scope === scope;
|
||||
}
|
||||
return all(def.orig, function(sym) {
|
||||
return !(sym instanceof AST_SymbolDefun
|
||||
|| sym instanceof AST_SymbolLambda);
|
||||
return !(sym instanceof AST_SymbolDefun || sym instanceof AST_SymbolLambda);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1699,6 +1698,19 @@ merge(Compressor.prototype, {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ab && !stat.alternative && stat.body instanceof AST_BlockStatement && next instanceof AST_Jump) {
|
||||
var negated = stat.condition.negate(compressor);
|
||||
if (negated.print_to_string().length <= stat.condition.print_to_string().length) {
|
||||
CHANGED = true;
|
||||
stat = stat.clone();
|
||||
stat.condition = negated;
|
||||
statements[j] = stat.body;
|
||||
stat.body = next;
|
||||
statements[i] = stat.transform(compressor);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
var ab = aborts(stat.alternative);
|
||||
if (can_merge_flow(ab)) {
|
||||
if (ab.label) {
|
||||
@@ -3316,13 +3328,14 @@ merge(Compressor.prototype, {
|
||||
} else if (node instanceof AST_Unary && node.write_only) {
|
||||
sym = node.expression;
|
||||
}
|
||||
if (/strict/.test(compressor.option("pure_getters"))) {
|
||||
while (sym instanceof AST_PropAccess && !sym.expression.may_throw_on_access(compressor)) {
|
||||
if (sym instanceof AST_Sub) props.unshift(sym.property);
|
||||
sym = sym.expression;
|
||||
}
|
||||
if (!/strict/.test(compressor.option("pure_getters"))) return sym instanceof AST_SymbolRef && sym;
|
||||
while (sym instanceof AST_PropAccess && !sym.expression.may_throw_on_access(compressor)) {
|
||||
if (sym instanceof AST_Sub) props.unshift(sym.property);
|
||||
sym = sym.expression;
|
||||
}
|
||||
return sym;
|
||||
return sym instanceof AST_SymbolRef && all(sym.definition().orig, function(sym) {
|
||||
return !(sym instanceof AST_SymbolLambda);
|
||||
}) && sym;
|
||||
};
|
||||
var in_use = [];
|
||||
var in_use_ids = Object.create(null); // avoid expensive linear scans of in_use
|
||||
@@ -3417,7 +3430,7 @@ merge(Compressor.prototype, {
|
||||
var parent = tt.parent();
|
||||
if (drop_vars) {
|
||||
var props = [], sym = assign_as_unused(node, props);
|
||||
if (sym instanceof AST_SymbolRef) {
|
||||
if (sym) {
|
||||
var def = sym.definition();
|
||||
var in_use = def.id in in_use_ids;
|
||||
var value = null;
|
||||
@@ -3616,8 +3629,7 @@ merge(Compressor.prototype, {
|
||||
|
||||
function scan_ref_scoped(node, descend) {
|
||||
var node_def, props = [], sym = assign_as_unused(node, props);
|
||||
if (sym instanceof AST_SymbolRef
|
||||
&& self.variables.get(sym.name) === (node_def = sym.definition())) {
|
||||
if (sym && self.variables.get(sym.name) === (node_def = sym.definition())) {
|
||||
props.forEach(function(prop) {
|
||||
prop.walk(tw);
|
||||
});
|
||||
@@ -5758,9 +5770,10 @@ merge(Compressor.prototype, {
|
||||
if (fixed instanceof AST_Defun) {
|
||||
fixed._squeezed = true;
|
||||
fixed = make_node(AST_Function, fixed, fixed);
|
||||
fixed.name = make_node(AST_SymbolLambda, fixed.name, fixed.name);
|
||||
}
|
||||
var value;
|
||||
if (d.recursive_refs > 0 && fixed.name instanceof AST_SymbolDefun) {
|
||||
if (d.recursive_refs > 0) {
|
||||
value = fixed.clone(true);
|
||||
var defun_def = value.name.definition();
|
||||
var lambda_def = value.variables.get(value.name.name);
|
||||
|
||||
@@ -694,23 +694,15 @@ function OutputStream(options) {
|
||||
// a function expression needs parens around it when it's provably
|
||||
// the first token to appear in a statement.
|
||||
PARENS(AST_Function, function(output) {
|
||||
if (!output.has_parens() && first_in_statement(output)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!output.has_parens() && first_in_statement(output)) return true;
|
||||
if (output.option('webkit')) {
|
||||
var p = output.parent();
|
||||
if (p instanceof AST_PropAccess && p.expression === this) {
|
||||
return true;
|
||||
}
|
||||
if (p instanceof AST_PropAccess && p.expression === this) return true;
|
||||
}
|
||||
|
||||
if (output.option('wrap_iife')) {
|
||||
var p = output.parent();
|
||||
return p instanceof AST_Call && p.expression === this;
|
||||
if (p instanceof AST_Call && p.expression === this) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
// same goes for an object literal, because otherwise it would be
|
||||
@@ -784,17 +776,17 @@ function OutputStream(options) {
|
||||
});
|
||||
|
||||
PARENS(AST_Call, function(output) {
|
||||
var p = output.parent(), p1;
|
||||
if (p instanceof AST_New && p.expression === this)
|
||||
return true;
|
||||
|
||||
// workaround for Safari bug.
|
||||
var p = output.parent();
|
||||
if (p instanceof AST_New && p.expression === this) return true;
|
||||
// https://bugs.webkit.org/show_bug.cgi?id=123506
|
||||
return this.expression instanceof AST_Function
|
||||
&& p instanceof AST_PropAccess
|
||||
&& p.expression === this
|
||||
&& (p1 = output.parent(1)) instanceof AST_Assign
|
||||
&& p1.left === p;
|
||||
if (output.option('webkit')) {
|
||||
var g = output.parent(1);
|
||||
return this.expression instanceof AST_Function
|
||||
&& p instanceof AST_PropAccess
|
||||
&& p.expression === this
|
||||
&& g instanceof AST_Assign
|
||||
&& g.left === p;
|
||||
}
|
||||
});
|
||||
|
||||
PARENS(AST_New, function(output) {
|
||||
|
||||
@@ -320,14 +320,6 @@ function next_mangled_name(scope, options, def) {
|
||||
var in_use = names_in_use(scope, options);
|
||||
var holes = scope.cname_holes;
|
||||
var names = Object.create(null);
|
||||
// #179, #326
|
||||
// in Safari strict mode, something like (function x(x){...}) is a syntax error;
|
||||
// a function expression's argument cannot shadow the function expression's name
|
||||
if (scope instanceof AST_Function && scope.name && def.orig[0] instanceof AST_SymbolFunarg) {
|
||||
var tricky_def = scope.name.definition();
|
||||
// the function's mangled_name is null when keep_fnames is true
|
||||
names[tricky_def.mangled_name || tricky_def.name] = true;
|
||||
}
|
||||
var scopes = [ scope ];
|
||||
def.references.forEach(function(sym) {
|
||||
var scope = sym.scope;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||
"license": "BSD-2-Clause",
|
||||
"version": "3.4.6",
|
||||
"version": "3.4.8",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
@@ -23,7 +23,7 @@
|
||||
"LICENSE"
|
||||
],
|
||||
"dependencies": {
|
||||
"commander": "~2.16.0",
|
||||
"commander": "~2.17.1",
|
||||
"source-map": "~0.6.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1982,3 +1982,26 @@ issue_3192: {
|
||||
"foo bar",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3233: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = function b() {
|
||||
b.c = "PASS";
|
||||
};
|
||||
a();
|
||||
console.log(a.c);
|
||||
}
|
||||
expect: {
|
||||
var a = function b() {
|
||||
b.c = "PASS";
|
||||
};
|
||||
a();
|
||||
console.log(a.c);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -236,32 +236,6 @@ issue_203: {
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
no_webkit: {
|
||||
beautify = {
|
||||
webkit: false,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
1 + 1;
|
||||
}.a = 1);
|
||||
}
|
||||
expect_exact: "console.log(function(){1+1}.a=1);"
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
webkit: {
|
||||
beautify = {
|
||||
webkit: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
1 + 1;
|
||||
}.a = 1);
|
||||
}
|
||||
expect_exact: "console.log((function(){1+1}).a=1);"
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_2084: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
|
||||
@@ -396,3 +396,151 @@ if_if_return_return: {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if_body_return_1: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
var c = "PASS";
|
||||
function f(a, b) {
|
||||
if (a) {
|
||||
if (b) throw new Error(c);
|
||||
return 42;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
console.log(f(0, 0));
|
||||
console.log(f(0, 1));
|
||||
console.log(f(1, 0));
|
||||
try {
|
||||
f(1, 1);
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var c = "PASS";
|
||||
function f(a, b) {
|
||||
if (a) {
|
||||
if (b) throw new Error(c);
|
||||
return 42;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
console.log(f(0, 0));
|
||||
console.log(f(0, 1));
|
||||
console.log(f(1, 0));
|
||||
try {
|
||||
f(1, 1);
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"true",
|
||||
"true",
|
||||
"42",
|
||||
"PASS",
|
||||
]
|
||||
}
|
||||
|
||||
if_body_return_2: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
var c = "PASS";
|
||||
function f(a, b) {
|
||||
if (0 + a) {
|
||||
if (b) throw new Error(c);
|
||||
return 42;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
console.log(f(0, 0));
|
||||
console.log(f(0, 1));
|
||||
console.log(f(1, 0));
|
||||
try {
|
||||
f(1, 1);
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var c = "PASS";
|
||||
function f(a, b) {
|
||||
if (0 + a) {
|
||||
if (b) throw new Error(c);
|
||||
return 42;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
console.log(f(0, 0));
|
||||
console.log(f(0, 1));
|
||||
console.log(f(1, 0));
|
||||
try {
|
||||
f(1, 1);
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"true",
|
||||
"true",
|
||||
"42",
|
||||
"PASS",
|
||||
]
|
||||
}
|
||||
|
||||
if_body_return_3: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
var c = "PASS";
|
||||
function f(a, b) {
|
||||
if (1 == a) {
|
||||
if (b) throw new Error(c);
|
||||
return 42;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
console.log(f(0, 0));
|
||||
console.log(f(0, 1));
|
||||
console.log(f(1, 0));
|
||||
try {
|
||||
f(1, 1);
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var c = "PASS";
|
||||
function f(a, b) {
|
||||
if (1 != a) return true;
|
||||
if (b) throw new Error(c);
|
||||
return 42;
|
||||
}
|
||||
console.log(f(0, 0));
|
||||
console.log(f(0, 1));
|
||||
console.log(f(1, 0));
|
||||
try {
|
||||
f(1, 1);
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"true",
|
||||
"true",
|
||||
"42",
|
||||
"PASS",
|
||||
]
|
||||
}
|
||||
|
||||
109
test/compress/webkit.js
Normal file
109
test/compress/webkit.js
Normal file
@@ -0,0 +1,109 @@
|
||||
lambda_call_dot_assign: {
|
||||
beautify = {
|
||||
webkit: false,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
return {};
|
||||
}().a = 1);
|
||||
}
|
||||
expect_exact: "console.log(function(){return{}}().a=1);"
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
lambda_call_dot_assign_webkit: {
|
||||
beautify = {
|
||||
webkit: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
return {};
|
||||
}().a = 1);
|
||||
}
|
||||
expect_exact: "console.log((function(){return{}}()).a=1);"
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
lambda_dot_assign: {
|
||||
beautify = {
|
||||
webkit: false,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
1 + 1;
|
||||
}.a = 1);
|
||||
}
|
||||
expect_exact: "console.log(function(){1+1}.a=1);"
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
lambda_dot_assign_webkit: {
|
||||
beautify = {
|
||||
webkit: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
1 + 1;
|
||||
}.a = 1);
|
||||
}
|
||||
expect_exact: "console.log((function(){1+1}).a=1);"
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
lambda_name_mangle: {
|
||||
mangle = {}
|
||||
input: {
|
||||
console.log(typeof function foo(bar) {});
|
||||
}
|
||||
expect_exact: "console.log(typeof function o(n){});"
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
lambda_name_mangle_ie8: {
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof function foo(bar) {});
|
||||
}
|
||||
expect_exact: "console.log(typeof function n(o){});"
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
function_name_mangle: {
|
||||
options = {
|
||||
keep_fnames: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
(function() {
|
||||
function foo(bar) {}
|
||||
console.log(typeof foo);
|
||||
})();
|
||||
}
|
||||
expect_exact: "(function(){console.log(typeof function o(n){})})();"
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
function_name_mangle_ie8: {
|
||||
options = {
|
||||
keep_fnames: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
function foo(bar) {}
|
||||
console.log(typeof foo);
|
||||
})();
|
||||
}
|
||||
expect_exact: "(function(){console.log(typeof function n(o){})})();"
|
||||
expect_stdout: "function"
|
||||
}
|
||||
@@ -23,10 +23,9 @@ module.exports = function(url, callback) {
|
||||
var options = parse(url);
|
||||
options.rejectUnauthorized = false;
|
||||
require(options.protocol.slice(0, -1)).get(options, function(res) {
|
||||
if (res.statusCode !== 200) return callback(res);
|
||||
res.pipe(fs.createWriteStream(local(url)).on("close", function() {
|
||||
callback(null, read(url));
|
||||
}));
|
||||
if (res.statusCode !== 200) return callback(res.statusCode);
|
||||
res.pipe(fs.createWriteStream(local(url)));
|
||||
callback(null, res);
|
||||
});
|
||||
}).on("open", function() {
|
||||
callback(null, result);
|
||||
|
||||
@@ -25,30 +25,35 @@ if (typeof phantom == "undefined") {
|
||||
request.resume();
|
||||
var url = site + request.url;
|
||||
fetch(url, function(err, res) {
|
||||
if (err) throw err;
|
||||
response.writeHead(200, {
|
||||
"Content-Type": {
|
||||
css: "text/css",
|
||||
js: "application/javascript",
|
||||
png: "image/png"
|
||||
}[url.slice(url.lastIndexOf(".") + 1)] || "text/html; charset=utf-8"
|
||||
});
|
||||
if (/\.js$/.test(url)) {
|
||||
var stderr = "";
|
||||
var uglifyjs = child_process.fork("bin/uglifyjs", args, {
|
||||
silent: true
|
||||
}).on("exit", function(code) {
|
||||
console.log("uglifyjs", url.slice(site.length + 1), args.join(" "));
|
||||
console.log(stderr);
|
||||
if (code) throw new Error("uglifyjs failed with code " + code);
|
||||
});
|
||||
uglifyjs.stderr.on("data", function(data) {
|
||||
stderr += data;
|
||||
}).setEncoding("utf8");
|
||||
uglifyjs.stdout.pipe(response);
|
||||
res.pipe(uglifyjs.stdin);
|
||||
if (err) {
|
||||
if (typeof err != "number") throw err;
|
||||
response.writeHead(err);
|
||||
response.end();
|
||||
} else {
|
||||
res.pipe(response);
|
||||
response.writeHead(200, {
|
||||
"Content-Type": {
|
||||
css: "text/css",
|
||||
js: "application/javascript",
|
||||
png: "image/png"
|
||||
}[url.slice(url.lastIndexOf(".") + 1)] || "text/html; charset=utf-8"
|
||||
});
|
||||
if (/\.js$/.test(url)) {
|
||||
var stderr = "";
|
||||
var uglifyjs = child_process.fork("bin/uglifyjs", args, {
|
||||
silent: true
|
||||
}).on("exit", function(code) {
|
||||
console.log("uglifyjs", url.slice(site.length + 1), args.join(" "));
|
||||
console.log(stderr);
|
||||
if (code) throw new Error("uglifyjs failed with code " + code);
|
||||
});
|
||||
uglifyjs.stderr.on("data", function(data) {
|
||||
stderr += data;
|
||||
}).setEncoding("utf8");
|
||||
uglifyjs.stdout.pipe(response);
|
||||
res.pipe(uglifyjs.stdin);
|
||||
} else {
|
||||
res.pipe(response);
|
||||
}
|
||||
}
|
||||
});
|
||||
}).listen();
|
||||
|
||||
@@ -651,7 +651,7 @@ describe("bin/uglifyjs", function() {
|
||||
});
|
||||
});
|
||||
it("Should work with explicit --no-rename", function(done) {
|
||||
var command = uglifyjscmd + " test/input/rename/input.js -mc --no-rename";
|
||||
var command = uglifyjscmd + " test/input/rename/input.js -mc passes=2 --no-rename";
|
||||
exec(command, function(err, stdout, stderr) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, "function f(n){return function(n){return n}(n)}\n");
|
||||
@@ -659,7 +659,7 @@ describe("bin/uglifyjs", function() {
|
||||
});
|
||||
});
|
||||
it("Should work with implicit --rename", function(done) {
|
||||
var command = uglifyjscmd + " test/input/rename/input.js -mc";
|
||||
var command = uglifyjscmd + " test/input/rename/input.js -mc passes=2";
|
||||
exec(command, function(err, stdout, stderr) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, "function f(n){return n}\n");
|
||||
@@ -667,7 +667,7 @@ describe("bin/uglifyjs", function() {
|
||||
});
|
||||
});
|
||||
it("Should work with implicit --no-rename", function(done) {
|
||||
var command = uglifyjscmd + " test/input/rename/input.js -c";
|
||||
var command = uglifyjscmd + " test/input/rename/input.js -c passes=2";
|
||||
exec(command, function(err, stdout, stderr) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, "function f(x){return function(x){return x}(x)}\n");
|
||||
|
||||
@@ -1,21 +1,6 @@
|
||||
var semver = require("semver");
|
||||
var vm = require("vm");
|
||||
|
||||
function createContext() {
|
||||
return vm.createContext(Object.defineProperty({}, "console", {
|
||||
value: {
|
||||
log: function(msg) {
|
||||
if (arguments.length == 1 && typeof msg == "string") {
|
||||
return console.log("%s", msg);
|
||||
}
|
||||
return console.log.apply(console, [].map.call(arguments, function(arg) {
|
||||
return safe_log(arg, 3);
|
||||
}));
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
function safe_log(arg, level) {
|
||||
if (arg) switch (typeof arg) {
|
||||
case "function":
|
||||
@@ -25,21 +10,21 @@ function safe_log(arg, level) {
|
||||
arg.constructor.toString();
|
||||
if (level--) for (var key in arg) {
|
||||
var desc = Object.getOwnPropertyDescriptor(arg, key);
|
||||
if (!desc || !desc.get) {
|
||||
arg[key] = safe_log(arg[key], level);
|
||||
}
|
||||
if (!desc || !desc.get) arg[key] = safe_log(arg[key], level);
|
||||
}
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
|
||||
function strip_func_ids(text) {
|
||||
return ("" + text).replace(/F[0-9]{6}N/g, "<F<>N>");
|
||||
function log(msg) {
|
||||
if (arguments.length == 1 && typeof msg == "string") return console.log("%s", msg);
|
||||
return console.log.apply(console, [].map.call(arguments, function(arg) {
|
||||
return safe_log(arg, 3);
|
||||
}));
|
||||
}
|
||||
|
||||
var context;
|
||||
var FUNC_TOSTRING = [
|
||||
"[ Array, Boolean, Error, Function, Number, Object, RegExp, String].forEach(function(f) {",
|
||||
var func_toString = new vm.Script([
|
||||
"[ Array, Boolean, Error, Function, Number, Object, RegExp, String ].forEach(function(f) {",
|
||||
" f.toString = Function.prototype.toString;",
|
||||
"});",
|
||||
"Function.prototype.toString = function() {",
|
||||
@@ -59,7 +44,15 @@ var FUNC_TOSTRING = [
|
||||
' return "function(){}";',
|
||||
" };",
|
||||
"}();",
|
||||
]).join("\n");
|
||||
]).join("\n"));
|
||||
|
||||
function createContext() {
|
||||
var ctx = vm.createContext(Object.defineProperty({}, "console", { value: { log: log } }));
|
||||
func_toString.runInContext(ctx);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
var context;
|
||||
exports.run_code = function(code, reuse) {
|
||||
var stdout = "";
|
||||
var original_write = process.stdout.write;
|
||||
@@ -69,7 +62,6 @@ exports.run_code = function(code, reuse) {
|
||||
try {
|
||||
if (!reuse || !context) context = createContext();
|
||||
vm.runInContext([
|
||||
FUNC_TOSTRING,
|
||||
"!function() {",
|
||||
code,
|
||||
"}();",
|
||||
@@ -86,6 +78,11 @@ exports.run_code = function(code, reuse) {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function strip_func_ids(text) {
|
||||
return ("" + text).replace(/F[0-9]{6}N/g, "<F<>N>");
|
||||
}
|
||||
|
||||
exports.same_stdout = semver.satisfies(process.version, "0.12") ? function(expected, actual) {
|
||||
if (typeof expected != typeof actual) return false;
|
||||
if (typeof expected != "string") {
|
||||
|
||||
Reference in New Issue
Block a user