Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9336cc8247 | ||
|
|
9809567dfc | ||
|
|
1ee8be8d91 | ||
|
|
8430c2f9f8 | ||
|
|
659c8a7632 | ||
|
|
3564b4f20d | ||
|
|
3505a3604a | ||
|
|
9b1bc6c014 | ||
|
|
9f23185f2b | ||
|
|
b82feb9302 | ||
|
|
7f2a591c7e | ||
|
|
afbcebddf6 | ||
|
|
484e484571 | ||
|
|
6f3f21233f | ||
|
|
a6873a3859 | ||
|
|
7a6d452b54 | ||
|
|
9b58b54e2d | ||
|
|
c598a12af9 | ||
|
|
cfe3a98ce5 | ||
|
|
14778e049b | ||
|
|
446fb0198b | ||
|
|
7d3cddf9d6 | ||
|
|
6dead95eb3 | ||
|
|
cc931b3ad8 | ||
|
|
d838b4b52e | ||
|
|
2f3bddbaca | ||
|
|
673b071637 | ||
|
|
da82fa59a7 | ||
|
|
333792352e | ||
|
|
e2ec270b04 | ||
|
|
ed7a0a454e | ||
|
|
d819559a01 | ||
|
|
8ca49155a8 | ||
|
|
b95e3338d9 | ||
|
|
e40a0ee9c6 | ||
|
|
cb62bd98d3 | ||
|
|
f30790b11b | ||
|
|
5205dbcbf4 | ||
|
|
3ff625de7e | ||
|
|
4832bc5d88 | ||
|
|
7f342cb3e3 | ||
|
|
05e7d34ed4 | ||
|
|
86607156e3 | ||
|
|
0fe259e9c5 |
@@ -640,7 +640,13 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
||||
|
||||
- `if_return` (default: `true`) -- optimizations for if/return and if/continue
|
||||
|
||||
- `inline` (default: `true`) -- embed simple functions
|
||||
- `inline` (default: `true`) -- inline calls to function with simple/`return` statement:
|
||||
- `false` -- same as `0`
|
||||
- `0` -- disabled inlining
|
||||
- `1` -- inline simple functions
|
||||
- `2` -- inline functions with arguments
|
||||
- `3` -- inline functions with arguments and variables
|
||||
- `true` -- same as `3`
|
||||
|
||||
- `join_vars` (default: `true`) -- join consecutive `var` statements
|
||||
|
||||
|
||||
28
appveyor.yml
28
appveyor.yml
@@ -1,24 +1,20 @@
|
||||
environment:
|
||||
matrix:
|
||||
- nodejs_version: "0.10"
|
||||
- nodejs_version: "0.12"
|
||||
- nodejs_version: "4.0"
|
||||
- nodejs_version: "6.0"
|
||||
|
||||
- nodejs_version: "0.10"
|
||||
- nodejs_version: "0.12"
|
||||
- nodejs_version: "4"
|
||||
- nodejs_version: "6"
|
||||
- nodejs_version: "8"
|
||||
install:
|
||||
- ps: Install-Product node $env:nodejs_version
|
||||
- set UGLIFYJS_TEST_ALL=1
|
||||
- npm install
|
||||
build: off
|
||||
cache:
|
||||
- tmp
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
platform:
|
||||
- x86
|
||||
- x64
|
||||
|
||||
install:
|
||||
- ps: Install-Product node $env:nodejs_version $env:platform
|
||||
- npm install
|
||||
|
||||
test_script:
|
||||
- node --version
|
||||
- npm --version
|
||||
- npm test
|
||||
|
||||
build: off
|
||||
|
||||
@@ -3,11 +3,7 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
// workaround for tty output truncation upon process.exit()
|
||||
[process.stdout, process.stderr].forEach(function(stream){
|
||||
if (stream._handle && stream._handle.setBlocking)
|
||||
stream._handle.setBlocking(true);
|
||||
});
|
||||
require("../tools/exit");
|
||||
|
||||
var fs = require("fs");
|
||||
var info = require("../package.json");
|
||||
|
||||
632
lib/compress.js
632
lib/compress.js
File diff suppressed because it is too large
Load Diff
@@ -29,7 +29,6 @@ function set_shorthand(name, options, keys) {
|
||||
|
||||
function init_cache(cache) {
|
||||
if (!cache) return;
|
||||
if (!("cname" in cache)) cache.cname = -1;
|
||||
if (!("props" in cache)) {
|
||||
cache.props = new Dictionary();
|
||||
} else if (!(cache.props instanceof Dictionary)) {
|
||||
@@ -39,7 +38,6 @@ function init_cache(cache) {
|
||||
|
||||
function to_json(cache) {
|
||||
return {
|
||||
cname: cache.cname,
|
||||
props: cache.props.toObject()
|
||||
};
|
||||
}
|
||||
|
||||
@@ -534,7 +534,11 @@ function OutputStream(options) {
|
||||
var token = node.end;
|
||||
if (!token) return;
|
||||
var comments = token[tail ? "comments_before" : "comments_after"];
|
||||
if (comments && comments._dumped !== self) {
|
||||
if (comments
|
||||
&& comments._dumped !== self
|
||||
&& (node instanceof AST_Statement || all(comments, function(c) {
|
||||
return !/comment[134]/.test(c.type);
|
||||
}))) {
|
||||
comments._dumped = self;
|
||||
var insert = OUTPUT.length;
|
||||
comments.filter(comment_filter, node).forEach(function(c, i) {
|
||||
@@ -599,7 +603,7 @@ function OutputStream(options) {
|
||||
add_mapping : add_mapping,
|
||||
option : function(opt) { return options[opt] },
|
||||
prepend_comments: readonly ? noop : prepend_comments,
|
||||
append_comments : readonly ? noop : append_comments,
|
||||
append_comments : readonly || comment_filter === return_false ? noop : append_comments,
|
||||
line : function() { return current_line },
|
||||
col : function() { return current_col },
|
||||
pos : function() { return current_pos },
|
||||
@@ -671,9 +675,7 @@ function OutputStream(options) {
|
||||
}
|
||||
};
|
||||
|
||||
PARENS(AST_Node, function(){
|
||||
return false;
|
||||
});
|
||||
PARENS(AST_Node, return_false);
|
||||
|
||||
// a function expression needs parens around it when it's provably
|
||||
// the first token to appear in a statement.
|
||||
@@ -699,9 +701,7 @@ function OutputStream(options) {
|
||||
|
||||
// same goes for an object literal, because otherwise it would be
|
||||
// interpreted as a block of code.
|
||||
PARENS(AST_Object, function(output){
|
||||
return first_in_statement(output);
|
||||
});
|
||||
PARENS(AST_Object, first_in_statement);
|
||||
|
||||
PARENS(AST_Unary, function(output){
|
||||
var p = output.parent();
|
||||
|
||||
44
lib/parse.js
44
lib/parse.js
@@ -774,10 +774,15 @@ function parse($TEXT, options) {
|
||||
|
||||
function expect(punc) { return expect_token("punc", punc); };
|
||||
|
||||
function has_newline_before(token) {
|
||||
return token.nlb || !all(token.comments_before, function(comment) {
|
||||
return !comment.nlb;
|
||||
});
|
||||
}
|
||||
|
||||
function can_insert_semicolon() {
|
||||
return !options.strict && (
|
||||
S.token.nlb || is("eof") || is("punc", "}")
|
||||
);
|
||||
return !options.strict
|
||||
&& (is("eof") || is("punc", "}") || has_newline_before(S.token));
|
||||
};
|
||||
|
||||
function semicolon(optional) {
|
||||
@@ -795,7 +800,7 @@ function parse($TEXT, options) {
|
||||
function embed_tokens(parser) {
|
||||
return function() {
|
||||
var start = S.token;
|
||||
var expr = parser();
|
||||
var expr = parser.apply(null, arguments);
|
||||
var end = prev();
|
||||
expr.start = start;
|
||||
expr.end = end;
|
||||
@@ -810,17 +815,17 @@ function parse($TEXT, options) {
|
||||
}
|
||||
};
|
||||
|
||||
var statement = embed_tokens(function() {
|
||||
var statement = embed_tokens(function(strict_defun) {
|
||||
handle_regexp();
|
||||
switch (S.token.type) {
|
||||
case "string":
|
||||
if (S.in_directives) {
|
||||
var token = peek();
|
||||
if (S.token.raw.indexOf("\\") == -1
|
||||
&& (token.nlb
|
||||
|| is_token(token, "eof")
|
||||
|| is_token(token, "punc", ";")
|
||||
|| is_token(token, "punc", "}"))) {
|
||||
&& (is_token(token, "punc", ";")
|
||||
|| is_token(token, "punc", "}")
|
||||
|| has_newline_before(token)
|
||||
|| is_token(token, "eof"))) {
|
||||
S.input.add_directive(S.token.value);
|
||||
} else {
|
||||
S.in_directives = false;
|
||||
@@ -896,6 +901,9 @@ function parse($TEXT, options) {
|
||||
return for_();
|
||||
|
||||
case "function":
|
||||
if (!strict_defun && S.input.has_directive("use strict")) {
|
||||
croak("In strict mode code, functions can only be declared at top level or immediately within another function.");
|
||||
}
|
||||
next();
|
||||
return function_(AST_Defun);
|
||||
|
||||
@@ -927,7 +935,7 @@ function parse($TEXT, options) {
|
||||
|
||||
case "throw":
|
||||
next();
|
||||
if (S.token.nlb)
|
||||
if (has_newline_before(S.token))
|
||||
croak("Illegal newline after 'throw'");
|
||||
var value = expression(true);
|
||||
semicolon();
|
||||
@@ -1078,7 +1086,7 @@ function parse($TEXT, options) {
|
||||
S.input.push_directives_stack();
|
||||
S.in_loop = 0;
|
||||
S.labels = [];
|
||||
var body = block_();
|
||||
var body = block_(true);
|
||||
if (S.input.has_directive("use strict")) {
|
||||
if (name) strict_verify_symbol(name);
|
||||
argnames.forEach(strict_verify_symbol);
|
||||
@@ -1107,12 +1115,12 @@ function parse($TEXT, options) {
|
||||
});
|
||||
};
|
||||
|
||||
function block_() {
|
||||
function block_(strict_defun) {
|
||||
expect("{");
|
||||
var a = [];
|
||||
while (!is("punc", "}")) {
|
||||
if (is("eof")) unexpected();
|
||||
a.push(statement());
|
||||
a.push(statement(strict_defun));
|
||||
}
|
||||
next();
|
||||
return a;
|
||||
@@ -1220,12 +1228,14 @@ function parse($TEXT, options) {
|
||||
} else {
|
||||
args = [];
|
||||
}
|
||||
return subscripts(new AST_New({
|
||||
var call = new AST_New({
|
||||
start : start,
|
||||
expression : newexp,
|
||||
args : args,
|
||||
end : prev()
|
||||
}), allow_calls);
|
||||
});
|
||||
mark_pure(call);
|
||||
return subscripts(call, allow_calls);
|
||||
};
|
||||
|
||||
function as_atom_node() {
|
||||
@@ -1503,7 +1513,7 @@ function parse($TEXT, options) {
|
||||
return ex;
|
||||
}
|
||||
var val = expr_atom(allow_calls);
|
||||
while (is("operator") && UNARY_POSTFIX(S.token.value) && !S.token.nlb) {
|
||||
while (is("operator") && UNARY_POSTFIX(S.token.value) && !has_newline_before(S.token)) {
|
||||
val = make_unary(AST_UnaryPostfix, S.token, val);
|
||||
val.start = start;
|
||||
val.end = S.token;
|
||||
@@ -1623,7 +1633,7 @@ function parse($TEXT, options) {
|
||||
var body = [];
|
||||
S.input.push_directives_stack();
|
||||
while (!is("eof"))
|
||||
body.push(statement());
|
||||
body.push(statement(true));
|
||||
S.input.pop_directives_stack();
|
||||
var end = prev();
|
||||
var toplevel = options.toplevel;
|
||||
|
||||
@@ -110,12 +110,15 @@ function mangle_properties(ast, options) {
|
||||
if (!Array.isArray(reserved)) reserved = [];
|
||||
if (!options.builtins) find_builtins(reserved);
|
||||
|
||||
var cache = options.cache;
|
||||
if (cache == null) {
|
||||
cache = {
|
||||
cname: -1,
|
||||
props: new Dictionary()
|
||||
};
|
||||
var cname = -1;
|
||||
var cache;
|
||||
if (options.cache) {
|
||||
cache = options.cache.props;
|
||||
cache.each(function(mangled_name) {
|
||||
push_uniq(reserved, mangled_name);
|
||||
});
|
||||
} else {
|
||||
cache = new Dictionary();
|
||||
}
|
||||
|
||||
var regex = options.regex;
|
||||
@@ -172,7 +175,7 @@ function mangle_properties(ast, options) {
|
||||
if (unmangleable.indexOf(name) >= 0) return false;
|
||||
if (reserved.indexOf(name) >= 0) return false;
|
||||
if (options.only_cache) {
|
||||
return cache.props.has(name);
|
||||
return cache.has(name);
|
||||
}
|
||||
if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false;
|
||||
return true;
|
||||
@@ -181,7 +184,7 @@ function mangle_properties(ast, options) {
|
||||
function should_mangle(name) {
|
||||
if (regex && !regex.test(name)) return false;
|
||||
if (reserved.indexOf(name) >= 0) return false;
|
||||
return cache.props.has(name)
|
||||
return cache.has(name)
|
||||
|| names_to_mangle.indexOf(name) >= 0;
|
||||
}
|
||||
|
||||
@@ -199,7 +202,7 @@ function mangle_properties(ast, options) {
|
||||
return name;
|
||||
}
|
||||
|
||||
var mangled = cache.props.get(name);
|
||||
var mangled = cache.get(name);
|
||||
if (!mangled) {
|
||||
if (debug) {
|
||||
// debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
|
||||
@@ -213,11 +216,11 @@ function mangle_properties(ast, options) {
|
||||
// either debug mode is off, or it is on and we could not use the mangled name
|
||||
if (!mangled) {
|
||||
do {
|
||||
mangled = base54(++cache.cname);
|
||||
mangled = base54(++cname);
|
||||
} while (!can_mangle(mangled));
|
||||
}
|
||||
|
||||
cache.props.set(name, mangled);
|
||||
cache.set(name, mangled);
|
||||
}
|
||||
return mangled;
|
||||
}
|
||||
|
||||
66
lib/scope.js
66
lib/scope.js
@@ -43,9 +43,10 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
function SymbolDef(scope, orig) {
|
||||
function SymbolDef(scope, orig, init) {
|
||||
this.name = orig.name;
|
||||
this.orig = [ orig ];
|
||||
this.init = init;
|
||||
this.eliminated = 0;
|
||||
this.scope = scope;
|
||||
this.references = [];
|
||||
@@ -150,7 +151,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
node.references = [];
|
||||
}
|
||||
if (node instanceof AST_SymbolLambda) {
|
||||
defun.def_function(node);
|
||||
defun.def_function(node, node.name == "arguments" ? undefined : defun);
|
||||
}
|
||||
else if (node instanceof AST_SymbolDefun) {
|
||||
// Careful here, the scope where this should be defined is
|
||||
@@ -158,10 +159,10 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
// scope when we encounter the AST_Defun node (which is
|
||||
// instanceof AST_Scope) but we get to the symbol a bit
|
||||
// later.
|
||||
(node.scope = defun.parent_scope).def_function(node);
|
||||
(node.scope = defun.parent_scope).def_function(node, defun);
|
||||
}
|
||||
else if (node instanceof AST_SymbolVar) {
|
||||
defun.def_variable(node);
|
||||
defun.def_variable(node, node.TYPE == "SymbolVar" ? null : undefined);
|
||||
if (defun !== scope) {
|
||||
node.mark_enclosed(options);
|
||||
var def = scope.find_variable(node);
|
||||
@@ -241,10 +242,6 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
if (options.cache) {
|
||||
this.cname = options.cache.cname;
|
||||
}
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("def_global", function(node){
|
||||
@@ -306,27 +303,32 @@ AST_Scope.DEFMETHOD("find_variable", function(name){
|
||||
|| (this.parent_scope && this.parent_scope.find_variable(name));
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("def_function", function(symbol){
|
||||
this.functions.set(symbol.name, this.def_variable(symbol));
|
||||
AST_Scope.DEFMETHOD("def_function", function(symbol, init){
|
||||
var def = this.def_variable(symbol, init);
|
||||
if (!def.init) def.init = init;
|
||||
this.functions.set(symbol.name, def);
|
||||
return def;
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("def_variable", function(symbol){
|
||||
var def;
|
||||
if (!this.variables.has(symbol.name)) {
|
||||
def = new SymbolDef(this, symbol);
|
||||
AST_Scope.DEFMETHOD("def_variable", function(symbol, init){
|
||||
var def = this.variables.get(symbol.name);
|
||||
if (def) {
|
||||
def.orig.push(symbol);
|
||||
if (def.init && (def.scope !== symbol.scope || def.init instanceof AST_Function)) {
|
||||
def.init = init;
|
||||
}
|
||||
} else {
|
||||
def = new SymbolDef(this, symbol, init);
|
||||
this.variables.set(symbol.name, def);
|
||||
def.global = !this.parent_scope;
|
||||
} else {
|
||||
def = this.variables.get(symbol.name);
|
||||
def.orig.push(symbol);
|
||||
}
|
||||
return symbol.thedef = def;
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("next_mangled", function(options){
|
||||
var ext = this.enclosed;
|
||||
function next_mangled(scope, options) {
|
||||
var ext = scope.enclosed;
|
||||
out: while (true) {
|
||||
var m = base54(++this.cname);
|
||||
var m = base54(++scope.cname);
|
||||
if (!is_identifier(m)) continue; // skip over "do"
|
||||
|
||||
// https://github.com/mishoo/UglifyJS2/issues/242 -- do not
|
||||
@@ -343,6 +345,18 @@ AST_Scope.DEFMETHOD("next_mangled", function(options){
|
||||
}
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
AST_Scope.DEFMETHOD("next_mangled", function(options){
|
||||
return next_mangled(this, options);
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("next_mangled", function(options){
|
||||
var name;
|
||||
do {
|
||||
name = next_mangled(this, options);
|
||||
} while (member(name, this.mangled_names));
|
||||
return name;
|
||||
});
|
||||
|
||||
AST_Function.DEFMETHOD("next_mangled", function(options, def){
|
||||
@@ -356,7 +370,7 @@ AST_Function.DEFMETHOD("next_mangled", function(options, def){
|
||||
var tricky_name = tricky_def ? tricky_def.mangled_name || tricky_def.name : null;
|
||||
|
||||
while (true) {
|
||||
var name = AST_Lambda.prototype.next_mangled.call(this, options, def);
|
||||
var name = next_mangled(this, options);
|
||||
if (!tricky_name || tricky_name != name)
|
||||
return name;
|
||||
}
|
||||
@@ -407,8 +421,14 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
||||
var lname = -1;
|
||||
var to_mangle = [];
|
||||
|
||||
var mangled_names = this.mangled_names = [];
|
||||
if (options.cache) {
|
||||
this.globals.each(collect);
|
||||
if (options.cache.props) {
|
||||
options.cache.props.each(function(mangled_name) {
|
||||
push_uniq(mangled_names, mangled_name);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var tw = new TreeWalker(function(node, descend){
|
||||
@@ -437,10 +457,6 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
||||
this.walk(tw);
|
||||
to_mangle.forEach(function(def){ def.mangle(options) });
|
||||
|
||||
if (options.cache) {
|
||||
options.cache.cname = this.cname;
|
||||
}
|
||||
|
||||
function collect(symbol) {
|
||||
if (!member(symbol.name, options.reserved)) {
|
||||
to_mangle.push(symbol);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"homepage": "http://lisperator.net/uglifyjs",
|
||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||
"license": "BSD-2-Clause",
|
||||
"version": "3.3.1",
|
||||
"version": "3.3.5",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
|
||||
@@ -3878,10 +3878,9 @@ recursive_function_replacement: {
|
||||
console.log(f(c));
|
||||
}
|
||||
expect: {
|
||||
function f(n) {
|
||||
return x(y(f(n)));
|
||||
}
|
||||
console.log(f(c));
|
||||
console.log(function n(o) {
|
||||
return x(y(n(o)));
|
||||
}(c));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1203,3 +1203,24 @@ issue_2560: {
|
||||
"2",
|
||||
]
|
||||
}
|
||||
|
||||
hoist_decl: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
join_vars: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
if (x()) {
|
||||
var a;
|
||||
y();
|
||||
} else {
|
||||
z();
|
||||
var b;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a, b;
|
||||
x() ? y() : z();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,46 +62,6 @@ dead_code_2_should_warn: {
|
||||
node_version: "<=4"
|
||||
}
|
||||
|
||||
dead_code_2_should_warn_strict: {
|
||||
options = {
|
||||
dead_code: true
|
||||
};
|
||||
input: {
|
||||
"use strict";
|
||||
function f() {
|
||||
g();
|
||||
x = 10;
|
||||
throw new Error("foo");
|
||||
// completely discarding the `if` would introduce some
|
||||
// bugs. UglifyJS v1 doesn't deal with this issue; in v2
|
||||
// we copy any declarations to the upper scope.
|
||||
if (x) {
|
||||
y();
|
||||
var x;
|
||||
function g(){};
|
||||
// but nested declarations should not be kept.
|
||||
(function(){
|
||||
var q;
|
||||
function y(){};
|
||||
})();
|
||||
}
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f() {
|
||||
g();
|
||||
x = 10;
|
||||
throw new Error("foo");
|
||||
var x;
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
dead_code_constant_boolean_should_warn_more: {
|
||||
options = {
|
||||
dead_code : true,
|
||||
@@ -137,42 +97,6 @@ dead_code_constant_boolean_should_warn_more: {
|
||||
node_version: "<=4"
|
||||
}
|
||||
|
||||
dead_code_constant_boolean_should_warn_more_strict: {
|
||||
options = {
|
||||
dead_code : true,
|
||||
loops : true,
|
||||
booleans : true,
|
||||
conditionals : true,
|
||||
evaluate : true,
|
||||
side_effects : true,
|
||||
};
|
||||
input: {
|
||||
"use strict";
|
||||
while (!((foo && bar) || (x + "0"))) {
|
||||
console.log("unreachable");
|
||||
var foo;
|
||||
function bar() {}
|
||||
}
|
||||
for (var x = 10, y; x && (y || x) && (!typeof x); ++x) {
|
||||
asdf();
|
||||
foo();
|
||||
var moo;
|
||||
}
|
||||
bar();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var foo;
|
||||
// nothing for the while
|
||||
// as for the for, it should keep:
|
||||
var moo;
|
||||
var x = 10, y;
|
||||
bar();
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
try_catch_finally: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
@@ -828,3 +752,84 @@ issue_2597: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2666: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
return a = {
|
||||
p: function() {
|
||||
return a;
|
||||
}
|
||||
};
|
||||
}
|
||||
console.log(typeof f().p());
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
return a = {
|
||||
p: function() {
|
||||
return a;
|
||||
}
|
||||
};
|
||||
}
|
||||
console.log(typeof f().p());
|
||||
}
|
||||
expect_stdout: "object"
|
||||
}
|
||||
|
||||
issue_2692: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
reduce_vars: false,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
return a = g;
|
||||
function g() {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
console.log(typeof f()());
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
return a = g;
|
||||
function g() {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
console.log(typeof f()());
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
issue_2701: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
inline: false,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
return a = function() {
|
||||
return function() {
|
||||
return a;
|
||||
};
|
||||
}();
|
||||
}
|
||||
console.log(typeof f()());
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
return a = function() {
|
||||
return function() {
|
||||
return a;
|
||||
};
|
||||
}();
|
||||
}
|
||||
console.log(typeof f()());
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
@@ -1413,3 +1413,234 @@ issue_2516_2: {
|
||||
Baz(2);
|
||||
}
|
||||
}
|
||||
|
||||
defun_lambda_same_name: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(n) {
|
||||
return n ? n * f(n - 1) : 1;
|
||||
}
|
||||
console.log(function f(n) {
|
||||
return n ? n * f(n - 1) : 1;
|
||||
}(5));
|
||||
}
|
||||
expect: {
|
||||
console.log(function f(n) {
|
||||
return n ? n * f(n - 1) : 1;
|
||||
}(5));
|
||||
}
|
||||
expect_stdout: "120"
|
||||
}
|
||||
|
||||
issue_2660_1: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 2;
|
||||
function f(b) {
|
||||
return b && f() || a--;
|
||||
}
|
||||
f(1);
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 2;
|
||||
(function f(b) {
|
||||
return b && f() || a--;
|
||||
})(1);
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_2660_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
function f(b) {
|
||||
b && f();
|
||||
--a, a.toString();
|
||||
}
|
||||
f();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 1;
|
||||
(function f(b) {
|
||||
b && f(),
|
||||
(--a).toString();
|
||||
})(),
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "0"
|
||||
}
|
||||
|
||||
issue_2665: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
keep_fargs: false,
|
||||
passes: 2,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
typeofs: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
function g() {
|
||||
a-- && g();
|
||||
}
|
||||
typeof h == "function" && h();
|
||||
function h() {
|
||||
typeof g == "function" && g();
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 1;
|
||||
!function g() {
|
||||
a-- && g();
|
||||
}();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "-1"
|
||||
}
|
||||
|
||||
double_assign_1: {
|
||||
options = {
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f1() {
|
||||
var a = {};
|
||||
var a = [];
|
||||
return a;
|
||||
}
|
||||
function f2() {
|
||||
var a = {};
|
||||
a = [];
|
||||
return a;
|
||||
}
|
||||
function f3() {
|
||||
a = {};
|
||||
var a = [];
|
||||
return a;
|
||||
}
|
||||
function f4(a) {
|
||||
a = {};
|
||||
a = [];
|
||||
return a;
|
||||
}
|
||||
function f5(a) {
|
||||
var a = {};
|
||||
a = [];
|
||||
return a;
|
||||
}
|
||||
function f6(a) {
|
||||
a = {};
|
||||
var a = [];
|
||||
return a;
|
||||
}
|
||||
console.log(f1(), f2(), f3(), f4(), f5(), f6());
|
||||
}
|
||||
expect: {
|
||||
function f1() {
|
||||
return [];
|
||||
}
|
||||
function f2() {
|
||||
var a;
|
||||
a = [];
|
||||
return a;
|
||||
}
|
||||
function f3() {
|
||||
return [];
|
||||
}
|
||||
function f4(a) {
|
||||
a = [];
|
||||
return a;
|
||||
}
|
||||
function f5(a) {
|
||||
a = [];
|
||||
return a;
|
||||
}
|
||||
function f6(a) {
|
||||
a = [];
|
||||
return a;
|
||||
}
|
||||
console.log(f1(), f2(), f3(), f4(), f5(), f6());
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
double_assign_2: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
for (var i = 0; i < 2; i++)
|
||||
a = void 0, a = {}, console.log(a);
|
||||
var a;
|
||||
}
|
||||
expect: {
|
||||
for (var i = 0; i < 2; i++)
|
||||
void 0, a = {}, console.log(a);
|
||||
var a;
|
||||
}
|
||||
}
|
||||
|
||||
double_assign_3: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
for (var i = 0; i < 2; i++)
|
||||
a = void 0, a = { a: a }, console.log(a);
|
||||
var a;
|
||||
}
|
||||
expect: {
|
||||
for (var i = 0; i < 2; i++)
|
||||
a = void 0, a = { a: a }, console.log(a);
|
||||
var a;
|
||||
}
|
||||
}
|
||||
|
||||
cascade_drop_assign: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a, b = a = "PASS";
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
var b = "PASS";
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -214,46 +214,6 @@ hoist_funs: {
|
||||
node_version: "<=4"
|
||||
}
|
||||
|
||||
hoist_funs_strict: {
|
||||
options = {
|
||||
hoist_funs: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
console.log(1, typeof f, typeof g);
|
||||
if (console.log(2, typeof f, typeof g))
|
||||
console.log(3, typeof f, typeof g);
|
||||
else {
|
||||
console.log(4, typeof f, typeof g);
|
||||
function f() {}
|
||||
console.log(5, typeof f, typeof g);
|
||||
}
|
||||
function g() {}
|
||||
console.log(6, typeof f, typeof g);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function g() {}
|
||||
console.log(1, typeof f, typeof g);
|
||||
if (console.log(2, typeof f, typeof g))
|
||||
console.log(3, typeof f, typeof g);
|
||||
else {
|
||||
console.log(4, typeof f, typeof g);
|
||||
function f() {}
|
||||
console.log(5, typeof f, typeof g);
|
||||
}
|
||||
console.log(6, typeof f, typeof g);
|
||||
}
|
||||
expect_stdout: [
|
||||
"1 'undefined' 'function'",
|
||||
"2 'undefined' 'function'",
|
||||
"4 'function' 'function'",
|
||||
"5 'function' 'function'",
|
||||
"6 'undefined' 'function'",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_203: {
|
||||
options = {
|
||||
keep_fargs: false,
|
||||
@@ -800,12 +760,12 @@ issue_2601_1: {
|
||||
expect: {
|
||||
var a = "FAIL";
|
||||
(function() {
|
||||
var b;
|
||||
b = "foo",
|
||||
function(b) {
|
||||
b && b();
|
||||
}(),
|
||||
b && (a = "PASS");
|
||||
var b;
|
||||
})(),
|
||||
console.log(a);
|
||||
}
|
||||
@@ -1285,7 +1245,7 @@ issue_2630_1: {
|
||||
expect: {
|
||||
var c = 0;
|
||||
(function() {
|
||||
while (c++, void (c = 1 + c));
|
||||
while (void (c = 1 + ++c));
|
||||
})(),
|
||||
console.log(c);
|
||||
}
|
||||
@@ -1299,6 +1259,7 @@ issue_2630_2: {
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
@@ -1316,7 +1277,7 @@ issue_2630_2: {
|
||||
expect: {
|
||||
var c = 0;
|
||||
!function() {
|
||||
while (c += 1, void (c = 1 + c));
|
||||
while (void (c = 1 + (c += 1)));
|
||||
}(), console.log(c);
|
||||
}
|
||||
expect_stdout: "2"
|
||||
@@ -1345,11 +1306,10 @@ issue_2630_3: {
|
||||
expect: {
|
||||
var x = 2, a = 1;
|
||||
(function() {
|
||||
function f1(a) {
|
||||
(function f1(a) {
|
||||
f2();
|
||||
--x >= 0 && f1({});
|
||||
}
|
||||
f1(a++);
|
||||
})(a++);
|
||||
function f2() {
|
||||
a++;
|
||||
}
|
||||
@@ -1417,14 +1377,14 @@ issue_2630_5: {
|
||||
!function() {
|
||||
do {
|
||||
c *= 10;
|
||||
} while (c += 3, (c = 2 + c) < 100);
|
||||
} while ((c = 2 + (c += 3)) < 100);
|
||||
}();
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "155"
|
||||
}
|
||||
|
||||
recursive_inline: {
|
||||
recursive_inline_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
@@ -1447,3 +1407,547 @@ recursive_inline: {
|
||||
}
|
||||
expect: {}
|
||||
}
|
||||
|
||||
recursive_inline_2: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(n) {
|
||||
return n ? n * f(n - 1) : 1;
|
||||
}
|
||||
console.log(f(5));
|
||||
}
|
||||
expect: {
|
||||
console.log(function f(n) {
|
||||
return n ? n * f(n - 1) : 1;
|
||||
}(5));
|
||||
}
|
||||
expect_stdout: "120"
|
||||
}
|
||||
|
||||
issue_2657: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
console.log(function f() {
|
||||
return h;
|
||||
function g(b) {
|
||||
return b || b();
|
||||
}
|
||||
function h(a) {
|
||||
g(a);
|
||||
return a;
|
||||
}
|
||||
}()(42));
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(function(a) {
|
||||
return b = a, b || b(), a;
|
||||
var b;
|
||||
}(42));
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_2663_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
var i, o = {};
|
||||
function createFn(j) {
|
||||
return function() {
|
||||
console.log(j);
|
||||
};
|
||||
}
|
||||
for (i in { a: 1, b: 2, c: 3 })
|
||||
o[i] = createFn(i);
|
||||
for (i in o)
|
||||
o[i]();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
var i, o = {};
|
||||
function createFn(j) {
|
||||
return function() {
|
||||
console.log(j);
|
||||
};
|
||||
}
|
||||
for (i in { a: 1, b: 2, c: 3 })
|
||||
o[i] = createFn(i);
|
||||
for (i in o)
|
||||
o[i]();
|
||||
})();
|
||||
}
|
||||
expect_stdout: [
|
||||
"a",
|
||||
"b",
|
||||
"c",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2663_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
var i;
|
||||
function fn(j) {
|
||||
return function() {
|
||||
console.log(j);
|
||||
}();
|
||||
}
|
||||
for (i in { a: 1, b: 2, c: 3 })
|
||||
fn(i);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
var i;
|
||||
for (i in { a: 1, b: 2, c: 3 })
|
||||
j = i, console.log(j);
|
||||
var j;
|
||||
})();
|
||||
}
|
||||
expect_stdout: [
|
||||
"a",
|
||||
"b",
|
||||
"c",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2663_3: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function () {
|
||||
var outputs = [
|
||||
{ type: 0, target: null, eventName: "ngSubmit", propName: null },
|
||||
{ type: 0, target: null, eventName: "submit", propName: null },
|
||||
{ type: 0, target: null, eventName: "reset", propName: null },
|
||||
];
|
||||
function listenToElementOutputs(outputs) {
|
||||
var handlers = [];
|
||||
for (var i = 0; i < outputs.length; i++) {
|
||||
var output = outputs[i];
|
||||
var handleEventClosure = renderEventHandlerClosure(output.eventName);
|
||||
handlers.push(handleEventClosure)
|
||||
}
|
||||
var target, name;
|
||||
return handlers;
|
||||
}
|
||||
function renderEventHandlerClosure(eventName) {
|
||||
return function () {
|
||||
return console.log(eventName);
|
||||
};
|
||||
}
|
||||
listenToElementOutputs(outputs).forEach(function (handler) {
|
||||
return handler()
|
||||
});
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
function renderEventHandlerClosure(eventName) {
|
||||
return function() {
|
||||
return console.log(eventName);
|
||||
};
|
||||
}
|
||||
(function(outputs) {
|
||||
var handlers = [];
|
||||
for (var i = 0; i < outputs.length; i++) {
|
||||
var output = outputs[i];
|
||||
var handleEventClosure = renderEventHandlerClosure(output.eventName);
|
||||
handlers.push(handleEventClosure);
|
||||
}
|
||||
return handlers;
|
||||
})([ {
|
||||
type: 0,
|
||||
target: null,
|
||||
eventName: "ngSubmit",
|
||||
propName: null
|
||||
}, {
|
||||
type: 0,
|
||||
target: null,
|
||||
eventName: "submit",
|
||||
propName: null
|
||||
}, {
|
||||
type: 0,
|
||||
target: null,
|
||||
eventName: "reset",
|
||||
propName: null
|
||||
} ]).forEach(function(handler) {
|
||||
return handler();
|
||||
});
|
||||
})();
|
||||
}
|
||||
expect_stdout: [
|
||||
"ngSubmit",
|
||||
"submit",
|
||||
"reset",
|
||||
]
|
||||
}
|
||||
|
||||
duplicate_argnames: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
function f(b, b, b) {
|
||||
b && (a = "FAIL");
|
||||
}
|
||||
f(0, console);
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
console, b && (a = "FAIL");
|
||||
var b;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
loop_init_arg: {
|
||||
options = {
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
for (var k in "12") (function (b) {
|
||||
(b >>= 1) && (a = "FAIL"), b = 2;
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
for (var k in "12")
|
||||
b = void 0, (b >>= 1) && (a = "FAIL"), b = 2;
|
||||
var b;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
inline_false: {
|
||||
options = {
|
||||
inline: false,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
console.log(1);
|
||||
})();
|
||||
(function(a) {
|
||||
console.log(a);
|
||||
})(2);
|
||||
(function(b) {
|
||||
var c = b;
|
||||
console.log(c);
|
||||
})(3);
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
console.log(1);
|
||||
})();
|
||||
(function(a) {
|
||||
console.log(a);
|
||||
})(2);
|
||||
(function(b) {
|
||||
var c = b;
|
||||
console.log(c);
|
||||
})(3);
|
||||
}
|
||||
expect_stdout: [
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
]
|
||||
}
|
||||
|
||||
inline_0: {
|
||||
options = {
|
||||
inline: 0,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
console.log(1);
|
||||
})();
|
||||
(function(a) {
|
||||
console.log(a);
|
||||
})(2);
|
||||
(function(b) {
|
||||
var c = b;
|
||||
console.log(c);
|
||||
})(3);
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
console.log(1);
|
||||
})();
|
||||
(function(a) {
|
||||
console.log(a);
|
||||
})(2);
|
||||
(function(b) {
|
||||
var c = b;
|
||||
console.log(c);
|
||||
})(3);
|
||||
}
|
||||
expect_stdout: [
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
]
|
||||
}
|
||||
|
||||
inline_1: {
|
||||
options = {
|
||||
inline: 1,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
console.log(1);
|
||||
})();
|
||||
(function(a) {
|
||||
console.log(a);
|
||||
})(2);
|
||||
(function(b) {
|
||||
var c = b;
|
||||
console.log(c);
|
||||
})(3);
|
||||
}
|
||||
expect: {
|
||||
console.log(1);
|
||||
(function(a) {
|
||||
console.log(a);
|
||||
})(2);
|
||||
(function(b) {
|
||||
var c = b;
|
||||
console.log(c);
|
||||
})(3);
|
||||
}
|
||||
expect_stdout: [
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
]
|
||||
}
|
||||
|
||||
inline_2: {
|
||||
options = {
|
||||
inline: 2,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
console.log(1);
|
||||
})();
|
||||
(function(a) {
|
||||
console.log(a);
|
||||
})(2);
|
||||
(function(b) {
|
||||
var c = b;
|
||||
console.log(c);
|
||||
})(3);
|
||||
}
|
||||
expect: {
|
||||
console.log(1);
|
||||
a = 2, console.log(a);
|
||||
var a;
|
||||
(function(b) {
|
||||
var c = b;
|
||||
console.log(c);
|
||||
})(3);
|
||||
}
|
||||
expect_stdout: [
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
]
|
||||
}
|
||||
|
||||
inline_3: {
|
||||
options = {
|
||||
inline: 3,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
console.log(1);
|
||||
})();
|
||||
(function(a) {
|
||||
console.log(a);
|
||||
})(2);
|
||||
(function(b) {
|
||||
var c = b;
|
||||
console.log(c);
|
||||
})(3);
|
||||
}
|
||||
expect: {
|
||||
console.log(1);
|
||||
a = 2, console.log(a);
|
||||
var a;
|
||||
b = 3, c = b, console.log(c);
|
||||
var b, c;
|
||||
}
|
||||
expect_stdout: [
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
]
|
||||
}
|
||||
|
||||
inline_true: {
|
||||
options = {
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
console.log(1);
|
||||
})();
|
||||
(function(a) {
|
||||
console.log(a);
|
||||
})(2);
|
||||
(function(b) {
|
||||
var c = b;
|
||||
console.log(c);
|
||||
})(3);
|
||||
}
|
||||
expect: {
|
||||
console.log(1);
|
||||
a = 2, console.log(a);
|
||||
var a;
|
||||
b = 3, c = b, console.log(c);
|
||||
var b, c;
|
||||
}
|
||||
expect_stdout: [
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
]
|
||||
}
|
||||
|
||||
use_before_init_in_loop: {
|
||||
options = {
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
for (var b = 2; --b >= 0;) (function() {
|
||||
var c = function() {
|
||||
return 1;
|
||||
}(c && (a = "FAIL"));
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
for (var b = 2; --b >= 0;)
|
||||
c = void 0, c = (c && (a = "FAIL"), 1);
|
||||
var c;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
duplicate_arg_var: {
|
||||
options = {
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(b) {
|
||||
return b;
|
||||
var b;
|
||||
}("PASS"));
|
||||
}
|
||||
expect: {
|
||||
console.log((b = "PASS", b));
|
||||
var b;
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2737_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(a) {
|
||||
while (a());
|
||||
})(function f() {
|
||||
console.log(typeof f);
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
(function(a) {
|
||||
while (a());
|
||||
})(function f() {
|
||||
console.log(typeof f);
|
||||
});
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
issue_2737_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(bar) {
|
||||
for (;bar(); ) break;
|
||||
})(function qux() {
|
||||
return console.log("PASS"), qux;
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
(function(bar) {
|
||||
for (;bar(); ) break;
|
||||
})(function qux() {
|
||||
return console.log("PASS"), qux;
|
||||
});
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -326,3 +326,73 @@ issue_512: {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if_var_return: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var a;
|
||||
return;
|
||||
var b;
|
||||
}
|
||||
function g() {
|
||||
var a;
|
||||
if (u()) {
|
||||
var b;
|
||||
return v();
|
||||
var c;
|
||||
}
|
||||
var d;
|
||||
if (w()) {
|
||||
var e;
|
||||
return x();
|
||||
var f;
|
||||
} else {
|
||||
var g;
|
||||
y();
|
||||
var h;
|
||||
}
|
||||
var i;
|
||||
z();
|
||||
var j;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
var a, b;
|
||||
}
|
||||
function g() {
|
||||
var a, b, c, d, e, f, g, h, i, j;
|
||||
return u() ? v() : w() ? x() : (y(), z(), void 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if_if_return_return: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
if (a) {
|
||||
if (b)
|
||||
return b;
|
||||
return;
|
||||
}
|
||||
g();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
if (a)
|
||||
return b || void 0;
|
||||
g();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
33
test/compress/issue-2652.js
Normal file
33
test/compress/issue-2652.js
Normal file
@@ -0,0 +1,33 @@
|
||||
insert_semicolon: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
var a
|
||||
/* foo */ var b
|
||||
}
|
||||
expect_exact: [
|
||||
"var a",
|
||||
"/* foo */;",
|
||||
"",
|
||||
"var b;",
|
||||
]
|
||||
}
|
||||
|
||||
unary_postfix: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
a
|
||||
/* foo */++b
|
||||
}
|
||||
expect_exact: [
|
||||
"a",
|
||||
"/* foo */;",
|
||||
"",
|
||||
"++b;",
|
||||
]
|
||||
}
|
||||
@@ -64,3 +64,27 @@ strings_concat: {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
regexp: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
RegExp("foo");
|
||||
RegExp("bar", "ig");
|
||||
RegExp(foo);
|
||||
RegExp("bar", ig);
|
||||
RegExp("should", "fail");
|
||||
}
|
||||
expect: {
|
||||
/foo/;
|
||||
/bar/ig;
|
||||
RegExp(foo);
|
||||
RegExp("bar", ig);
|
||||
RegExp("should", "fail");
|
||||
}
|
||||
expect_warnings: [
|
||||
'WARN: Error converting RegExp("should","fail") [test/compress/issue-269.js:78,2]',
|
||||
]
|
||||
}
|
||||
|
||||
32
test/compress/issue-2719.js
Normal file
32
test/compress/issue-2719.js
Normal file
@@ -0,0 +1,32 @@
|
||||
warn: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
properties: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
return g();
|
||||
}
|
||||
function g() {
|
||||
return g["call" + "er"].arguments;
|
||||
}
|
||||
// 3
|
||||
console.log(f(1, 2, 3).length);
|
||||
}
|
||||
expect: {
|
||||
// TypeError: Cannot read property 'arguments' of null
|
||||
console.log(function g() {
|
||||
return g.caller.arguments;
|
||||
}().length);
|
||||
}
|
||||
expect_warnings: [
|
||||
"WARN: Function.protoype.caller not supported [test/compress/issue-2719.js:17,19]",
|
||||
"WARN: Function.protoype.arguments not supported [test/compress/issue-2719.js:17,19]",
|
||||
]
|
||||
}
|
||||
@@ -567,12 +567,18 @@ native_prototype: {
|
||||
}
|
||||
input: {
|
||||
Array.prototype.splice.apply(a, [1, 2, b, c]);
|
||||
Function.prototype.call.apply(console.log, console, [ "foo" ]);
|
||||
Number.prototype.toFixed.call(Math.PI, 2);
|
||||
Object.prototype.hasOwnProperty.call(d, "foo");
|
||||
RegExp.prototype.test.call(/foo/, "bar");
|
||||
String.prototype.indexOf.call(e, "bar");
|
||||
}
|
||||
expect: {
|
||||
[].splice.apply(a, [1, 2, b, c]);
|
||||
(function() {}).call.apply(console.log, console, [ "foo" ]);
|
||||
0..toFixed.call(Math.PI, 2);
|
||||
({}).hasOwnProperty.call(d, "foo");
|
||||
/t/.test.call(/foo/, "bar");
|
||||
"".indexOf.call(e, "bar");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -414,3 +414,124 @@ issue_2638: {
|
||||
"/* */(a()||b())(c(),d());",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2705_1: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/ new a();
|
||||
/*@__PURE__*/ (new b());
|
||||
new (/*@__PURE__*/ c)();
|
||||
(/*@__PURE__*/ new d());
|
||||
}
|
||||
expect_exact: [
|
||||
"new/* */c;",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2705_2: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/ new a(1)(2)(3);
|
||||
/*@__PURE__*/ new (b(1))(2)(3);
|
||||
/*@__PURE__*/ new (c(1)(2))(3);
|
||||
/*@__PURE__*/ new (d(1)(2)(3));
|
||||
new (/*@__PURE__*/ e)(1)(2)(3);
|
||||
(/*@__PURE__*/ new f(1))(2)(3);
|
||||
(/*@__PURE__*/ new g(1)(2))(3);
|
||||
(/*@__PURE__*/ new h(1)(2)(3));
|
||||
}
|
||||
expect_exact: [
|
||||
"new/* */e(1)(2)(3);",
|
||||
"/* */new f(1)(2)(3);",
|
||||
"/* */new g(1)(2)(3);",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2705_3: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/ new a.x(1).y(2).z(3);
|
||||
/*@__PURE__*/ new (b.x)(1).y(2).z(3);
|
||||
/*@__PURE__*/ new (c.x(1)).y(2).z(3);
|
||||
/*@__PURE__*/ new (d.x(1).y)(2).z(3);
|
||||
/*@__PURE__*/ new (e.x(1).y(2)).z(3);
|
||||
/*@__PURE__*/ new (f.x(1).y(2).z)(3);
|
||||
/*@__PURE__*/ new (g.x(1).y(2).z(3));
|
||||
new (/*@__PURE__*/ h).x(1).y(2).z(3);
|
||||
/* */ new (/*@__PURE__*/ i.x)(1).y(2).z(3);
|
||||
(/*@__PURE__*/ new j.x(1)).y(2).z(3);
|
||||
(/*@__PURE__*/ new k.x(1).y)(2).z(3);
|
||||
(/*@__PURE__*/ new l.x(1).y(2)).z(3);
|
||||
(/*@__PURE__*/ new m.x(1).y(2).z)(3);
|
||||
(/*@__PURE__*/ new n.x(1).y(2).z(3));
|
||||
}
|
||||
expect_exact: [
|
||||
"new/* */h.x(1).y(2).z(3);",
|
||||
"/* */new/* */i.x(1).y(2).z(3);",
|
||||
"/* */new j.x(1).y(2).z(3);",
|
||||
"/* */new k.x(1).y(2).z(3);",
|
||||
"/* */new l.x(1).y(2).z(3);",
|
||||
"/* */new m.x(1).y(2).z(3);",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2705_4: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(/*@__PURE__*/ new x(), y());
|
||||
(w(), /*@__PURE__*/ new x(), y());
|
||||
}
|
||||
expect: {
|
||||
y();
|
||||
w(), y();
|
||||
}
|
||||
}
|
||||
|
||||
issue_2705_5: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
[ /*@__PURE__*/ new x() ];
|
||||
[ /*@__PURE__*/ new x(), y() ];
|
||||
[ w(), /*@__PURE__*/ new x(), y() ];
|
||||
}
|
||||
expect: {
|
||||
y();
|
||||
w(), y();
|
||||
}
|
||||
}
|
||||
|
||||
issue_2705_6: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/new (g() || h())(x(), y());
|
||||
/* */ new (/*@__PURE__*/ (a() || b()))(c(), d());
|
||||
}
|
||||
expect_exact: [
|
||||
"/* */x(),y();",
|
||||
"/* */new(/* */a()||b())(c(),d());",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -348,6 +348,57 @@ set_immutable_4: {
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
set_immutable_5: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
pure_getters: "strict",
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a = 1;
|
||||
a.foo += "";
|
||||
if (a.foo) console.log("FAIL");
|
||||
else console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
1..foo += "";
|
||||
1..foo ? console.log("FAIL") : console.log("PASS");
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
set_immutable_6: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
pure_getters: "strict",
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
a.foo += "";
|
||||
if (a.foo) console.log("FAIL");
|
||||
else console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
1..foo ? console.log("FAIL") : console.log("PASS");
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
set_mutable_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
@@ -611,3 +662,35 @@ issue_2313_6: {
|
||||
x();
|
||||
}
|
||||
}
|
||||
|
||||
issue_2678: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1, c = "FAIL";
|
||||
(function f() {
|
||||
(a-- && f()).p;
|
||||
return {
|
||||
get p() {
|
||||
c = "PASS";
|
||||
}
|
||||
};
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var a = 1, c = "FAIL";
|
||||
(function f() {
|
||||
(a-- && f()).p;
|
||||
return {
|
||||
get p() {
|
||||
c = "PASS";
|
||||
}
|
||||
};
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -299,7 +299,7 @@ unsafe_evaluate_modified: {
|
||||
console.log(function(){ var o={p:1}; o.p++; console.log(o.p); return o.p; }());
|
||||
console.log(function(){ var o={p:2}; --o.p; console.log(o.p); return o.p; }());
|
||||
console.log(function(){ var o={p:3}; o.p += ""; console.log(o.p); return o.p; }());
|
||||
console.log(function(){ var o={p:4}; o = {}; console.log(o.p); return o.p; }());
|
||||
console.log(function(){ var o; o = {}; console.log(o.p); return o.p; }());
|
||||
console.log(function(){ var o={p:5}; o.p = -9; console.log(o.p); return o.p; }());
|
||||
function inc() { this.p++; }
|
||||
console.log(function(){ var o={p:6}; inc.call(o); console.log(o.p); return o.p; }());
|
||||
@@ -1355,10 +1355,9 @@ defun_inline_1: {
|
||||
function f() {
|
||||
return function(b) {
|
||||
return b;
|
||||
}(2) + h();
|
||||
function h() {
|
||||
}(2) + function h() {
|
||||
return h();
|
||||
}
|
||||
}();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1382,12 +1381,11 @@ defun_inline_2: {
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
function h() {
|
||||
return h();
|
||||
}
|
||||
return function(b) {
|
||||
return b;
|
||||
}(2) + h();
|
||||
}(2) + function h() {
|
||||
return h();
|
||||
}();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2314,8 +2312,7 @@ delay_def: {
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
return a;
|
||||
var a;
|
||||
return;
|
||||
}
|
||||
function g() {
|
||||
return a;
|
||||
@@ -2326,6 +2323,28 @@ delay_def: {
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
delay_def_lhs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
long_name++;
|
||||
return long_name;
|
||||
var long_name;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
long_name++;
|
||||
return long_name;
|
||||
var long_name;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "NaN"
|
||||
}
|
||||
|
||||
booleans: {
|
||||
options = {
|
||||
booleans: true,
|
||||
@@ -4954,3 +4973,306 @@ issue_2598: {
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
var_if: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
if (x()) {
|
||||
var a;
|
||||
if (!g) a = true;
|
||||
if (a) g();
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
if (x()) {
|
||||
var a;
|
||||
if (!g) a = true;
|
||||
if (a) g();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defun_assign: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof a);
|
||||
a = 42;
|
||||
console.log(typeof a);
|
||||
function a() {}
|
||||
console.log(typeof a);
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof a);
|
||||
a = 42;
|
||||
console.log(typeof a);
|
||||
function a() {}
|
||||
console.log(typeof a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"function",
|
||||
"number",
|
||||
"number",
|
||||
]
|
||||
}
|
||||
|
||||
defun_var_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
typeofs: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 42, b;
|
||||
function a() {}
|
||||
function b() {}
|
||||
console.log(typeof a, typeof b);
|
||||
}
|
||||
expect: {
|
||||
var a = 42;
|
||||
function a() {}
|
||||
console.log(typeof a, "function");
|
||||
}
|
||||
expect_stdout: "number function"
|
||||
}
|
||||
|
||||
defun_var_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
typeofs: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function a() {}
|
||||
function b() {}
|
||||
var a = 42, b;
|
||||
console.log(typeof a, typeof b);
|
||||
}
|
||||
expect: {
|
||||
function a() {}
|
||||
var a = 42;
|
||||
console.log(typeof a, "function");
|
||||
}
|
||||
expect_stdout: "number function"
|
||||
}
|
||||
|
||||
defun_var_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
typeofs: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function a() {}
|
||||
function b() {}
|
||||
console.log(typeof a, typeof b);
|
||||
var a = 42, b;
|
||||
}
|
||||
expect: {
|
||||
function a() {}
|
||||
console.log(typeof a, "function");
|
||||
var a = 42;
|
||||
}
|
||||
expect_stdout: "function function"
|
||||
}
|
||||
|
||||
defun_catch_1: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function a() {}
|
||||
try {
|
||||
throw 42;
|
||||
} catch (a) {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
throw 42;
|
||||
} catch (a) {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
defun_catch_2: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
function a() {}
|
||||
throw 42;
|
||||
} catch (a) {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
throw 42;
|
||||
} catch (a) {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
defun_catch_3: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
throw 42;
|
||||
function a() {}
|
||||
} catch (a) {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
throw 42;
|
||||
} catch (a) {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
defun_catch_4: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
throw 42;
|
||||
} catch (a) {
|
||||
function a() {}
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
throw 42;
|
||||
} catch (a) {
|
||||
function a() {}
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
defun_catch_5: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
throw 42;
|
||||
} catch (a) {
|
||||
console.log(a);
|
||||
function a() {}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
throw 42;
|
||||
} catch (a) {
|
||||
console.log(a);
|
||||
function a() {}
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
defun_catch_6: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
throw 42;
|
||||
} catch (a) {
|
||||
console.log(a);
|
||||
}
|
||||
function a() {}
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
throw 42;
|
||||
} catch (a) {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
duplicate_lambda_defun_name_1: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function f(a) {
|
||||
function f() {}
|
||||
return f.length;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function f(a) {
|
||||
function f() {}
|
||||
return f.length;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "0"
|
||||
}
|
||||
|
||||
duplicate_lambda_defun_name_2: {
|
||||
options = {
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function f(a) {
|
||||
function f() {}
|
||||
return f.length;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
return function() {}.length;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "0"
|
||||
}
|
||||
|
||||
@@ -796,3 +796,66 @@ cascade_assignment_in_return: {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hoist_defun: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
x();
|
||||
function f() {}
|
||||
y();
|
||||
}
|
||||
expect: {
|
||||
function f() {}
|
||||
x(), y();
|
||||
}
|
||||
}
|
||||
|
||||
hoist_decl: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
w();
|
||||
var b = x();
|
||||
y();
|
||||
for (var c; 0;) z();
|
||||
var d;
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
w();
|
||||
var b = x(), c, d;
|
||||
for (y(); 0;) z();
|
||||
}
|
||||
}
|
||||
|
||||
for_init_var: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
unused: false,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
(function() {
|
||||
var b = 42;
|
||||
for (var c = 5; c > 0;) c--;
|
||||
a = "FAIL";
|
||||
var a;
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
(function() {
|
||||
for (var b = 42, c = 5, a; c > 0;) c--;
|
||||
a = "FAIL";
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ typeof_defun_1: {
|
||||
g = 42;
|
||||
console.log("YES");
|
||||
"function" == typeof g && g();
|
||||
h();
|
||||
"function" == typeof h && h();
|
||||
}
|
||||
expect_stdout: [
|
||||
"YES",
|
||||
@@ -138,3 +138,166 @@ typeof_defun_2: {
|
||||
"2",
|
||||
]
|
||||
}
|
||||
|
||||
duplicate_defun_arg_name: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
function long_name(long_name) {
|
||||
return typeof long_name;
|
||||
}
|
||||
console.log(typeof long_name, long_name());
|
||||
}
|
||||
expect: {
|
||||
function long_name(long_name) {
|
||||
return typeof long_name;
|
||||
}
|
||||
console.log(typeof long_name, long_name());
|
||||
}
|
||||
expect_stdout: "function undefined"
|
||||
}
|
||||
|
||||
duplicate_lambda_arg_name: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function long_name(long_name) {
|
||||
return typeof long_name;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function long_name(long_name) {
|
||||
return typeof long_name;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_2728_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
(function arguments() {
|
||||
console.log(typeof arguments);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function arguments() {
|
||||
console.log(typeof arguments);
|
||||
})();
|
||||
}
|
||||
expect_stdout: "object"
|
||||
}
|
||||
|
||||
issue_2728_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
function arguments() {
|
||||
return typeof arguments;
|
||||
}
|
||||
console.log(typeof arguments, arguments());
|
||||
}
|
||||
expect: {
|
||||
function arguments() {
|
||||
return typeof arguments;
|
||||
}
|
||||
console.log(typeof arguments, arguments());
|
||||
}
|
||||
expect_stdout: "function object"
|
||||
}
|
||||
|
||||
issue_2728_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
function arguments() {
|
||||
}
|
||||
console.log(typeof arguments);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
function arguments() {
|
||||
}
|
||||
console.log("function");
|
||||
})();
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
issue_2728_4: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
function arguments() {
|
||||
}
|
||||
console.log(typeof arguments);
|
||||
}
|
||||
expect: {
|
||||
function arguments() {
|
||||
}
|
||||
console.log("function");
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
issue_2728_5: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
(function arguments(arguments) {
|
||||
console.log(typeof arguments);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function arguments(arguments) {
|
||||
console.log(typeof arguments);
|
||||
})();
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_2728_6: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
function arguments(arguments) {
|
||||
return typeof arguments;
|
||||
}
|
||||
console.log(typeof arguments, arguments());
|
||||
}
|
||||
expect: {
|
||||
function arguments(arguments) {
|
||||
return typeof arguments;
|
||||
}
|
||||
console.log(typeof arguments, arguments());
|
||||
}
|
||||
expect_stdout: "function undefined"
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
var a = bar(1+2);
|
||||
var b = baz(3+9);
|
||||
print('q' + 'u' + 'x', a, b);
|
||||
var x = bar(1+2);
|
||||
var y = baz(3+9);
|
||||
print('q' + 'u' + 'x', x, y);
|
||||
foo(5+6);
|
||||
|
||||
@@ -5,11 +5,7 @@
|
||||
|
||||
var site = "http://browserbench.org/JetStream";
|
||||
if (typeof phantom == "undefined") {
|
||||
// workaround for tty output truncation upon process.exit()
|
||||
[process.stdout, process.stderr].forEach(function(stream){
|
||||
if (stream._handle && stream._handle.setBlocking)
|
||||
stream._handle.setBlocking(true);
|
||||
});
|
||||
require("../tools/exit");
|
||||
var args = process.argv.slice(2);
|
||||
var debug = args.indexOf("--debug");
|
||||
if (debug >= 0) {
|
||||
|
||||
@@ -219,4 +219,24 @@ describe("Comment", function() {
|
||||
if (result.error) throw result.error;
|
||||
assert.strictEqual(result.code, "/*a*/ /*b*/(function(){/*c*/}/*d*/ /*e*/)();");
|
||||
});
|
||||
|
||||
it("Should output line comments after statements", function() {
|
||||
var result = uglify.minify([
|
||||
"x()//foo",
|
||||
"{y()//bar",
|
||||
"}",
|
||||
].join("\n"), {
|
||||
compress: false,
|
||||
mangle: false,
|
||||
output: {
|
||||
comments: "all",
|
||||
},
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
assert.strictEqual(result.code, [
|
||||
"x();//foo",
|
||||
"{y();//bar",
|
||||
"}",
|
||||
].join("\n"));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -42,8 +42,15 @@ describe("minify", function() {
|
||||
original += code;
|
||||
compressed += result.code;
|
||||
});
|
||||
assert.strictEqual(JSON.stringify(cache).slice(0, 20), '{"cname":5,"props":{');
|
||||
assert.strictEqual(compressed, 'function n(n){return 3*n}function r(n){return n/2}var c=console.log.bind(console);function l(o){c("Foo:",2*o)}var f=n(3),i=r(12);c("qux",f,i),l(11);');
|
||||
assert.strictEqual(JSON.stringify(cache).slice(0, 10), '{"props":{');
|
||||
assert.strictEqual(compressed, [
|
||||
"function n(n){return 3*n}",
|
||||
"function r(n){return n/2}",
|
||||
"var o=console.log.bind(console);",
|
||||
'function c(n){o("Foo:",2*n)}',
|
||||
"var a=n(3),b=r(12);",
|
||||
'o("qux",a,b),c(11);',
|
||||
].join(""));
|
||||
assert.strictEqual(run_code(compressed), run_code(original));
|
||||
});
|
||||
|
||||
@@ -68,12 +75,48 @@ describe("minify", function() {
|
||||
original += code;
|
||||
compressed += result.code;
|
||||
});
|
||||
assert.strictEqual(JSON.stringify(cache).slice(0, 28), '{"vars":{"cname":5,"props":{');
|
||||
assert.strictEqual(compressed, 'function n(n){return 3*n}function r(n){return n/2}var c=console.log.bind(console);function l(o){c("Foo:",2*o)}var f=n(3),i=r(12);c("qux",f,i),l(11);');
|
||||
assert.strictEqual(JSON.stringify(cache).slice(0, 18), '{"vars":{"props":{');
|
||||
assert.strictEqual(compressed, [
|
||||
"function n(n){return 3*n}",
|
||||
"function r(n){return n/2}",
|
||||
"var o=console.log.bind(console);",
|
||||
'function c(n){o("Foo:",2*n)}',
|
||||
"var a=n(3),b=r(12);",
|
||||
'o("qux",a,b),c(11);',
|
||||
].join(""));
|
||||
assert.strictEqual(run_code(compressed), run_code(original));
|
||||
});
|
||||
|
||||
it("should not parse invalid use of reserved words", function() {
|
||||
it("Should avoid mangled names in cache", function() {
|
||||
var cache = {};
|
||||
var original = "";
|
||||
var compressed = "";
|
||||
[
|
||||
'"xxxyy";var i={s:1};',
|
||||
'"xxyyy";var j={t:2,u:3},k=4;',
|
||||
'console.log(i.s,j.t,j.u,k);',
|
||||
].forEach(function(code) {
|
||||
var result = Uglify.minify(code, {
|
||||
compress: false,
|
||||
mangle: {
|
||||
properties: true,
|
||||
toplevel: true
|
||||
},
|
||||
nameCache: cache
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
original += code;
|
||||
compressed += result.code;
|
||||
});
|
||||
assert.strictEqual(compressed, [
|
||||
'"xxxyy";var x={x:1};',
|
||||
'"xxyyy";var y={y:2,a:3},a=4;',
|
||||
'console.log(x.x,y.y,y.a,a);',
|
||||
].join(""));
|
||||
assert.strictEqual(run_code(compressed), run_code(original));
|
||||
});
|
||||
|
||||
it("Should not parse invalid use of reserved words", function() {
|
||||
assert.strictEqual(Uglify.minify("function enum(){}").error, undefined);
|
||||
assert.strictEqual(Uglify.minify("function static(){}").error, undefined);
|
||||
assert.strictEqual(Uglify.minify("function this(){}").error.message, "Unexpected token: name (this)");
|
||||
|
||||
@@ -10,6 +10,7 @@ var semver = require("semver");
|
||||
var tests_dir = path.dirname(module.filename);
|
||||
var failures = 0;
|
||||
var failed_files = {};
|
||||
var minify_options = require("./ufuzz.json").map(JSON.stringify);
|
||||
|
||||
run_compress_tests();
|
||||
if (failures) {
|
||||
@@ -100,6 +101,15 @@ function run_compress_tests() {
|
||||
quote_style: 3,
|
||||
keep_quoted_props: true
|
||||
});
|
||||
try {
|
||||
U.parse(input_code);
|
||||
} catch (ex) {
|
||||
log("!!! Cannot parse input\n---INPUT---\n{input}\n--PARSE ERROR--\n{error}\n\n", {
|
||||
input: input_formatted,
|
||||
error: ex,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
var options = U.defaults(test.options, {
|
||||
warnings: false
|
||||
});
|
||||
@@ -139,78 +149,77 @@ function run_compress_tests() {
|
||||
output: output,
|
||||
expected: expect
|
||||
});
|
||||
failures++;
|
||||
failed_files[file] = 1;
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
// expect == output
|
||||
try {
|
||||
var reparsed_ast = U.parse(output);
|
||||
} catch (ex) {
|
||||
log("!!! Test matched expected result but cannot parse output\n---INPUT---\n{input}\n---OUTPUT---\n{output}\n--REPARSE ERROR--\n{error}\n\n", {
|
||||
// expect == output
|
||||
try {
|
||||
U.parse(output);
|
||||
} catch (ex) {
|
||||
log("!!! Test matched expected result but cannot parse output\n---INPUT---\n{input}\n---OUTPUT---\n{output}\n--REPARSE ERROR--\n{error}\n\n", {
|
||||
input: input_formatted,
|
||||
output: output,
|
||||
error: ex,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (test.expect_warnings) {
|
||||
U.AST_Node.warn_function = original_warn_function;
|
||||
var expected_warnings = make_code(test.expect_warnings, {
|
||||
beautify: false,
|
||||
quote_style: 2, // force double quote to match JSON
|
||||
});
|
||||
warnings_emitted = warnings_emitted.map(function(input) {
|
||||
return input.split(process.cwd() + path.sep).join("").split(path.sep).join("/");
|
||||
});
|
||||
var actual_warnings = JSON.stringify(warnings_emitted);
|
||||
if (expected_warnings != actual_warnings) {
|
||||
log("!!! failed\n---INPUT---\n{input}\n---EXPECTED WARNINGS---\n{expected_warnings}\n---ACTUAL WARNINGS---\n{actual_warnings}\n\n", {
|
||||
input: input_formatted,
|
||||
output: output,
|
||||
error: ex.toString(),
|
||||
expected_warnings: expected_warnings,
|
||||
actual_warnings: actual_warnings,
|
||||
});
|
||||
failures++;
|
||||
failed_files[file] = 1;
|
||||
}
|
||||
if (test.expect_warnings) {
|
||||
U.AST_Node.warn_function = original_warn_function;
|
||||
var expected_warnings = make_code(test.expect_warnings, {
|
||||
beautify: false,
|
||||
quote_style: 2, // force double quote to match JSON
|
||||
});
|
||||
warnings_emitted = warnings_emitted.map(function(input) {
|
||||
return input.split(process.cwd() + path.sep).join("").split(path.sep).join("/");
|
||||
});
|
||||
var actual_warnings = JSON.stringify(warnings_emitted);
|
||||
if (expected_warnings != actual_warnings) {
|
||||
log("!!! failed\n---INPUT---\n{input}\n---EXPECTED WARNINGS---\n{expected_warnings}\n---ACTUAL WARNINGS---\n{actual_warnings}\n\n", {
|
||||
input: input_formatted,
|
||||
expected_warnings: expected_warnings,
|
||||
actual_warnings: actual_warnings,
|
||||
});
|
||||
failures++;
|
||||
failed_files[file] = 1;
|
||||
}
|
||||
}
|
||||
if (test.expect_stdout
|
||||
&& (!test.node_version || semver.satisfies(process.version, test.node_version))) {
|
||||
var stdout = sandbox.run_code(input_code);
|
||||
if (test.expect_stdout === true) {
|
||||
test.expect_stdout = stdout;
|
||||
}
|
||||
if (!sandbox.same_stdout(test.expect_stdout, stdout)) {
|
||||
log("!!! Invalid input or expected stdout\n---INPUT---\n{input}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
|
||||
input: input_formatted,
|
||||
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
|
||||
expected: test.expect_stdout,
|
||||
actual_type: typeof stdout == "string" ? "STDOUT" : "ERROR",
|
||||
actual: stdout,
|
||||
});
|
||||
failures++;
|
||||
failed_files[file] = 1;
|
||||
} else {
|
||||
stdout = sandbox.run_code(output);
|
||||
if (!sandbox.same_stdout(test.expect_stdout, stdout)) {
|
||||
log("!!! failed\n---INPUT---\n{input}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
|
||||
input: input_formatted,
|
||||
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
|
||||
expected: test.expect_stdout,
|
||||
actual_type: typeof stdout == "string" ? "STDOUT" : "ERROR",
|
||||
actual: stdout,
|
||||
});
|
||||
failures++;
|
||||
failed_files[file] = 1;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (test.expect_stdout
|
||||
&& (!test.node_version || semver.satisfies(process.version, test.node_version))) {
|
||||
var stdout = sandbox.run_code(input_code);
|
||||
if (test.expect_stdout === true) {
|
||||
test.expect_stdout = stdout;
|
||||
}
|
||||
if (!sandbox.same_stdout(test.expect_stdout, stdout)) {
|
||||
log("!!! Invalid input or expected stdout\n---INPUT---\n{input}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
|
||||
input: input_formatted,
|
||||
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
|
||||
expected: test.expect_stdout,
|
||||
actual_type: typeof stdout == "string" ? "STDOUT" : "ERROR",
|
||||
actual: stdout,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
stdout = sandbox.run_code(output);
|
||||
if (!sandbox.same_stdout(test.expect_stdout, stdout)) {
|
||||
log("!!! failed\n---INPUT---\n{input}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
|
||||
input: input_formatted,
|
||||
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
|
||||
expected: test.expect_stdout,
|
||||
actual_type: typeof stdout == "string" ? "STDOUT" : "ERROR",
|
||||
actual: stdout,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!reminify(test.options, input_code, input_formatted, test.expect_stdout)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
var tests = parse_test(path.resolve(dir, file));
|
||||
for (var i in tests) if (tests.hasOwnProperty(i)) {
|
||||
test_case(tests[i]);
|
||||
if (!test_case(tests[i])) {
|
||||
failures++;
|
||||
failed_files[file] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
files.forEach(function(file){
|
||||
@@ -346,3 +355,46 @@ function evaluate(code) {
|
||||
code = make_code(code, { beautify: true });
|
||||
return new Function("return(" + code + ")")();
|
||||
}
|
||||
|
||||
// Try to reminify original input with standard options
|
||||
// to see if it matches expect_stdout.
|
||||
function reminify(orig_options, input_code, input_formatted, expect_stdout) {
|
||||
for (var i = 0; i < minify_options.length; i++) {
|
||||
var options = JSON.parse(minify_options[i]);
|
||||
if (options.compress) [
|
||||
"keep_fargs",
|
||||
"keep_fnames",
|
||||
].forEach(function(name) {
|
||||
if (name in orig_options) {
|
||||
options.compress[name] = orig_options[name];
|
||||
}
|
||||
});
|
||||
var options_formatted = JSON.stringify(options, null, 4);
|
||||
var result = U.minify(input_code, options);
|
||||
if (result.error) {
|
||||
log("!!! failed input reminify\n---INPUT---\n{input}\n--ERROR---\n{error}\n\n", {
|
||||
input: input_formatted,
|
||||
error: result.error,
|
||||
});
|
||||
return false;
|
||||
} else {
|
||||
var stdout = sandbox.run_code(result.code);
|
||||
if (typeof expect_stdout != "string" && typeof stdout != "string" && expect_stdout.name == stdout.name) {
|
||||
stdout = expect_stdout;
|
||||
}
|
||||
if (!sandbox.same_stdout(expect_stdout, stdout)) {
|
||||
log("!!! failed running reminified input\n---INPUT---\n{input}\n---OPTIONS---\n{options}\n---OUTPUT---\n{output}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
|
||||
input: input_formatted,
|
||||
options: options_formatted,
|
||||
output: result.code,
|
||||
expected_type: typeof expect_stdout == "string" ? "STDOUT" : "ERROR",
|
||||
expected: expect_stdout,
|
||||
actual_type: typeof stdout == "string" ? "STDOUT" : "ERROR",
|
||||
actual: stdout,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -6,11 +6,7 @@
|
||||
// bin/uglifyjs s.js -c && bin/uglifyjs s.js -c passes=3 && bin/uglifyjs s.js -c passes=3 -m
|
||||
// cat s.js | node && node s.js && bin/uglifyjs s.js -c | node && bin/uglifyjs s.js -c passes=3 | node && bin/uglifyjs s.js -c passes=3 -m | node
|
||||
|
||||
// workaround for tty output truncation upon process.exit()
|
||||
[process.stdout, process.stderr].forEach(function(stream){
|
||||
if (stream._handle && stream._handle.setBlocking)
|
||||
stream._handle.setBlocking(true);
|
||||
});
|
||||
require("../tools/exit");
|
||||
|
||||
var UglifyJS = require("..");
|
||||
var randomBytes = require("crypto").randomBytes;
|
||||
@@ -127,6 +123,9 @@ for (var i = 2; i < process.argv.length; ++i) {
|
||||
}
|
||||
|
||||
var VALUES = [
|
||||
'"a"',
|
||||
'"b"',
|
||||
'"c"',
|
||||
'""',
|
||||
'true',
|
||||
'false',
|
||||
@@ -329,7 +328,8 @@ function createTopLevelCode() {
|
||||
rng(2) == 0
|
||||
? createStatements(3, MAX_GENERATION_RECURSION_DEPTH, CANNOT_THROW, CANNOT_BREAK, CANNOT_CONTINUE, CANNOT_RETURN, 0)
|
||||
: createFunctions(rng(MAX_GENERATED_TOPLEVELS_PER_RUN) + 1, MAX_GENERATION_RECURSION_DEPTH, DEFUN_OK, CANNOT_THROW, 0),
|
||||
'console.log(null, a, b, c);' // preceding `null` makes for a cleaner output (empty string still shows up etc)
|
||||
// preceding `null` makes for a cleaner output (empty string still shows up etc)
|
||||
'console.log(null, a, b, c, Infinity, NaN, undefined);'
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
@@ -635,6 +635,8 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
||||
case p++:
|
||||
case p++:
|
||||
return getVarName();
|
||||
case p++:
|
||||
return getVarName() + createAssignment() + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow);
|
||||
case p++:
|
||||
return createExpression(recurmax, COMMA_OK, stmtDepth, canThrow);
|
||||
case p++:
|
||||
|
||||
15
tools/exit.js
Normal file
15
tools/exit.js
Normal file
@@ -0,0 +1,15 @@
|
||||
// workaround for tty output truncation upon process.exit()
|
||||
var exit = process.exit;
|
||||
process.exit = function() {
|
||||
var args = [].slice.call(arguments);
|
||||
process.once("uncaughtException", function() {
|
||||
(function callback() {
|
||||
if (process.stdout.bufferSize || process.stderr.bufferSize) {
|
||||
setImmediate(callback);
|
||||
} else {
|
||||
exit.apply(process, args);
|
||||
}
|
||||
})();
|
||||
});
|
||||
throw exit;
|
||||
};
|
||||
Reference in New Issue
Block a user