Compare commits
57 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b2b8a0d386 | ||
|
|
ac40301813 | ||
|
|
3563d8c09e | ||
|
|
5ae04b3545 | ||
|
|
a80b228d8b | ||
|
|
cf4bf4ceb1 | ||
|
|
8223b2e0db | ||
|
|
381bd3836e | ||
|
|
919d5e3482 | ||
|
|
e3a3db73ae | ||
|
|
d9344f30b8 | ||
|
|
be80f7e706 | ||
|
|
cf45e2f79b | ||
|
|
8354758f30 | ||
|
|
9e6b128374 | ||
|
|
93cdb194f4 | ||
|
|
b633706ce4 | ||
|
|
e9920f7ca1 | ||
|
|
7e465d4a01 | ||
|
|
aa80ee349d | ||
|
|
80e81765cf | ||
|
|
711f88dcb4 | ||
|
|
344d11d591 | ||
|
|
c7cdcf06a6 | ||
|
|
3ee55748d4 | ||
|
|
dedbeeff15 | ||
|
|
bd6dee52ab | ||
|
|
144052ca49 | ||
|
|
65c848cc6f | ||
|
|
8a8a94a596 | ||
|
|
8153b7bd8a | ||
|
|
d787d70127 | ||
|
|
3ac2421932 | ||
|
|
a9fc9ddc33 | ||
|
|
a5d62a3fc6 | ||
|
|
067e5a5762 | ||
|
|
33b5f31984 | ||
|
|
35a849dc48 | ||
|
|
b70591be1a | ||
|
|
b33e7f88e6 | ||
|
|
1f0333e9f1 | ||
|
|
eb98a7f2f3 | ||
|
|
78d1bb92d4 | ||
|
|
ea9ab9fb0e | ||
|
|
ce54c9ccee | ||
|
|
07accd2fbb | ||
|
|
18059cc94f | ||
|
|
b5e0e8c203 | ||
|
|
e5cb9275df | ||
|
|
17b81350d4 | ||
|
|
4d63d4f5b3 | ||
|
|
70d72ad806 | ||
|
|
fe9227a41b | ||
|
|
b49e142a26 | ||
|
|
ee3b39b909 | ||
|
|
9699ffb1af | ||
|
|
fdc9b9413b |
7
.github/ISSUE_TEMPLATE.md
vendored
Normal file
7
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
- Bug report or feature request?
|
||||
- `uglify-js` version (`uglifyjs -V`)
|
||||
- JavaScript input - ideally as small as possible.
|
||||
- The `uglifyjs` CLI command executed or `minify()` options used.
|
||||
- An example of JavaScript output produced and/or the error or warning.
|
||||
|
||||
Note: the release version of `uglify-js` only supports ES5. Those wishing to minify ES6 should use the experimental [`harmony`](https://github.com/mishoo/UglifyJS2#harmony) branch.
|
||||
@@ -1,10 +1,13 @@
|
||||
language: node_js
|
||||
before_install: "npm install -g npm"
|
||||
node_js:
|
||||
- "0.12"
|
||||
- "0.10"
|
||||
- "0.12"
|
||||
- "4"
|
||||
- "6"
|
||||
- "7"
|
||||
env:
|
||||
- UGLIFYJS_TEST_ALL=1
|
||||
matrix:
|
||||
fast_finish: true
|
||||
sudo: false
|
||||
|
||||
16
README.md
16
README.md
@@ -75,8 +75,6 @@ The available options are:
|
||||
--support-ie8 Use this flag to support Internet Explorer 6/7/8.
|
||||
Equivalent to setting `screw_ie8: false` in `minify()`
|
||||
for `compress`, `mangle` and `output` options.
|
||||
Note: `--support-ie8` may generate incorrect code
|
||||
for `try`/`catch` in ES5 compliant browsers.
|
||||
--expr Parse a single expression, rather than a
|
||||
program (for parsing JSON)
|
||||
-p, --prefix Skip prefix for original filenames that appear
|
||||
@@ -350,6 +348,9 @@ to set `true`; it's effectively a shortcut for `foo=true`).
|
||||
comparison are switching. Compression only works if both `comparisons` and
|
||||
`unsafe_comps` are both set to true.
|
||||
|
||||
- `unsafe_math` (default: false) -- optimize numerical expressions like
|
||||
`2 * x * 3` into `6 * x`, which may give imprecise floating point results.
|
||||
|
||||
- `unsafe_proto` (default: false) -- optimize expressions like
|
||||
`Array.prototype.slice.call(a)` into `[].slice.call(a)`
|
||||
|
||||
@@ -390,11 +391,11 @@ to set `true`; it's effectively a shortcut for `foo=true`).
|
||||
- `cascade` -- small optimization for sequences, transform `x, x` into `x`
|
||||
and `x = something(), x` into `x = something()`
|
||||
|
||||
- `collapse_vars` -- default `false`. Collapse single-use `var` and `const`
|
||||
definitions when possible.
|
||||
- `collapse_vars` -- Collapse single-use `var` and `const` definitions
|
||||
when possible.
|
||||
|
||||
- `reduce_vars` -- default `false`. Improve optimization on variables assigned
|
||||
with and used as constant values.
|
||||
- `reduce_vars` -- Improve optimization on variables assigned with and
|
||||
used as constant values.
|
||||
|
||||
- `warnings` -- display warnings when dropping unreachable code or unused
|
||||
declarations etc.
|
||||
@@ -423,6 +424,9 @@ to set `true`; it's effectively a shortcut for `foo=true`).
|
||||
such as `console.info` and/or retain side effects from function arguments
|
||||
after dropping the function call then use `pure_funcs` instead.
|
||||
|
||||
- `expression` -- default `false`. Pass `true` to preserve completion values
|
||||
from terminal statements without `return`, e.g. in bookmarklets.
|
||||
|
||||
- `keep_fargs` -- default `true`. Prevents the
|
||||
compressor from discarding unused function arguments. You need this
|
||||
for code which relies on `Function.length`.
|
||||
|
||||
14
bin/uglifyjs
14
bin/uglifyjs
@@ -8,7 +8,6 @@ var sys = require("util");
|
||||
var yargs = require("yargs");
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
var async = require("async");
|
||||
var acorn;
|
||||
var screw_ie8 = true;
|
||||
var ARGS = yargs
|
||||
@@ -27,7 +26,7 @@ mangling you need to use `-c` and `-m`.\
|
||||
.describe("source-map-include-sources", "Pass this flag if you want to include the content of source files in the source map as sourcesContent property.")
|
||||
.describe("in-source-map", "Input source map, useful if you're compressing JS that was generated from some other original code.")
|
||||
.describe("screw-ie8", "Do not support Internet Explorer 6/7/8. This flag is enabled by default.")
|
||||
.describe("support-ie8", "Support non-standard Internet Explorer 6/7/8 javascript. Note: may generate incorrect code for try/catch in ES5 compliant browsers.")
|
||||
.describe("support-ie8", "Support non-standard Internet Explorer 6/7/8 javascript.")
|
||||
.describe("expr", "Parse a single expression, rather than a program (for parsing JSON)")
|
||||
.describe("p", "Skip prefix for original filenames that appear in source maps. \
|
||||
For example -p 3 will drop 3 directories from file names and ensure they are relative paths. \
|
||||
@@ -319,8 +318,11 @@ var STATS = {};
|
||||
var TOPLEVEL = null;
|
||||
var P_RELATIVE = ARGS.p && ARGS.p == "relative";
|
||||
var SOURCES_CONTENT = {};
|
||||
var index = 0;
|
||||
|
||||
async.eachLimit(files, 1, function (file, cb) {
|
||||
!function cb() {
|
||||
if (index == files.length) return done();
|
||||
var file = files[index++];
|
||||
read_whole_file(file, function (err, code) {
|
||||
if (err) {
|
||||
print_error("ERROR: can't read file: " + file);
|
||||
@@ -388,7 +390,9 @@ async.eachLimit(files, 1, function (file, cb) {
|
||||
});
|
||||
cb();
|
||||
});
|
||||
}, function () {
|
||||
}();
|
||||
|
||||
function done() {
|
||||
var OUTPUT_FILE = ARGS.o;
|
||||
|
||||
var SOURCE_MAP = (ARGS.source_map || ARGS.source_map_inline) ? UglifyJS.SourceMap({
|
||||
@@ -537,7 +541,7 @@ async.eachLimit(files, 1, function (file, cb) {
|
||||
}));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* -----[ functions ]----- */
|
||||
|
||||
|
||||
36
lib/ast.js
36
lib/ast.js
@@ -91,9 +91,20 @@ var AST_Token = DEFNODE("Token", "type value line col pos endline endcol endpos
|
||||
}, null);
|
||||
|
||||
var AST_Node = DEFNODE("Node", "start end", {
|
||||
clone: function() {
|
||||
_clone: function(deep) {
|
||||
if (deep) {
|
||||
var self = this.clone();
|
||||
return self.transform(new TreeTransformer(function(node) {
|
||||
if (node !== self) {
|
||||
return node.clone(true);
|
||||
}
|
||||
}));
|
||||
}
|
||||
return new this.CTOR(this);
|
||||
},
|
||||
clone: function(deep) {
|
||||
return this._clone(deep);
|
||||
},
|
||||
$documentation: "Base class of all AST nodes",
|
||||
$propdoc: {
|
||||
start: "[AST_Token] The first token of this node",
|
||||
@@ -199,6 +210,20 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
|
||||
this.label._walk(visitor);
|
||||
this.body._walk(visitor);
|
||||
});
|
||||
},
|
||||
clone: function(deep) {
|
||||
var node = this._clone(deep);
|
||||
if (deep) {
|
||||
var refs = node.label.references;
|
||||
var label = this.label;
|
||||
node.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_LoopControl
|
||||
&& node.label && node.label.thedef === label) {
|
||||
refs.push(node);
|
||||
}
|
||||
}));
|
||||
}
|
||||
return node;
|
||||
}
|
||||
}, AST_StatementWithBody);
|
||||
|
||||
@@ -812,9 +837,6 @@ var AST_SymbolAccessor = DEFNODE("SymbolAccessor", null, {
|
||||
|
||||
var AST_SymbolDeclaration = DEFNODE("SymbolDeclaration", "init", {
|
||||
$documentation: "A declaration symbol (symbol in var/const, function name or argument, symbol in catch)",
|
||||
$propdoc: {
|
||||
init: "[AST_Node*/S] array of initializers for this declaration."
|
||||
}
|
||||
}, AST_Symbol);
|
||||
|
||||
var AST_SymbolVar = DEFNODE("SymbolVar", null, {
|
||||
@@ -962,8 +984,8 @@ TreeWalker.prototype = {
|
||||
push: function (node) {
|
||||
if (node instanceof AST_Lambda) {
|
||||
this.directives = Object.create(this.directives);
|
||||
} else if (node instanceof AST_Directive) {
|
||||
this.directives[node.value] = this.directives[node.value] ? "up" : true;
|
||||
} else if (node instanceof AST_Directive && !this.directives[node.value]) {
|
||||
this.directives[node.value] = node;
|
||||
}
|
||||
this.stack.push(node);
|
||||
},
|
||||
@@ -991,7 +1013,7 @@ TreeWalker.prototype = {
|
||||
for (var i = 0; i < node.body.length; ++i) {
|
||||
var st = node.body[i];
|
||||
if (!(st instanceof AST_Directive)) break;
|
||||
if (st.value == type) return true;
|
||||
if (st.value == type) return st;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
836
lib/compress.js
836
lib/compress.js
File diff suppressed because it is too large
Load Diff
@@ -46,17 +46,8 @@
|
||||
var EXPECT_DIRECTIVE = /^$|[;{][\s\n]*$/;
|
||||
|
||||
function is_some_comments(comment) {
|
||||
var text = comment.value;
|
||||
var type = comment.type;
|
||||
if (type == "comment2") {
|
||||
// multiline comment
|
||||
return /@preserve|@license|@cc_on/i.test(text);
|
||||
}
|
||||
return type == "comment5";
|
||||
}
|
||||
|
||||
function is_comment5(comment) {
|
||||
return comment.type == "comment5";
|
||||
// multiline comment
|
||||
return comment.type == "comment2" && /@preserve|@license|@cc_on/i.test(comment.value);
|
||||
}
|
||||
|
||||
function OutputStream(options) {
|
||||
@@ -86,7 +77,7 @@ function OutputStream(options) {
|
||||
}, true);
|
||||
|
||||
// Convert comment option to RegExp if neccessary and set up comments filter
|
||||
var comment_filter = options.shebang ? is_comment5 : return_false; // Default case, throw all comments away except shebangs
|
||||
var comment_filter = return_false; // Default case, throw all comments away
|
||||
if (options.comments) {
|
||||
var comments = options.comments;
|
||||
if (typeof options.comments === "string" && /^\/.*\/[a-zA-Z]*$/.test(options.comments)) {
|
||||
@@ -98,12 +89,12 @@ function OutputStream(options) {
|
||||
}
|
||||
if (comments instanceof RegExp) {
|
||||
comment_filter = function(comment) {
|
||||
return comment.type == "comment5" || comments.test(comment.value);
|
||||
return comment.type != "comment5" && comments.test(comment.value);
|
||||
};
|
||||
}
|
||||
else if (typeof comments === "function") {
|
||||
comment_filter = function(comment) {
|
||||
return comment.type == "comment5" || comments(this, comment);
|
||||
return comment.type != "comment5" && comments(this, comment);
|
||||
};
|
||||
}
|
||||
else if (comments === "some") {
|
||||
@@ -400,10 +391,6 @@ function OutputStream(options) {
|
||||
return OUTPUT;
|
||||
};
|
||||
|
||||
if (options.preamble) {
|
||||
print(options.preamble.replace(/\r\n?|[\n\u2028\u2029]|\s*$/g, "\n"));
|
||||
}
|
||||
|
||||
var stack = [];
|
||||
return {
|
||||
get : get,
|
||||
@@ -523,6 +510,17 @@ function OutputStream(options) {
|
||||
}));
|
||||
}
|
||||
|
||||
if (comments.length > 0 && output.pos() == 0) {
|
||||
if (output.option("shebang") && comments[0].type == "comment5") {
|
||||
output.print("#!" + comments.shift().value + "\n");
|
||||
output.indent();
|
||||
}
|
||||
var preamble = output.option("preamble");
|
||||
if (preamble) {
|
||||
output.print(preamble.replace(/\r\n?|[\n\u2028\u2029]|\s*$/g, "\n"));
|
||||
}
|
||||
}
|
||||
|
||||
comments = comments.filter(output.comment_filter, self);
|
||||
|
||||
// Keep single line comments after nlb, after nlb
|
||||
@@ -547,10 +545,6 @@ function OutputStream(options) {
|
||||
output.space();
|
||||
}
|
||||
}
|
||||
else if (output.pos() === 0 && c.type == "comment5" && output.option("shebang")) {
|
||||
output.print("#!" + c.value + "\n");
|
||||
output.indent();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -783,7 +777,7 @@ function OutputStream(options) {
|
||||
DEFPRINT(AST_Do, function(self, output){
|
||||
output.print("do");
|
||||
output.space();
|
||||
self._do_print_body(output);
|
||||
make_block(self.body, output);
|
||||
output.space();
|
||||
output.print("while");
|
||||
output.space();
|
||||
@@ -910,10 +904,10 @@ function OutputStream(options) {
|
||||
|
||||
/* -----[ if ]----- */
|
||||
function make_then(self, output) {
|
||||
if (output.option("bracketize")) {
|
||||
make_block(self.body, output);
|
||||
return;
|
||||
}
|
||||
var b = self.body;
|
||||
if (output.option("bracketize")
|
||||
|| !output.option("screw_ie8") && b instanceof AST_Do)
|
||||
return make_block(b, output);
|
||||
// The squeezer replaces "block"-s that contain only a single
|
||||
// statement with the statement itself; technically, the AST
|
||||
// is correct, but this can create problems when we output an
|
||||
@@ -921,18 +915,7 @@ function OutputStream(options) {
|
||||
// IF *without* an ELSE block (then the outer ELSE would refer
|
||||
// to the inner IF). This function checks for this case and
|
||||
// adds the block brackets if needed.
|
||||
if (!self.body)
|
||||
return output.force_semicolon();
|
||||
if (self.body instanceof AST_Do) {
|
||||
// Unconditionally use the if/do-while workaround for all browsers.
|
||||
// https://github.com/mishoo/UglifyJS/issues/#issue/57 IE
|
||||
// croaks with "syntax error" on code like this: if (foo)
|
||||
// do ... while(cond); else ... we need block brackets
|
||||
// around do/while
|
||||
make_block(self.body, output);
|
||||
return;
|
||||
}
|
||||
var b = self.body;
|
||||
if (!b) return output.force_semicolon();
|
||||
while (true) {
|
||||
if (b instanceof AST_If) {
|
||||
if (!b.alternative) {
|
||||
@@ -1341,15 +1324,7 @@ function OutputStream(options) {
|
||||
|
||||
function force_statement(stat, output) {
|
||||
if (output.option("bracketize")) {
|
||||
if (!stat || stat instanceof AST_EmptyStatement)
|
||||
output.print("{}");
|
||||
else if (stat instanceof AST_BlockStatement)
|
||||
stat.print(output);
|
||||
else output.with_block(function(){
|
||||
output.indent();
|
||||
stat.print(output);
|
||||
output.newline();
|
||||
});
|
||||
make_block(stat, output);
|
||||
} else {
|
||||
if (!stat || stat instanceof AST_EmptyStatement)
|
||||
output.force_semicolon();
|
||||
@@ -1398,11 +1373,11 @@ function OutputStream(options) {
|
||||
};
|
||||
|
||||
function make_block(stmt, output) {
|
||||
if (stmt instanceof AST_BlockStatement) {
|
||||
if (!stmt || stmt instanceof AST_EmptyStatement)
|
||||
output.print("{}");
|
||||
else if (stmt instanceof AST_BlockStatement)
|
||||
stmt.print(output);
|
||||
return;
|
||||
}
|
||||
output.with_block(function(){
|
||||
else output.with_block(function(){
|
||||
output.indent();
|
||||
stmt.print(output);
|
||||
output.newline();
|
||||
|
||||
16
lib/parse.js
16
lib/parse.js
@@ -558,6 +558,11 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
function next_token(force_regexp) {
|
||||
if (force_regexp != null)
|
||||
return read_regexp(force_regexp);
|
||||
if (shebang && S.pos == 0 && looking_at("#!")) {
|
||||
start_token();
|
||||
forward(2);
|
||||
skip_line_comment("comment5");
|
||||
}
|
||||
for (;;) {
|
||||
skip_whitespace();
|
||||
start_token();
|
||||
@@ -589,13 +594,6 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
if (PUNC_CHARS(ch)) return token("punc", next());
|
||||
if (OPERATOR_CHARS(ch)) return read_operator();
|
||||
if (code == 92 || is_identifier_start(code)) return read_word();
|
||||
if (shebang) {
|
||||
if (S.pos == 0 && looking_at("#!")) {
|
||||
forward(2);
|
||||
skip_line_comment("comment5");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
parse_error("Unexpected character '" + ch + "'");
|
||||
@@ -930,11 +928,9 @@ function parse($TEXT, options) {
|
||||
expression : parenthesised(),
|
||||
body : statement()
|
||||
});
|
||||
|
||||
default:
|
||||
unexpected();
|
||||
}
|
||||
}
|
||||
unexpected();
|
||||
});
|
||||
|
||||
function labeled_statement() {
|
||||
|
||||
26
lib/scope.js
26
lib/scope.js
@@ -97,7 +97,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
var labels = new Dictionary();
|
||||
var defun = null;
|
||||
var tw = new TreeWalker(function(node, descend){
|
||||
if (options.screw_ie8 && node instanceof AST_Catch) {
|
||||
if (node instanceof AST_Catch) {
|
||||
var save_scope = scope;
|
||||
scope = new AST_Scope(node);
|
||||
scope.init_scope_vars();
|
||||
@@ -154,12 +154,10 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
}
|
||||
else if (node instanceof AST_SymbolVar
|
||||
|| node instanceof AST_SymbolConst) {
|
||||
var def = defun.def_variable(node);
|
||||
def.init = tw.parent().value;
|
||||
defun.def_variable(node);
|
||||
}
|
||||
else if (node instanceof AST_SymbolCatch) {
|
||||
(options.screw_ie8 ? scope : defun)
|
||||
.def_variable(node);
|
||||
scope.def_variable(node);
|
||||
}
|
||||
else if (node instanceof AST_LabelRef) {
|
||||
var sym = labels.get(node.name);
|
||||
@@ -209,6 +207,24 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
});
|
||||
self.walk(tw);
|
||||
|
||||
// pass 3: fix up any scoping issue with IE8
|
||||
if (!options.screw_ie8) {
|
||||
self.walk(new TreeWalker(function(node, descend) {
|
||||
if (node instanceof AST_SymbolCatch) {
|
||||
var name = node.name;
|
||||
var refs = node.thedef.references;
|
||||
var scope = node.thedef.scope.parent_scope;
|
||||
var def = scope.find_variable(name) || self.globals.get(name) || scope.def_variable(node);
|
||||
refs.forEach(function(ref) {
|
||||
ref.thedef = def;
|
||||
ref.reference(options);
|
||||
});
|
||||
node.thedef = def;
|
||||
return true;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
if (options.cache) {
|
||||
this.cname = options.cache.cname;
|
||||
}
|
||||
|
||||
@@ -126,9 +126,11 @@ function merge(obj, ext) {
|
||||
return count;
|
||||
};
|
||||
|
||||
function noop() {};
|
||||
function noop() {}
|
||||
function return_false() { return false; }
|
||||
function return_true() { return true; }
|
||||
function return_this() { return this; }
|
||||
function return_null() { return null; }
|
||||
|
||||
var MAP = (function(){
|
||||
function MAP(a, f, backwards) {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"homepage": "http://lisperator.net/uglifyjs",
|
||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||
"license": "BSD-2-Clause",
|
||||
"version": "2.8.4",
|
||||
"version": "2.8.13",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
@@ -29,7 +29,6 @@
|
||||
"LICENSE"
|
||||
],
|
||||
"dependencies": {
|
||||
"async": "~0.2.6",
|
||||
"source-map": "~0.5.1",
|
||||
"uglify-to-browserify": "~1.0.0",
|
||||
"yargs": "~3.10.0"
|
||||
|
||||
@@ -24,26 +24,57 @@ var results = {};
|
||||
var remaining = 2 * urls.length;
|
||||
function done() {
|
||||
if (!--remaining) {
|
||||
var failures = [];
|
||||
urls.forEach(function(url) {
|
||||
var info = results[url];
|
||||
console.log();
|
||||
console.log(url);
|
||||
console.log(results[url].time);
|
||||
console.log("SHA1:", results[url].sha1);
|
||||
console.log(info.log);
|
||||
var elapsed = 0;
|
||||
info.log.replace(/: ([0-9]+\.[0-9]{3})s/g, function(match, time) {
|
||||
elapsed += parseFloat(time);
|
||||
});
|
||||
console.log("Run-time:", elapsed.toFixed(3), "s");
|
||||
console.log("Original:", info.input, "bytes");
|
||||
console.log("Uglified:", info.output, "bytes");
|
||||
console.log("SHA1 sum:", info.sha1);
|
||||
if (info.code) {
|
||||
failures.push(url);
|
||||
}
|
||||
});
|
||||
if (failures.length) {
|
||||
console.error("Benchmark failed:");
|
||||
failures.forEach(function(url) {
|
||||
console.error(url);
|
||||
});
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
urls.forEach(function(url) {
|
||||
results[url] = { time: "" };
|
||||
results[url] = {
|
||||
input: 0,
|
||||
output: 0,
|
||||
log: ""
|
||||
};
|
||||
require(url.slice(0, url.indexOf(":"))).get(url, function(res) {
|
||||
var uglifyjs = fork("bin/uglifyjs", args, { silent: true });
|
||||
res.pipe(uglifyjs.stdin);
|
||||
uglifyjs.stdout.pipe(createHash("sha1")).on("data", function(data) {
|
||||
res.on("data", function(data) {
|
||||
results[url].input += data.length;
|
||||
}).pipe(uglifyjs.stdin);
|
||||
uglifyjs.stdout.on("data", function(data) {
|
||||
results[url].output += data.length;
|
||||
}).pipe(createHash("sha1")).on("data", function(data) {
|
||||
results[url].sha1 = data.toString("hex");
|
||||
done();
|
||||
});
|
||||
uglifyjs.stderr.setEncoding("utf8");
|
||||
uglifyjs.stderr.on("data", function(data) {
|
||||
results[url].time += data;
|
||||
}).on("end", done)
|
||||
results[url].log += data;
|
||||
});
|
||||
uglifyjs.on("exit", function(code) {
|
||||
results[url].code = code;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -344,9 +344,9 @@ collapse_vars_do_while: {
|
||||
}
|
||||
input: {
|
||||
function f1(y) {
|
||||
// The constant do-while condition `c` will be replaced.
|
||||
// The constant do-while condition `c` will not be replaced.
|
||||
var c = 9;
|
||||
do { } while (c === 77);
|
||||
do {} while (c === 77);
|
||||
}
|
||||
function f2(y) {
|
||||
// The non-constant do-while condition `c` will not be replaced.
|
||||
@@ -381,7 +381,8 @@ collapse_vars_do_while: {
|
||||
}
|
||||
expect: {
|
||||
function f1(y) {
|
||||
do ; while (false);
|
||||
var c = 9;
|
||||
do ; while (77 === c);
|
||||
}
|
||||
function f2(y) {
|
||||
var c = 5 - y;
|
||||
@@ -418,9 +419,9 @@ collapse_vars_do_while_drop_assign: {
|
||||
}
|
||||
input: {
|
||||
function f1(y) {
|
||||
// The constant do-while condition `c` will be replaced.
|
||||
// The constant do-while condition `c` will be not replaced.
|
||||
var c = 9;
|
||||
do { } while (c === 77);
|
||||
do {} while (c === 77);
|
||||
}
|
||||
function f2(y) {
|
||||
// The non-constant do-while condition `c` will not be replaced.
|
||||
@@ -455,7 +456,8 @@ collapse_vars_do_while_drop_assign: {
|
||||
}
|
||||
expect: {
|
||||
function f1(y) {
|
||||
do ; while (false);
|
||||
var c = 9;
|
||||
do ; while (77 === c);
|
||||
}
|
||||
function f2(y) {
|
||||
var c = 5 - y;
|
||||
@@ -1141,7 +1143,7 @@ collapse_vars_constants: {
|
||||
function f3(x) {
|
||||
var b = x.prop;
|
||||
sideeffect1();
|
||||
return b + (function() { return -9; })();
|
||||
return b + -9;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1150,7 +1152,8 @@ collapse_vars_arguments: {
|
||||
options = {
|
||||
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true,
|
||||
toplevel:true
|
||||
}
|
||||
input: {
|
||||
var outer = function() {
|
||||
@@ -1309,9 +1312,99 @@ collapse_vars_regexp: {
|
||||
};
|
||||
}
|
||||
(function(){
|
||||
var result, rx = /ab*/g;
|
||||
while (result = rx.exec('acdabcdeabbb'))
|
||||
var result, s = "acdabcdeabbb", rx = /ab*/g;
|
||||
while (result = rx.exec(s))
|
||||
console.log(result[0]);
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
issue_1537: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var k = '';
|
||||
for (k in {prop: 'val'}){}
|
||||
}
|
||||
expect: {
|
||||
var k = '';
|
||||
for (k in {prop: 'val'});
|
||||
}
|
||||
}
|
||||
|
||||
issue_1562: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var v = 1, B = 2;
|
||||
for (v in objs) f(B);
|
||||
|
||||
var x = 3, C = 10;
|
||||
while(x + 2) bar(C);
|
||||
|
||||
var y = 4, D = 20;
|
||||
do bar(D); while(y + 2);
|
||||
|
||||
var z = 5, E = 30;
|
||||
for (; f(z + 2) ;) bar(E);
|
||||
}
|
||||
expect: {
|
||||
var v = 1;
|
||||
for (v in objs) f(2);
|
||||
|
||||
var x = 3;
|
||||
while(x + 2) bar(10);
|
||||
|
||||
var y = 4;
|
||||
do bar(20); while(y + 2);
|
||||
|
||||
var z = 5;
|
||||
for (; f(z + 2) ;) bar(30);
|
||||
}
|
||||
}
|
||||
|
||||
issue_1605_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
function foo(x) {
|
||||
var y = x;
|
||||
return y;
|
||||
}
|
||||
var o = new Object;
|
||||
o.p = 1;
|
||||
}
|
||||
expect: {
|
||||
function foo(x) {
|
||||
return x;
|
||||
}
|
||||
var o = new Object;
|
||||
o.p = 1;
|
||||
}
|
||||
}
|
||||
|
||||
issue_1605_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
toplevel: "vars",
|
||||
}
|
||||
input: {
|
||||
function foo(x) {
|
||||
var y = x;
|
||||
return y;
|
||||
}
|
||||
var o = new Object;
|
||||
o.p = 1;
|
||||
}
|
||||
expect: {
|
||||
function foo(x) {
|
||||
return x;
|
||||
}
|
||||
(new Object).p = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,3 +164,53 @@ concat_6: {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
concat_7: {
|
||||
input: {
|
||||
console.log(
|
||||
"" + 1,
|
||||
"" + "1",
|
||||
"" + 1 + 2,
|
||||
"" + 1 + "2",
|
||||
"" + "1" + 2,
|
||||
"" + "1" + "2",
|
||||
"" + (x += "foo")
|
||||
);
|
||||
}
|
||||
expect: {
|
||||
console.log(
|
||||
"" + 1,
|
||||
"1",
|
||||
"" + 1 + 2,
|
||||
1 + "2",
|
||||
"1" + 2,
|
||||
"1" + "2",
|
||||
x += "foo"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
concat_8: {
|
||||
input: {
|
||||
console.log(
|
||||
1 + "",
|
||||
"1" + "",
|
||||
1 + 2 + "",
|
||||
1 + "2" + "",
|
||||
"1" + 2 + "",
|
||||
"1" + "2" + "",
|
||||
(x += "foo") + ""
|
||||
);
|
||||
}
|
||||
expect: {
|
||||
console.log(
|
||||
1 + "",
|
||||
"1",
|
||||
1 + 2 + "",
|
||||
1 + "2",
|
||||
"1" + 2,
|
||||
"1" + "2",
|
||||
x += "foo"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,6 +123,7 @@ dead_code_const_annotation: {
|
||||
conditionals : true,
|
||||
evaluate : true,
|
||||
reduce_vars : true,
|
||||
toplevel : true,
|
||||
};
|
||||
input: {
|
||||
var unused;
|
||||
@@ -172,6 +173,7 @@ dead_code_const_annotation_complex_scope: {
|
||||
conditionals : true,
|
||||
evaluate : true,
|
||||
reduce_vars : true,
|
||||
toplevel : true,
|
||||
};
|
||||
input: {
|
||||
var unused_var;
|
||||
|
||||
@@ -632,7 +632,7 @@ iife: {
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
~function() {}(b);
|
||||
b;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -679,3 +679,115 @@ const_assign: {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_1539: {
|
||||
options = {
|
||||
cascade: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var a, b;
|
||||
a = b = 42;
|
||||
return a;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
return 42;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vardef_value: {
|
||||
options = {
|
||||
keep_fnames: false,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
function g(){
|
||||
return x();
|
||||
}
|
||||
var a = g();
|
||||
return a(42);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
var a = function(){
|
||||
return x();
|
||||
}();
|
||||
return a(42);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assign_binding: {
|
||||
options = {
|
||||
cascade: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var a;
|
||||
a = f.g, a();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
(0, f.g)();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assign_chain: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var a, b;
|
||||
x = a = y = b = 42;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
x = y = 42;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_1583: {
|
||||
options = {
|
||||
keep_fargs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function m(t) {
|
||||
(function(e) {
|
||||
t = e();
|
||||
})(function() {
|
||||
return (function(a) {
|
||||
return a;
|
||||
})(function(a) {});
|
||||
});
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function m(t) {
|
||||
(function(e) {
|
||||
t = (function() {
|
||||
return (function(a) {
|
||||
return a;
|
||||
})(function(a) {});
|
||||
})();
|
||||
})();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -640,9 +640,28 @@ call_args: {
|
||||
expect: {
|
||||
const a = 1;
|
||||
console.log(1);
|
||||
+(1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
call_args_drop_param: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
const a = 1;
|
||||
console.log(a);
|
||||
+function(a) {
|
||||
return 1;
|
||||
}(1);
|
||||
return a;
|
||||
}(a, b);
|
||||
}
|
||||
expect: {
|
||||
const a = 1;
|
||||
console.log(1);
|
||||
+(b, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,3 +6,88 @@ non_ascii_function_identifier_name: {
|
||||
}
|
||||
expect_exact: "function fooλ(δλ){}function λ(δλ){}(function λ(δλ){})();"
|
||||
}
|
||||
|
||||
iifes_returning_constants_keep_fargs_true: {
|
||||
options = {
|
||||
keep_fargs : true,
|
||||
side_effects : true,
|
||||
evaluate : true,
|
||||
unused : true,
|
||||
dead_code : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
booleans : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
reduce_vars : true,
|
||||
cascade : true,
|
||||
}
|
||||
input: {
|
||||
(function(){ return -1.23; }());
|
||||
console.log( function foo(){ return "okay"; }() );
|
||||
console.log( function foo(x, y, z){ return 123; }() );
|
||||
console.log( function(x, y, z){ return z; }() );
|
||||
console.log( function(x, y, z){ if (x) return y; return z; }(1, 2, 3) );
|
||||
console.log( function(x, y){ return x * y; }(2, 3) );
|
||||
console.log( function(x, y){ return x * y; }(2, 3, a(), b()) );
|
||||
}
|
||||
expect: {
|
||||
console.log("okay");
|
||||
console.log(123);
|
||||
console.log(void 0);
|
||||
console.log(2);
|
||||
console.log(6);
|
||||
console.log((a(), b(), 6));
|
||||
}
|
||||
}
|
||||
|
||||
iifes_returning_constants_keep_fargs_false: {
|
||||
options = {
|
||||
keep_fargs : false,
|
||||
side_effects : true,
|
||||
evaluate : true,
|
||||
unused : true,
|
||||
dead_code : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
booleans : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
reduce_vars : true,
|
||||
cascade : true,
|
||||
}
|
||||
input: {
|
||||
(function(){ return -1.23; }());
|
||||
console.log( function foo(){ return "okay"; }() );
|
||||
console.log( function foo(x, y, z){ return 123; }() );
|
||||
console.log( function(x, y, z){ return z; }() );
|
||||
console.log( function(x, y, z){ if (x) return y; return z; }(1, 2, 3) );
|
||||
console.log( function(x, y){ return x * y; }(2, 3) );
|
||||
console.log( function(x, y){ return x * y; }(2, 3, a(), b()) );
|
||||
}
|
||||
expect: {
|
||||
console.log("okay");
|
||||
console.log(123);
|
||||
console.log(void 0);
|
||||
console.log(2);
|
||||
console.log(6);
|
||||
console.log((a(), b(), 6));
|
||||
}
|
||||
}
|
||||
|
||||
issue_485_crashing_1530: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
(function(a) {
|
||||
if (true) return;
|
||||
var b = 42;
|
||||
})(this);
|
||||
}
|
||||
expect: {
|
||||
this, void 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
unsafe_undefined: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
unsafe: true
|
||||
}
|
||||
@@ -19,12 +20,7 @@ unsafe_undefined: {
|
||||
expect: {
|
||||
function f(n) {
|
||||
return function() {
|
||||
if (a)
|
||||
return b;
|
||||
if (c)
|
||||
return d;
|
||||
else
|
||||
return n;
|
||||
return a ? b : c ? d : n;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -32,6 +28,7 @@ unsafe_undefined: {
|
||||
|
||||
keep_fnames: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
unsafe: true
|
||||
}
|
||||
@@ -57,12 +54,7 @@ keep_fnames: {
|
||||
function n(n) {
|
||||
return n * n;
|
||||
}
|
||||
if (a)
|
||||
return b;
|
||||
if (c)
|
||||
return d;
|
||||
else
|
||||
return r;
|
||||
return a ? b : c ? d : r;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
19
test/compress/issue-1569.js
Normal file
19
test/compress/issue-1569.js
Normal file
@@ -0,0 +1,19 @@
|
||||
inner_reference: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
!function f(a) {
|
||||
return a && f(a - 1) + a;
|
||||
}(42);
|
||||
!function g(a) {
|
||||
return a;
|
||||
}(42);
|
||||
}
|
||||
expect: {
|
||||
!function f(a) {
|
||||
return a && f(a - 1) + a;
|
||||
}(42);
|
||||
!void 0;
|
||||
}
|
||||
}
|
||||
87
test/compress/issue-1588.js
Normal file
87
test/compress/issue-1588.js
Normal file
@@ -0,0 +1,87 @@
|
||||
screw_ie8: {
|
||||
options = {
|
||||
screw_ie8: true,
|
||||
}
|
||||
mangle = {
|
||||
screw_ie8: true,
|
||||
}
|
||||
input: {
|
||||
try { throw "foo"; } catch (x) { console.log(x); }
|
||||
}
|
||||
expect_exact: 'try{throw"foo"}catch(o){console.log(o)}'
|
||||
expect_stdout: [
|
||||
"foo"
|
||||
]
|
||||
}
|
||||
|
||||
support_ie8: {
|
||||
options = {
|
||||
screw_ie8: false,
|
||||
}
|
||||
mangle = {
|
||||
screw_ie8: false,
|
||||
}
|
||||
input: {
|
||||
try { throw "foo"; } catch (x) { console.log(x); }
|
||||
}
|
||||
expect_exact: 'try{throw"foo"}catch(x){console.log(x)}'
|
||||
expect_stdout: "foo"
|
||||
}
|
||||
|
||||
safe_undefined: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
unsafe: false,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
var a, c;
|
||||
console.log(function(undefined) {
|
||||
return function() {
|
||||
if (a)
|
||||
return b;
|
||||
if (c)
|
||||
return d;
|
||||
};
|
||||
}(1)());
|
||||
}
|
||||
expect: {
|
||||
var a, c;
|
||||
console.log(function(n) {
|
||||
return function() {
|
||||
return a ? b : c ? d : void 0;
|
||||
};
|
||||
}(1)());
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
unsafe_undefined: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
unsafe: true,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
var a, c;
|
||||
console.log(function(undefined) {
|
||||
return function() {
|
||||
if (a)
|
||||
return b;
|
||||
if (c)
|
||||
return d;
|
||||
};
|
||||
}()());
|
||||
}
|
||||
expect: {
|
||||
var a, c;
|
||||
console.log(function(n) {
|
||||
return function() {
|
||||
return a ? b : c ? d : n;
|
||||
};
|
||||
}()());
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
56
test/compress/issue-1609.js
Normal file
56
test/compress/issue-1609.js
Normal file
@@ -0,0 +1,56 @@
|
||||
chained_evaluation_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
var a = 1;
|
||||
(function() {
|
||||
var b = a, c;
|
||||
c = f(b);
|
||||
c.bar = b;
|
||||
})();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
(function() {
|
||||
var c;
|
||||
c = f(1);
|
||||
c.bar = 1;
|
||||
})();
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
chained_evaluation_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
var a = "long piece of string";
|
||||
(function() {
|
||||
var b = a, c;
|
||||
c = f(b);
|
||||
c.bar = b;
|
||||
})();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
var a = "long piece of string";
|
||||
(function() {
|
||||
var c;
|
||||
c = f(a);
|
||||
c.bar = a;
|
||||
})();
|
||||
})();
|
||||
}
|
||||
}
|
||||
55
test/compress/issue-368.js
Normal file
55
test/compress/issue-368.js
Normal file
@@ -0,0 +1,55 @@
|
||||
collapse: {
|
||||
options = {
|
||||
cascade: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f1() {
|
||||
var a;
|
||||
a = typeof b === 'function' ? b() : b;
|
||||
return a !== undefined && c();
|
||||
}
|
||||
function f2(b) {
|
||||
var a;
|
||||
b = c();
|
||||
a = typeof b === 'function' ? b() : b;
|
||||
return 'stirng' == typeof a && d();
|
||||
}
|
||||
function f3(c) {
|
||||
var a;
|
||||
a = b(a / 2);
|
||||
if (a < 0) {
|
||||
a++;
|
||||
++c;
|
||||
return c / 2;
|
||||
}
|
||||
}
|
||||
function f4(c) {
|
||||
var a;
|
||||
a = b(a / 2);
|
||||
if (a < 0) {
|
||||
a++;
|
||||
c++;
|
||||
return c / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f1() {
|
||||
return void 0 !== ('function' === typeof b ? b() : b) && c();
|
||||
}
|
||||
function f2(b) {
|
||||
return b = c(), 'stirng' == typeof ('function' === typeof b ? b() : b) && d();
|
||||
}
|
||||
function f3(c) {
|
||||
var a;
|
||||
if ((a = b(a / 2)) < 0) return a++, ++c / 2;
|
||||
}
|
||||
function f4(c) {
|
||||
var a;
|
||||
if ((a = b(a / 2)) < 0) return a++, ++c / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
317
test/compress/issue-640.js
Normal file
317
test/compress/issue-640.js
Normal file
@@ -0,0 +1,317 @@
|
||||
cond_5: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
}
|
||||
input: {
|
||||
if (some_condition()) {
|
||||
if (some_other_condition()) {
|
||||
do_something();
|
||||
} else {
|
||||
alternate();
|
||||
}
|
||||
} else {
|
||||
alternate();
|
||||
}
|
||||
|
||||
if (some_condition()) {
|
||||
if (some_other_condition()) {
|
||||
do_something();
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
some_condition() && some_other_condition() ? do_something() : alternate();
|
||||
if (some_condition() && some_other_condition()) do_something();
|
||||
}
|
||||
}
|
||||
|
||||
dead_code_const_annotation_regex: {
|
||||
options = {
|
||||
booleans : true,
|
||||
conditionals : true,
|
||||
dead_code : true,
|
||||
evaluate : true,
|
||||
expression : true,
|
||||
loops : true,
|
||||
}
|
||||
input: {
|
||||
var unused;
|
||||
// @constraint this shouldn't be a constant
|
||||
var CONST_FOO_ANN = false;
|
||||
if (CONST_FOO_ANN) {
|
||||
console.log("reachable");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var unused;
|
||||
var CONST_FOO_ANN = !1;
|
||||
if (CONST_FOO_ANN) console.log('reachable');
|
||||
}
|
||||
}
|
||||
|
||||
drop_console_2: {
|
||||
options = {
|
||||
drop_console: true,
|
||||
expression: true,
|
||||
}
|
||||
input: {
|
||||
console.log('foo');
|
||||
console.log.apply(console, arguments);
|
||||
}
|
||||
expect: {
|
||||
// with regular compression these will be stripped out as well
|
||||
void 0;
|
||||
void 0;
|
||||
}
|
||||
}
|
||||
|
||||
drop_value: {
|
||||
options = {
|
||||
expression: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(1, [2, foo()], 3, {a:1, b:bar()});
|
||||
}
|
||||
expect: {
|
||||
foo(), {a:1, b:bar()};
|
||||
}
|
||||
}
|
||||
|
||||
wrongly_optimized: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
booleans: true,
|
||||
evaluate: true,
|
||||
expression: true,
|
||||
}
|
||||
input: {
|
||||
function func() {
|
||||
foo();
|
||||
}
|
||||
if (func() || true) {
|
||||
bar();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function func() {
|
||||
foo();
|
||||
}
|
||||
// TODO: optimize to `func(), bar()`
|
||||
if (func(), !0) bar();
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_1: {
|
||||
options = {
|
||||
expression: true,
|
||||
negate_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function(){ stuff() })();
|
||||
}
|
||||
expect: {
|
||||
(function(){ stuff() })();
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_3: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
negate_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
expect: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_3_off: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
negate_iife: false,
|
||||
}
|
||||
input: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
expect: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_4: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
negate_iife: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
(function(){
|
||||
console.log("something");
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false), function(){
|
||||
console.log("something");
|
||||
}();
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_5: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
negate_iife: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
if ((function(){ return t })()) {
|
||||
foo(true);
|
||||
} else {
|
||||
bar(false);
|
||||
}
|
||||
(function(){
|
||||
console.log("something");
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function(){ return t })() ? foo(true) : bar(false), function(){
|
||||
console.log("something");
|
||||
}();
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_5_off: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
negate_iife: false,
|
||||
sequences: true,
|
||||
};
|
||||
input: {
|
||||
if ((function(){ return t })()) {
|
||||
foo(true);
|
||||
} else {
|
||||
bar(false);
|
||||
}
|
||||
(function(){
|
||||
console.log("something");
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function(){ return t })() ? foo(true) : bar(false), function(){
|
||||
console.log("something");
|
||||
}();
|
||||
}
|
||||
}
|
||||
|
||||
issue_1254_negate_iife_true: {
|
||||
options = {
|
||||
expression: true,
|
||||
negate_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
return function() {
|
||||
console.log('test')
|
||||
};
|
||||
})()();
|
||||
}
|
||||
expect_exact: '(function(){return function(){console.log("test")}})()();'
|
||||
}
|
||||
|
||||
issue_1254_negate_iife_nested: {
|
||||
options = {
|
||||
expression: true,
|
||||
negate_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
return function() {
|
||||
console.log('test')
|
||||
};
|
||||
})()()()()();
|
||||
}
|
||||
expect_exact: '(function(){return function(){console.log("test")}})()()()()();'
|
||||
}
|
||||
|
||||
conditional: {
|
||||
options = {
|
||||
expression: true,
|
||||
pure_funcs: [ "pure" ],
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
pure(1 | a() ? 2 & b() : 7 ^ c());
|
||||
pure(1 | a() ? 2 & b() : 5);
|
||||
pure(1 | a() ? 4 : 7 ^ c());
|
||||
pure(1 | a() ? 4 : 5);
|
||||
pure(3 ? 2 & b() : 7 ^ c());
|
||||
pure(3 ? 2 & b() : 5);
|
||||
pure(3 ? 4 : 7 ^ c());
|
||||
pure(3 ? 4 : 5);
|
||||
}
|
||||
expect: {
|
||||
1 | a() ? b() : c();
|
||||
1 | a() && b();
|
||||
1 | a() || c();
|
||||
a();
|
||||
3 ? b() : c();
|
||||
3 && b();
|
||||
3 || c();
|
||||
pure(3 ? 4 : 5);
|
||||
}
|
||||
}
|
||||
|
||||
limit_1: {
|
||||
options = {
|
||||
expression: true,
|
||||
sequences: 3,
|
||||
}
|
||||
input: {
|
||||
a;
|
||||
b;
|
||||
c;
|
||||
d;
|
||||
e;
|
||||
f;
|
||||
g;
|
||||
h;
|
||||
i;
|
||||
j;
|
||||
k;
|
||||
}
|
||||
expect: {
|
||||
// Turned into a single return statement
|
||||
// so it can no longer be split into lines
|
||||
a,b,c,d,e,f,g,h,i,j,k;
|
||||
}
|
||||
}
|
||||
|
||||
iife: {
|
||||
options = {
|
||||
expression: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
x = 42;
|
||||
(function a() {})();
|
||||
!function b() {}();
|
||||
~function c() {}();
|
||||
+function d() {}();
|
||||
-function e() {}();
|
||||
void function f() {}();
|
||||
typeof function g() {}();
|
||||
}
|
||||
expect: {
|
||||
x = 42, function a() {}(), function b() {}(), function c() {}(),
|
||||
function d() {}(), function e() {}(), function f() {}(), typeof function g() {}();
|
||||
}
|
||||
}
|
||||
@@ -50,6 +50,7 @@ this_binding_conditionals: {
|
||||
this_binding_collapse_vars: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
toplevel: true,
|
||||
};
|
||||
input: {
|
||||
var c = a; c();
|
||||
|
||||
@@ -213,6 +213,228 @@ evaluate: {
|
||||
a();
|
||||
for(;;)
|
||||
c();
|
||||
d();
|
||||
// rule disabled due to issue_1532
|
||||
do d(); while (false);
|
||||
}
|
||||
}
|
||||
|
||||
issue_1532: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y) {
|
||||
do {
|
||||
if (x) break;
|
||||
foo();
|
||||
} while (false);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(x, y) {
|
||||
do {
|
||||
if (x) break;
|
||||
foo();
|
||||
} while (false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_186: {
|
||||
beautify = {
|
||||
beautify: false,
|
||||
screw_ie8: true,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
if (foo())
|
||||
do
|
||||
do
|
||||
alert(x);
|
||||
while (--x);
|
||||
while (x);
|
||||
else
|
||||
bar();
|
||||
}
|
||||
expect_exact: 'var x=3;if(foo())do{do{alert(x)}while(--x)}while(x);else bar();'
|
||||
}
|
||||
|
||||
issue_186_ie8: {
|
||||
beautify = {
|
||||
beautify: false,
|
||||
screw_ie8: false,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
if (foo())
|
||||
do
|
||||
do
|
||||
alert(x);
|
||||
while (--x);
|
||||
while (x);
|
||||
else
|
||||
bar();
|
||||
}
|
||||
expect_exact: 'var x=3;if(foo()){do{do{alert(x)}while(--x)}while(x)}else bar();'
|
||||
}
|
||||
|
||||
issue_186_beautify: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
screw_ie8: true,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
if (foo())
|
||||
do
|
||||
do
|
||||
alert(x);
|
||||
while (--x);
|
||||
while (x);
|
||||
else
|
||||
bar();
|
||||
}
|
||||
expect_exact: [
|
||||
'var x = 3;',
|
||||
'',
|
||||
'if (foo()) do {',
|
||||
' do {',
|
||||
' alert(x);',
|
||||
' } while (--x);',
|
||||
'} while (x); else bar();',
|
||||
]
|
||||
}
|
||||
|
||||
issue_186_beautify_ie8: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
screw_ie8: false,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
if (foo())
|
||||
do
|
||||
do
|
||||
alert(x);
|
||||
while (--x);
|
||||
while (x);
|
||||
else
|
||||
bar();
|
||||
}
|
||||
expect_exact: [
|
||||
'var x = 3;',
|
||||
'',
|
||||
'if (foo()) {',
|
||||
' do {',
|
||||
' do {',
|
||||
' alert(x);',
|
||||
' } while (--x);',
|
||||
' } while (x);',
|
||||
'} else bar();',
|
||||
]
|
||||
}
|
||||
|
||||
issue_186_bracketize: {
|
||||
beautify = {
|
||||
beautify: false,
|
||||
bracketize: true,
|
||||
screw_ie8: true,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
if (foo())
|
||||
do
|
||||
do
|
||||
alert(x);
|
||||
while (--x);
|
||||
while (x);
|
||||
else
|
||||
bar();
|
||||
}
|
||||
expect_exact: 'var x=3;if(foo()){do{do{alert(x)}while(--x)}while(x)}else{bar()}'
|
||||
}
|
||||
|
||||
issue_186_bracketize_ie8: {
|
||||
beautify = {
|
||||
beautify: false,
|
||||
bracketize: true,
|
||||
screw_ie8: false,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
if (foo())
|
||||
do
|
||||
do
|
||||
alert(x);
|
||||
while (--x);
|
||||
while (x);
|
||||
else
|
||||
bar();
|
||||
}
|
||||
expect_exact: 'var x=3;if(foo()){do{do{alert(x)}while(--x)}while(x)}else{bar()}'
|
||||
}
|
||||
|
||||
issue_186_beautify_bracketize: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
bracketize: true,
|
||||
screw_ie8: true,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
if (foo())
|
||||
do
|
||||
do
|
||||
alert(x);
|
||||
while (--x);
|
||||
while (x);
|
||||
else
|
||||
bar();
|
||||
}
|
||||
expect_exact: [
|
||||
'var x = 3;',
|
||||
'',
|
||||
'if (foo()) {',
|
||||
' do {',
|
||||
' do {',
|
||||
' alert(x);',
|
||||
' } while (--x);',
|
||||
' } while (x);',
|
||||
'} else {',
|
||||
' bar();',
|
||||
'}',
|
||||
]
|
||||
}
|
||||
|
||||
issue_186_beautify_bracketize_ie8: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
bracketize: true,
|
||||
screw_ie8: false,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
if (foo())
|
||||
do
|
||||
do
|
||||
alert(x);
|
||||
while (--x);
|
||||
while (x);
|
||||
else
|
||||
bar();
|
||||
}
|
||||
expect_exact: [
|
||||
'var x = 3;',
|
||||
'',
|
||||
'if (foo()) {',
|
||||
' do {',
|
||||
' do {',
|
||||
' alert(x);',
|
||||
' } while (--x);',
|
||||
' } while (x);',
|
||||
'} else {',
|
||||
' bar();',
|
||||
'}',
|
||||
]
|
||||
}
|
||||
|
||||
@@ -7,7 +7,13 @@ too_short: {
|
||||
return { c: 42, d: a(), e: "foo"};
|
||||
}
|
||||
}
|
||||
expect_exact: 'function f(a){\nreturn{\nc:42,\nd:a(),\ne:"foo"}}'
|
||||
expect_exact: [
|
||||
'function f(a){',
|
||||
'return{',
|
||||
'c:42,',
|
||||
'd:a(),',
|
||||
'e:"foo"}}',
|
||||
]
|
||||
expect_warnings: [
|
||||
"WARN: Output exceeds 10 characters"
|
||||
]
|
||||
@@ -22,7 +28,12 @@ just_enough: {
|
||||
return { c: 42, d: a(), e: "foo"};
|
||||
}
|
||||
}
|
||||
expect_exact: 'function f(a){\nreturn{c:42,\nd:a(),e:"foo"}\n}'
|
||||
expect_exact: [
|
||||
'function f(a){',
|
||||
'return{c:42,',
|
||||
'd:a(),e:"foo"}',
|
||||
'}',
|
||||
]
|
||||
expect_warnings: [
|
||||
]
|
||||
}
|
||||
|
||||
@@ -32,16 +32,57 @@ negate_iife_2: {
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_2_side_effects: {
|
||||
options = {
|
||||
negate_iife: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(function(){ return {} })().x = 10; // should not transform this one
|
||||
}
|
||||
expect: {
|
||||
(function(){ return {} })().x = 10;
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_3: {
|
||||
options = {
|
||||
negate_iife: true,
|
||||
conditionals: true
|
||||
};
|
||||
input: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
expect: {
|
||||
!function(){ return t }() ? console.log(false) : console.log(true);
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_3_evaluate: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
negate_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function(){ return true })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
expect: {
|
||||
!function(){ return true }() ? console.log(false) : console.log(true);
|
||||
console.log(true);
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_3_side_effects: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
negate_iife: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
expect: {
|
||||
!function(){ return t }() ? console.log(false) : console.log(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,11 +91,25 @@ negate_iife_3_off: {
|
||||
negate_iife: false,
|
||||
conditionals: true,
|
||||
};
|
||||
input: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
expect: {
|
||||
!function(){ return t }() ? console.log(false) : console.log(true);
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_3_off_evaluate: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
negate_iife: false,
|
||||
}
|
||||
input: {
|
||||
(function(){ return true })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
expect: {
|
||||
!function(){ return true }() ? console.log(false) : console.log(true);
|
||||
console.log(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,13 +120,13 @@ negate_iife_4: {
|
||||
sequences: true
|
||||
};
|
||||
input: {
|
||||
(function(){ return true })() ? console.log(true) : console.log(false);
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
(function(){
|
||||
console.log("something");
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
!function(){ return true }() ? console.log(false) : console.log(true), function(){
|
||||
!function(){ return t }() ? console.log(false) : console.log(true), function(){
|
||||
console.log("something");
|
||||
}();
|
||||
}
|
||||
@@ -86,7 +141,7 @@ sequence_off: {
|
||||
};
|
||||
input: {
|
||||
function f() {
|
||||
(function(){ return true })() ? console.log(true) : console.log(false);
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
(function(){
|
||||
console.log("something");
|
||||
})();
|
||||
@@ -95,19 +150,19 @@ sequence_off: {
|
||||
(function(){
|
||||
console.log("something");
|
||||
})();
|
||||
(function(){ return true })() ? console.log(true) : console.log(false);
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
!function(){ return true }() ? console.log(false) : console.log(true), function(){
|
||||
!function(){ return t }() ? console.log(false) : console.log(true), function(){
|
||||
console.log("something");
|
||||
}();
|
||||
}
|
||||
function g() {
|
||||
(function(){
|
||||
console.log("something");
|
||||
})(), function(){ return true }() ? console.log(true) : console.log(false);
|
||||
})(), function(){ return t }() ? console.log(true) : console.log(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -119,7 +174,7 @@ negate_iife_5: {
|
||||
conditionals: true,
|
||||
};
|
||||
input: {
|
||||
if ((function(){ return true })()) {
|
||||
if ((function(){ return t })()) {
|
||||
foo(true);
|
||||
} else {
|
||||
bar(false);
|
||||
@@ -129,7 +184,7 @@ negate_iife_5: {
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
!function(){ return true }() ? bar(false) : foo(true), function(){
|
||||
!function(){ return t }() ? bar(false) : foo(true), function(){
|
||||
console.log("something");
|
||||
}();
|
||||
}
|
||||
@@ -142,7 +197,7 @@ negate_iife_5_off: {
|
||||
conditionals: true,
|
||||
};
|
||||
input: {
|
||||
if ((function(){ return true })()) {
|
||||
if ((function(){ return t })()) {
|
||||
foo(true);
|
||||
} else {
|
||||
bar(false);
|
||||
@@ -152,7 +207,7 @@ negate_iife_5_off: {
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
!function(){ return true }() ? bar(false) : foo(true), function(){
|
||||
!function(){ return t }() ? bar(false) : foo(true), function(){
|
||||
console.log("something");
|
||||
}();
|
||||
}
|
||||
@@ -320,3 +375,35 @@ issue_1288: {
|
||||
}(0);
|
||||
}
|
||||
}
|
||||
|
||||
issue_1288_side_effects: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
negate_iife: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
if (w) ;
|
||||
else {
|
||||
(function f() {})();
|
||||
}
|
||||
if (!x) {
|
||||
(function() {
|
||||
x = {};
|
||||
})();
|
||||
}
|
||||
if (y)
|
||||
(function() {})();
|
||||
else
|
||||
(function(z) {
|
||||
return z;
|
||||
})(0);
|
||||
}
|
||||
expect: {
|
||||
w;
|
||||
x || function() {
|
||||
x = {};
|
||||
}();
|
||||
y;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,3 +17,139 @@ hex_numbers_in_parentheses_for_prototype_functions: {
|
||||
}
|
||||
expect_exact: "-2;(-2).toFixed(0);2;2..toFixed(0);.2;.2.toFixed(0);2e-8;2e-8.toFixed(0);0xde0b6b3a7640080;(0xde0b6b3a7640080).toFixed(0);"
|
||||
}
|
||||
|
||||
comparisons: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
console.log(
|
||||
~x === 42,
|
||||
x % n === 42
|
||||
);
|
||||
}
|
||||
expect: {
|
||||
console.log(
|
||||
42 == ~x,
|
||||
x % n == 42
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
evaluate_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: false,
|
||||
}
|
||||
input: {
|
||||
console.log(
|
||||
x + 1 + 2,
|
||||
x * 1 * 2,
|
||||
+x + 1 + 2,
|
||||
1 + x + 2 + 3,
|
||||
1 | x | 2 | 3,
|
||||
1 + x-- + 2 + 3,
|
||||
1 + (x*y + 2) + 3,
|
||||
1 + (2 + x + 3),
|
||||
1 + (2 + ~x + 3),
|
||||
-y + (2 + ~x + 3),
|
||||
1 & (2 & x & 3),
|
||||
1 + (2 + (x |= 0) + 3)
|
||||
);
|
||||
}
|
||||
expect: {
|
||||
console.log(
|
||||
x + 1 + 2,
|
||||
1 * x * 2,
|
||||
+x + 1 + 2,
|
||||
1 + x + 2 + 3,
|
||||
3 | x,
|
||||
1 + x-- + 2 + 3,
|
||||
x*y + 2 + 1 + 3,
|
||||
1 + (2 + x + 3),
|
||||
2 + ~x + 3 + 1,
|
||||
-y + (2 + ~x + 3),
|
||||
0 & x,
|
||||
2 + (x |= 0) + 3 + 1
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
evaluate_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: true,
|
||||
}
|
||||
input: {
|
||||
console.log(
|
||||
x + 1 + 2,
|
||||
x * 1 * 2,
|
||||
+x + 1 + 2,
|
||||
1 + x + 2 + 3,
|
||||
1 | x | 2 | 3,
|
||||
1 + x-- + 2 + 3,
|
||||
1 + (x*y + 2) + 3,
|
||||
1 + (2 + x + 3),
|
||||
1 & (2 & x & 3),
|
||||
1 + (2 + (x |= 0) + 3)
|
||||
);
|
||||
}
|
||||
expect: {
|
||||
console.log(
|
||||
x + 1 + 2,
|
||||
2 * x,
|
||||
3 + +x,
|
||||
1 + x + 2 + 3,
|
||||
3 | x,
|
||||
6 + x--,
|
||||
6 + x*y,
|
||||
1 + (2 + x + 3),
|
||||
0 & x,
|
||||
6 + (x |= 0)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
evaluate_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
unsafe_math: true,
|
||||
}
|
||||
input: {
|
||||
console.log(1 + Number(x) + 2);
|
||||
}
|
||||
expect: {
|
||||
console.log(3 + +x);
|
||||
}
|
||||
}
|
||||
|
||||
evaluate_4: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
console.log(
|
||||
1+ +a,
|
||||
+a+1,
|
||||
1+-a,
|
||||
-a+1,
|
||||
+a+ +b,
|
||||
+a+-b,
|
||||
-a+ +b,
|
||||
-a+-b
|
||||
);
|
||||
}
|
||||
expect: {
|
||||
console.log(
|
||||
+a+1,
|
||||
+a+1,
|
||||
1-a,
|
||||
1-a,
|
||||
+a+ +b,
|
||||
+a-b,
|
||||
-a+ +b,
|
||||
-a-b
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ reduce_vars: {
|
||||
C : 0
|
||||
},
|
||||
reduce_vars : true,
|
||||
toplevel : true,
|
||||
unused : true
|
||||
}
|
||||
input: {
|
||||
@@ -452,22 +453,26 @@ multi_def_2: {
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
if (code == 16)
|
||||
var bitsLength = 2, bitsOffset = 3, what = len;
|
||||
else if (code == 17)
|
||||
var bitsLength = 3, bitsOffset = 3, what = (len = 0);
|
||||
else if (code == 18)
|
||||
var bitsLength = 7, bitsOffset = 11, what = (len = 0);
|
||||
var repeatLength = this.getBits(bitsLength) + bitsOffset;
|
||||
function f(){
|
||||
if (code == 16)
|
||||
var bitsLength = 2, bitsOffset = 3, what = len;
|
||||
else if (code == 17)
|
||||
var bitsLength = 3, bitsOffset = 3, what = (len = 0);
|
||||
else if (code == 18)
|
||||
var bitsLength = 7, bitsOffset = 11, what = (len = 0);
|
||||
var repeatLength = this.getBits(bitsLength) + bitsOffset;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
if (16 == code)
|
||||
var bitsLength = 2, bitsOffset = 3, what = len;
|
||||
else if (17 == code)
|
||||
var bitsLength = 3, bitsOffset = 3, what = (len = 0);
|
||||
else if (18 == code)
|
||||
var bitsLength = 7, bitsOffset = 11, what = (len = 0);
|
||||
var repeatLength = this.getBits(bitsLength) + bitsOffset;
|
||||
function f(){
|
||||
if (16 == code)
|
||||
var bitsLength = 2, bitsOffset = 3, what = len;
|
||||
else if (17 == code)
|
||||
var bitsLength = 3, bitsOffset = 3, what = (len = 0);
|
||||
else if (18 == code)
|
||||
var bitsLength = 7, bitsOffset = 11, what = (len = 0);
|
||||
var repeatLength = this.getBits(bitsLength) + bitsOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -477,12 +482,16 @@ use_before_var: {
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(t);
|
||||
var t = 1;
|
||||
function f(){
|
||||
console.log(t);
|
||||
var t = 1;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
console.log(t);
|
||||
var t = 1;
|
||||
function f(){
|
||||
console.log(t);
|
||||
var t = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -492,22 +501,20 @@ inner_var_if: {
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f(){
|
||||
return 0;
|
||||
function f(a){
|
||||
if (a)
|
||||
var t = 1;
|
||||
if (!t)
|
||||
console.log(t);
|
||||
}
|
||||
if (f())
|
||||
var t = 1;
|
||||
if (!t)
|
||||
console.log(t);
|
||||
}
|
||||
expect: {
|
||||
function f(){
|
||||
return 0;
|
||||
function f(a){
|
||||
if (a)
|
||||
var t = 1;
|
||||
if (!t)
|
||||
console.log(t);
|
||||
}
|
||||
if (f())
|
||||
var t = 1;
|
||||
if (!t)
|
||||
console.log(t);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,24 +524,22 @@ inner_var_label: {
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f(){
|
||||
return 1;
|
||||
function f(a){
|
||||
l: {
|
||||
if (a) break l;
|
||||
var t = 1;
|
||||
}
|
||||
console.log(t);
|
||||
}
|
||||
l: {
|
||||
if (f()) break l;
|
||||
var t = 1;
|
||||
}
|
||||
console.log(t);
|
||||
}
|
||||
expect: {
|
||||
function f(){
|
||||
return 1;
|
||||
function f(a){
|
||||
l: {
|
||||
if (a) break l;
|
||||
var t = 1;
|
||||
}
|
||||
console.log(t);
|
||||
}
|
||||
l: {
|
||||
if (f()) break l;
|
||||
var t = 1;
|
||||
}
|
||||
console.log(t);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -544,48 +549,805 @@ inner_var_for: {
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
x(a, b, d);
|
||||
for (var b = 2, c = 3; x(a, b, c, d); x(a, b, c, d)) {
|
||||
var d = 4, e = 5;
|
||||
function f() {
|
||||
var a = 1;
|
||||
x(a, b, d);
|
||||
for (var b = 2, c = 3; x(a, b, c, d); x(a, b, c, d)) {
|
||||
var d = 4, e = 5;
|
||||
x(a, b, c, d, e);
|
||||
}
|
||||
x(a, b, c, d, e);
|
||||
}
|
||||
x(a, b, c, d, e)
|
||||
}
|
||||
expect: {
|
||||
var a = 1;
|
||||
x(1, b, d);
|
||||
for (var b = 2, c = 3; x(1, b, 3, d); x(1, b, 3, d)) {
|
||||
var d = 4, e = 5;
|
||||
function f() {
|
||||
var a = 1;
|
||||
x(1, b, d);
|
||||
for (var b = 2, c = 3; x(1, b, 3, d); x(1, b, 3, d)) {
|
||||
var d = 4, e = 5;
|
||||
x(1, b, 3, d, e);
|
||||
}
|
||||
x(1, b, 3, d, e);
|
||||
}
|
||||
x(1, b, 3, d, e);
|
||||
}
|
||||
}
|
||||
|
||||
inner_var_for_in: {
|
||||
inner_var_for_in_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1, b = 2;
|
||||
for (b in (function() {
|
||||
return x(a, b, c);
|
||||
})()) {
|
||||
var c = 3, d = 4;
|
||||
function f() {
|
||||
var a = 1, b = 2;
|
||||
for (b in (function() {
|
||||
return x(a, b, c);
|
||||
})()) {
|
||||
var c = 3, d = 4;
|
||||
x(a, b, c, d);
|
||||
}
|
||||
x(a, b, c, d);
|
||||
}
|
||||
x(a, b, c, d);
|
||||
}
|
||||
expect: {
|
||||
var a = 1, b = 2;
|
||||
for (b in (function() {
|
||||
return x(1, b, c);
|
||||
})()) {
|
||||
var c = 3, d = 4;
|
||||
function f() {
|
||||
var a = 1, b = 2;
|
||||
for (b in (function() {
|
||||
return x(1, b, c);
|
||||
})()) {
|
||||
var c = 3, d = 4;
|
||||
x(1, b, c, d);
|
||||
}
|
||||
x(1, b, c, d);
|
||||
}
|
||||
x(1, b, c, d);
|
||||
}
|
||||
}
|
||||
|
||||
inner_var_for_in_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
for (var long_name in {})
|
||||
console.log(long_name);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
for (var long_name in {})
|
||||
console.log(long_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inner_var_catch: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
try {
|
||||
a();
|
||||
} catch (e) {
|
||||
var b = 1;
|
||||
}
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
try {
|
||||
a();
|
||||
} catch (e) {
|
||||
var b = 1;
|
||||
}
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_1533_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var id = "";
|
||||
for (id in {break: "me"})
|
||||
console.log(id);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
var id = "";
|
||||
for (id in {break: "me"})
|
||||
console.log(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_1533_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var id = "";
|
||||
for (var id in {break: "me"})
|
||||
console.log(id);
|
||||
console.log(id);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
var id = "";
|
||||
for (var id in {break: "me"})
|
||||
console.log(id);
|
||||
console.log(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
toplevel_on: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel:true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
console.log(x);
|
||||
}
|
||||
expect: {
|
||||
console.log(3);
|
||||
}
|
||||
}
|
||||
|
||||
toplevel_off: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel:false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
console.log(x);
|
||||
}
|
||||
expect: {
|
||||
var x = 3;
|
||||
console.log(x);
|
||||
}
|
||||
}
|
||||
|
||||
toplevel_on_loops_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
loops: true,
|
||||
reduce_vars: true,
|
||||
toplevel:true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function bar() {
|
||||
console.log("bar:", --x);
|
||||
}
|
||||
var x = 3;
|
||||
do
|
||||
bar();
|
||||
while (x);
|
||||
}
|
||||
expect: {
|
||||
var x = 3;
|
||||
do
|
||||
(function() {
|
||||
console.log("bar:", --x);
|
||||
})();
|
||||
while (x);
|
||||
}
|
||||
}
|
||||
|
||||
toplevel_off_loops_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
loops: true,
|
||||
reduce_vars: true,
|
||||
toplevel:false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function bar() {
|
||||
console.log("bar:", --x);
|
||||
}
|
||||
var x = 3;
|
||||
do
|
||||
bar();
|
||||
while (x);
|
||||
}
|
||||
expect: {
|
||||
function bar() {
|
||||
console.log("bar:", --x);
|
||||
}
|
||||
var x = 3;
|
||||
do
|
||||
bar();
|
||||
while (x);
|
||||
}
|
||||
}
|
||||
|
||||
toplevel_on_loops_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
loops: true,
|
||||
reduce_vars: true,
|
||||
toplevel:true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function bar() {
|
||||
console.log("bar:");
|
||||
}
|
||||
var x = 3;
|
||||
do
|
||||
bar();
|
||||
while (x);
|
||||
}
|
||||
expect: {
|
||||
for (;;) (function() {
|
||||
console.log("bar:");
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
toplevel_off_loops_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
loops: true,
|
||||
reduce_vars: true,
|
||||
toplevel:false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function bar() {
|
||||
console.log("bar:");
|
||||
}
|
||||
var x = 3;
|
||||
do
|
||||
bar();
|
||||
while (x);
|
||||
}
|
||||
expect: {
|
||||
function bar() {
|
||||
console.log("bar:");
|
||||
}
|
||||
var x = 3;
|
||||
do
|
||||
bar();
|
||||
while (x);
|
||||
}
|
||||
}
|
||||
|
||||
toplevel_on_loops_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
loops: true,
|
||||
reduce_vars: true,
|
||||
toplevel:true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
while (x) bar();
|
||||
}
|
||||
expect: {
|
||||
for (;;) bar();
|
||||
}
|
||||
}
|
||||
|
||||
toplevel_off_loops_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
loops: true,
|
||||
reduce_vars: true,
|
||||
toplevel:false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
while (x) bar();
|
||||
}
|
||||
expect: {
|
||||
var x = 3;
|
||||
for (;x;) bar();
|
||||
}
|
||||
}
|
||||
|
||||
defun_reference: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
function g() {
|
||||
x();
|
||||
return a;
|
||||
}
|
||||
var a = h();
|
||||
var b = 2;
|
||||
return a + b;
|
||||
function h() {
|
||||
y();
|
||||
return b;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
function g() {
|
||||
x();
|
||||
return a;
|
||||
}
|
||||
var a = h();
|
||||
var b = 2;
|
||||
return a + b;
|
||||
function h() {
|
||||
y();
|
||||
return b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defun_inline_1: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
return g(2) + h();
|
||||
function g(b) {
|
||||
return b;
|
||||
}
|
||||
function h() {
|
||||
return h();
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
return function(b) {
|
||||
return b;
|
||||
}(2) + h();
|
||||
function h() {
|
||||
return h();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defun_inline_2: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
function g(b) {
|
||||
return b;
|
||||
}
|
||||
function h() {
|
||||
return h();
|
||||
}
|
||||
return g(2) + h();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
function h() {
|
||||
return h();
|
||||
}
|
||||
return function(b) {
|
||||
return b;
|
||||
}(2) + h();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defun_inline_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
return g(2);
|
||||
function g(b) {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defun_call: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
return g() + h(1) - h(g(), 2, 3);
|
||||
function g() {
|
||||
return 4;
|
||||
}
|
||||
function h(a) {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
return 4 + h(1) - h(4);
|
||||
function h(a) {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defun_redefine: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
function g() {
|
||||
return 1;
|
||||
}
|
||||
function h() {
|
||||
return 2;
|
||||
}
|
||||
g = function() {
|
||||
return 3;
|
||||
};
|
||||
return g() + h();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
function g() {
|
||||
return 1;
|
||||
}
|
||||
g = function() {
|
||||
return 3;
|
||||
};
|
||||
return g() + 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func_inline: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var g = function() {
|
||||
return 1;
|
||||
};
|
||||
console.log(g() + h());
|
||||
var h = function() {
|
||||
return 2;
|
||||
};
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
console.log(1 + h());
|
||||
var h = function() {
|
||||
return 2;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func_modified: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
function a() { return 1; }
|
||||
function b() { return 2; }
|
||||
function c() { return 3; }
|
||||
b.inject = [];
|
||||
c = function() { return 4; };
|
||||
return a() + b() + c();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
function b() { return 2; }
|
||||
function c() { return 3; }
|
||||
b.inject = [];
|
||||
c = function() { return 4; };
|
||||
return 1 + 2 + c();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defun_label: {
|
||||
options = {
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
!function() {
|
||||
function f(a) {
|
||||
L: {
|
||||
if (a) break L;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
console.log(f(2));
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
!function() {
|
||||
console.log(function(a) {
|
||||
L: {
|
||||
if (a) break L;
|
||||
return 1;
|
||||
}
|
||||
}(2));
|
||||
}();
|
||||
}
|
||||
}
|
||||
|
||||
double_reference: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var g = function g() {
|
||||
g();
|
||||
};
|
||||
g();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
(function g() {
|
||||
g();
|
||||
})();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
iife_arguments_1: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(x) {
|
||||
console.log(x() === arguments[0]);
|
||||
})(function f() {
|
||||
return f;
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
(function(x) {
|
||||
console.log(x() === arguments[0]);
|
||||
})(function f() {
|
||||
return f;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
iife_arguments_2: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
var x = function f() {
|
||||
return f;
|
||||
};
|
||||
console.log(x() === arguments[0]);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
console.log(function f() {
|
||||
return f;
|
||||
}() === arguments[0]);
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
iife_eval_1: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(x) {
|
||||
console.log(x() === eval("x"));
|
||||
})(function f() {
|
||||
return f;
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
(function(x) {
|
||||
console.log(x() === eval("x"));
|
||||
})(function f() {
|
||||
return f;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
iife_eval_2: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
var x = function f() {
|
||||
return f;
|
||||
};
|
||||
console.log(x() === eval("x"));
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
var x = function f() {
|
||||
return f;
|
||||
};
|
||||
console.log(x() === eval("x"));
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
iife_func_side_effects: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(a, b, c) {
|
||||
return b();
|
||||
})(x(), function() {
|
||||
return y();
|
||||
}, z());
|
||||
}
|
||||
expect: {
|
||||
(function(a, b, c) {
|
||||
return function() {
|
||||
return y();
|
||||
}();
|
||||
})(x(), 0, z());
|
||||
}
|
||||
}
|
||||
|
||||
issue_1595_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function f(a) {
|
||||
return f(a + 1);
|
||||
})(2);
|
||||
}
|
||||
expect: {
|
||||
(function f(a) {
|
||||
return f(a + 1);
|
||||
})(2);
|
||||
}
|
||||
}
|
||||
|
||||
issue_1595_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function f(a) {
|
||||
return g(a + 1);
|
||||
})(2);
|
||||
}
|
||||
expect: {
|
||||
(function(a) {
|
||||
return g(a + 1);
|
||||
})(2);
|
||||
}
|
||||
}
|
||||
|
||||
issue_1595_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function f(a) {
|
||||
return g(a + 1);
|
||||
})(2);
|
||||
}
|
||||
expect: {
|
||||
(function(a) {
|
||||
return g(3);
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
issue_1595_4: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function iife(a, b, c) {
|
||||
console.log(a, b, c);
|
||||
if (a) iife(a - 1, b, c);
|
||||
})(3, 4, 5);
|
||||
}
|
||||
expect: {
|
||||
(function iife(a, b, c) {
|
||||
console.log(a, b, c);
|
||||
if (a) iife(a - 1, b, c);
|
||||
})(3, 4, 5);
|
||||
}
|
||||
}
|
||||
|
||||
issue_1606: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_vars: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var a;
|
||||
function g(){};
|
||||
var b = 2;
|
||||
x(b);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
var a, b;
|
||||
function g(){};
|
||||
b = 2;
|
||||
x(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,26 @@ dont_screw: {
|
||||
expect_exact: 'f("\\x0B");';
|
||||
}
|
||||
|
||||
do_screw_constants: {
|
||||
options = {
|
||||
screw_ie8: true,
|
||||
}
|
||||
input: {
|
||||
f(undefined, Infinity);
|
||||
}
|
||||
expect_exact: "f(void 0,1/0);"
|
||||
}
|
||||
|
||||
dont_screw_constants: {
|
||||
options = {
|
||||
screw_ie8: false,
|
||||
}
|
||||
input: {
|
||||
f(undefined, Infinity);
|
||||
}
|
||||
expect_exact: "f(undefined,Infinity);"
|
||||
}
|
||||
|
||||
do_screw_try_catch: {
|
||||
options = { screw_ie8: true };
|
||||
mangle = { screw_ie8: true };
|
||||
@@ -46,8 +66,6 @@ do_screw_try_catch: {
|
||||
}
|
||||
|
||||
dont_screw_try_catch: {
|
||||
// This test is known to generate incorrect code for screw_ie8=false.
|
||||
// Update expected result in the event this bug is ever fixed.
|
||||
options = { screw_ie8: false };
|
||||
mangle = { screw_ie8: false };
|
||||
beautify = { screw_ie8: false };
|
||||
@@ -64,11 +82,11 @@ dont_screw_try_catch: {
|
||||
}
|
||||
expect: {
|
||||
bad = function(n){
|
||||
return function(n){
|
||||
return function(t){
|
||||
try{
|
||||
t()
|
||||
} catch(t) {
|
||||
n(t)
|
||||
n()
|
||||
} catch(n) {
|
||||
t(n)
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -104,8 +122,6 @@ do_screw_try_catch_undefined: {
|
||||
}
|
||||
|
||||
dont_screw_try_catch_undefined: {
|
||||
// This test is known to generate incorrect code for screw_ie8=false.
|
||||
// Update expected result in the event this bug is ever fixed.
|
||||
options = { screw_ie8: false };
|
||||
mangle = { screw_ie8: false };
|
||||
beautify = { screw_ie8: false };
|
||||
@@ -121,14 +137,84 @@ dont_screw_try_catch_undefined: {
|
||||
};
|
||||
}
|
||||
expect: {
|
||||
function a(o){
|
||||
function a(n){
|
||||
try{
|
||||
throw "Stuff"
|
||||
} catch (n) {
|
||||
console.log("caught: "+n)
|
||||
} catch (undefined) {
|
||||
console.log("caught: " + undefined)
|
||||
}
|
||||
console.log("undefined is " + n);
|
||||
return o === n
|
||||
console.log("undefined is " + undefined);
|
||||
return n === undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reduce_vars: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
screw_ie8: false,
|
||||
unused: true,
|
||||
}
|
||||
mangle = {
|
||||
screw_ie8: false,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var a;
|
||||
try {
|
||||
x();
|
||||
} catch (a) {
|
||||
y();
|
||||
}
|
||||
alert(a);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
var t;
|
||||
try {
|
||||
x();
|
||||
} catch (t) {
|
||||
y();
|
||||
}
|
||||
alert(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_1586_1: {
|
||||
options = {
|
||||
screw_ie8: false,
|
||||
}
|
||||
mangle = {
|
||||
screw_ie8: false,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
try {
|
||||
} catch (err) {
|
||||
console.log(err.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect_exact: "function f(){try{}catch(c){console.log(c.message)}}"
|
||||
}
|
||||
|
||||
issue_1586_2: {
|
||||
options = {
|
||||
screw_ie8: true,
|
||||
}
|
||||
mangle = {
|
||||
screw_ie8: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
try {
|
||||
} catch (err) {
|
||||
console.log(err.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect_exact: "function f(){try{}catch(c){console.log(c.message)}}"
|
||||
}
|
||||
|
||||
@@ -248,6 +248,39 @@ iife: {
|
||||
}
|
||||
expect: {
|
||||
x = 42, function a() {}(), function b() {}(), function c() {}(),
|
||||
function d() {}(), function e() {}(), function f() {}(), function g() {}()
|
||||
function d() {}(), function e() {}(), function f() {}(), function g() {}();
|
||||
}
|
||||
}
|
||||
|
||||
unsafe_undefined: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
function f(undefined) {
|
||||
if (a)
|
||||
return b;
|
||||
if (c)
|
||||
return d;
|
||||
}
|
||||
function g(undefined) {
|
||||
if (a)
|
||||
return b;
|
||||
if (c)
|
||||
return d;
|
||||
e();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(undefined) {
|
||||
return a ? b : c ? d : undefined;
|
||||
}
|
||||
function g(undefined) {
|
||||
return a ? b : c ? d : void e();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
129
test/compress/transform.js
Normal file
129
test/compress/transform.js
Normal file
@@ -0,0 +1,129 @@
|
||||
booleans_evaluate: {
|
||||
options = {
|
||||
booleans: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof void 0 != "undefined");
|
||||
console.log(1 == 1, 1 === 1)
|
||||
console.log(1 != 1, 1 !== 1)
|
||||
}
|
||||
expect: {
|
||||
console.log(!1);
|
||||
console.log(!0, !0);
|
||||
console.log(!1, !1);
|
||||
}
|
||||
}
|
||||
|
||||
booleans_global_defs: {
|
||||
options = {
|
||||
booleans: true,
|
||||
evaluate: true,
|
||||
global_defs: {
|
||||
A: true,
|
||||
},
|
||||
}
|
||||
input: {
|
||||
console.log(A == 1);
|
||||
}
|
||||
expect: {
|
||||
console.log(!0);
|
||||
}
|
||||
}
|
||||
|
||||
condition_evaluate: {
|
||||
options = {
|
||||
booleans: true,
|
||||
dead_code: false,
|
||||
evaluate: true,
|
||||
loops: false,
|
||||
}
|
||||
input: {
|
||||
while (1 === 2);
|
||||
for (; 1 == true;);
|
||||
if (void 0 == null);
|
||||
}
|
||||
expect: {
|
||||
while (!1);
|
||||
for (; !0;);
|
||||
if (!0);
|
||||
}
|
||||
}
|
||||
|
||||
if_else_empty: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
if ({} ? a : b); else {}
|
||||
}
|
||||
expect: {
|
||||
!{} ? b : a;
|
||||
}
|
||||
}
|
||||
|
||||
label_if_break: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
L: if (true) {
|
||||
a;
|
||||
break L;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
a;
|
||||
}
|
||||
}
|
||||
|
||||
while_if_break: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
loops: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
while (a) {
|
||||
if (b) if(c) d;
|
||||
if (e) break;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
for(; a && (b && c && d, !e););
|
||||
}
|
||||
}
|
||||
|
||||
if_return: {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
function f(w, x, y, z) {
|
||||
if (x) return;
|
||||
if (w) {
|
||||
if (y) return;
|
||||
} else if (z) return;
|
||||
if (x == y) return true;
|
||||
|
||||
if (x) w();
|
||||
if (y) z();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(w, x, y, z) {
|
||||
if (!x) {
|
||||
if (w) {
|
||||
if (y) return;
|
||||
} else if (z) return;
|
||||
return x == y || (x && w(), y && z(), !0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1
test/input/invalid/loop-no-body.js
Normal file
1
test/input/invalid/loop-no-body.js
Normal file
@@ -0,0 +1 @@
|
||||
for (var i = 0; i < 1; i++)
|
||||
@@ -82,7 +82,7 @@ describe("bin/uglifyjs", function () {
|
||||
});
|
||||
});
|
||||
it("Should work with --keep-fnames (mangle & compress)", function (done) {
|
||||
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m -c';
|
||||
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m -c unused=false';
|
||||
|
||||
exec(command, function (err, stdout) {
|
||||
if (err) throw err;
|
||||
@@ -152,7 +152,7 @@ describe("bin/uglifyjs", function () {
|
||||
});
|
||||
});
|
||||
it("Should process inline source map", function(done) {
|
||||
var command = uglifyjscmd + ' test/input/issue-520/input.js -cm toplevel --in-source-map inline --source-map-inline';
|
||||
var command = uglifyjscmd + ' test/input/issue-520/input.js -mc toplevel --in-source-map inline --source-map-inline';
|
||||
|
||||
exec(command, function (err, stdout) {
|
||||
if (err) throw err;
|
||||
@@ -238,4 +238,17 @@ describe("bin/uglifyjs", function () {
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should fail with a missing loop body", function(done) {
|
||||
var command = uglifyjscmd + ' test/input/invalid/loop-no-body.js';
|
||||
|
||||
exec(command, function (err, stdout, stderr) {
|
||||
assert.ok(err);
|
||||
var lines = stderr.split(/\n/);
|
||||
assert.strictEqual(lines[0], "Parse error at test/input/invalid/loop-no-body.js:2,0");
|
||||
assert.strictEqual(lines[1], "for (var i = 0; i < 1; i++) ");
|
||||
assert.strictEqual(lines[2], " ^");
|
||||
assert.strictEqual(lines[3], "SyntaxError: Unexpected token: eof (undefined)");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -72,4 +72,12 @@ describe("comment filters", function() {
|
||||
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
|
||||
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
|
||||
});
|
||||
|
||||
it("Should handle shebang and preamble correctly", function() {
|
||||
var code = UglifyJS.minify("#!/usr/bin/node\nvar x = 10;", {
|
||||
fromString: true,
|
||||
output: { preamble: "/* Build */" }
|
||||
}).code;
|
||||
assert.strictEqual(code, "#!/usr/bin/node\n/* Build */\nvar x=10;");
|
||||
})
|
||||
});
|
||||
|
||||
@@ -3,17 +3,13 @@ var assert = require("assert");
|
||||
|
||||
describe("minify() with input file globs", function() {
|
||||
it("minify() with one input file glob string.", function() {
|
||||
var result = Uglify.minify("test/input/issue-1242/foo.*", {
|
||||
compress: { collapse_vars: true }
|
||||
});
|
||||
var result = Uglify.minify("test/input/issue-1242/foo.*");
|
||||
assert.strictEqual(result.code, 'function foo(o){print("Foo:",2*o)}var print=console.log.bind(console);');
|
||||
});
|
||||
it("minify() with an array of one input file glob.", function() {
|
||||
var result = Uglify.minify([
|
||||
"test/input/issue-1242/b*.es5",
|
||||
], {
|
||||
compress: { collapse_vars: true }
|
||||
});
|
||||
]);
|
||||
assert.strictEqual(result.code, 'function bar(n){return 3*n}function baz(n){return n/2}');
|
||||
});
|
||||
it("minify() with an array of multiple input file globs.", function() {
|
||||
@@ -21,8 +17,8 @@ describe("minify() with input file globs", function() {
|
||||
"test/input/issue-1242/???.es5",
|
||||
"test/input/issue-1242/*.js",
|
||||
], {
|
||||
compress: { collapse_vars: true }
|
||||
compress: { toplevel: true }
|
||||
});
|
||||
assert.strictEqual(result.code, 'function bar(n){return 3*n}function baz(n){return n/2}function foo(n){print("Foo:",2*n)}var print=console.log.bind(console);print("qux",bar(3),baz(12)),foo(11);');
|
||||
assert.strictEqual(result.code, 'var print=console.log.bind(console);print("qux",function(n){return 3*n}(3),function(n){return n/2}(12)),function(n){print("Foo:",2*n)}(11);');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -78,6 +78,7 @@ describe("minify", function() {
|
||||
});
|
||||
it("Should process inline source map", function() {
|
||||
var code = Uglify.minify("./test/input/issue-520/input.js", {
|
||||
compress: { toplevel: true },
|
||||
inSourceMap: "inline",
|
||||
sourceMapInline: true
|
||||
}).code + "\n";
|
||||
@@ -155,7 +156,7 @@ describe("minify", function() {
|
||||
assert.strictEqual(code, "// comment1 comment2\nbar();");
|
||||
});
|
||||
it("should not drop #__PURE__ hint if function is retained", function() {
|
||||
var result = Uglify.minify("var a = /*#__PURE__*/(function(){return 1})();", {
|
||||
var result = Uglify.minify("var a = /*#__PURE__*/(function(){ foo(); })();", {
|
||||
fromString: true,
|
||||
output: {
|
||||
comments: "all",
|
||||
@@ -163,7 +164,7 @@ describe("minify", function() {
|
||||
}
|
||||
});
|
||||
var code = result.code;
|
||||
assert.strictEqual(code, "var a=/*#__PURE__*/function(){return 1}();");
|
||||
assert.strictEqual(code, "var a=/*#__PURE__*/function(){foo()}();");
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
54
test/mocha/release.js
Normal file
54
test/mocha/release.js
Normal file
@@ -0,0 +1,54 @@
|
||||
var assert = require("assert");
|
||||
var spawn = require("child_process").spawn;
|
||||
|
||||
if (!process.env.UGLIFYJS_TEST_ALL) return;
|
||||
|
||||
function run(command, args, done) {
|
||||
var id = setInterval(function() {
|
||||
process.stdout.write("\0");
|
||||
}, 5 * 60 * 1000);
|
||||
spawn(command, args, {
|
||||
stdio: "ignore"
|
||||
}).on("exit", function(code) {
|
||||
clearInterval(id);
|
||||
assert.strictEqual(code, 0);
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
describe("test/benchmark.js", function() {
|
||||
this.timeout(5 * 60 * 1000);
|
||||
[
|
||||
"-b",
|
||||
"-b bracketize",
|
||||
"-m",
|
||||
"-mc passes=3",
|
||||
"-mc passes=3,toplevel",
|
||||
"-mc passes=3,unsafe",
|
||||
"-mc keep_fargs=false,passes=3",
|
||||
"-mc keep_fargs=false,passes=3,pure_getters,unsafe,unsafe_comps,unsafe_math,unsafe_proto",
|
||||
].forEach(function(options) {
|
||||
it("Should pass with options " + options, function(done) {
|
||||
var args = options.split(/ /);
|
||||
args.unshift("test/benchmark.js");
|
||||
run(process.argv[0], args, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("test/jetstream.js", function() {
|
||||
this.timeout(20 * 60 * 1000);
|
||||
it("Should install phantomjs-prebuilt", function(done) {
|
||||
run("npm", ["install", "phantomjs-prebuilt@2.1.14"], done);
|
||||
});
|
||||
[
|
||||
"-mc warnings=false",
|
||||
"-mc keep_fargs=false,passes=3,pure_getters,unsafe,unsafe_comps,unsafe_math,unsafe_proto,warnings=false",
|
||||
].forEach(function(options) {
|
||||
it("Should pass with options " + options, function(done) {
|
||||
var args = options.split(/ /);
|
||||
args.unshift("test/jetstream.js");
|
||||
run(process.argv[0], args, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -6,6 +6,7 @@ var U = require("../tools/node");
|
||||
var path = require("path");
|
||||
var fs = require("fs");
|
||||
var assert = require("assert");
|
||||
var vm = require("vm");
|
||||
|
||||
var tests_dir = path.dirname(module.filename);
|
||||
var failures = 0;
|
||||
@@ -165,6 +166,51 @@ function run_compress_tests() {
|
||||
failed_files[file] = 1;
|
||||
}
|
||||
}
|
||||
if (test.expect_stdout) {
|
||||
try {
|
||||
var stdout = run_code(input_code);
|
||||
if (test.expect_stdout === true) {
|
||||
test.expect_stdout = stdout;
|
||||
}
|
||||
if (test.expect_stdout != stdout) {
|
||||
log("!!! Invalid input or expected stdout\n---INPUT---\n{input}\n---EXPECTED STDOUT---\n{expected}\n---ACTUAL STDOUT---\n{actual}\n\n", {
|
||||
input: input_code,
|
||||
expected: test.expect_stdout,
|
||||
actual: stdout,
|
||||
});
|
||||
failures++;
|
||||
failed_files[file] = 1;
|
||||
} else {
|
||||
try {
|
||||
stdout = run_code(output);
|
||||
if (test.expect_stdout != stdout) {
|
||||
log("!!! failed\n---INPUT---\n{input}\n---EXPECTED STDOUT---\n{expected}\n---ACTUAL STDOUT---\n{actual}\n\n", {
|
||||
input: input_code,
|
||||
expected: test.expect_stdout,
|
||||
actual: stdout,
|
||||
});
|
||||
failures++;
|
||||
failed_files[file] = 1;
|
||||
}
|
||||
} catch (ex) {
|
||||
log("!!! Execution of output failed\n---INPUT---\n{input}\n---OUTPUT---\n{output}\n--ERROR--\n{error}\n\n", {
|
||||
input: input_code,
|
||||
output: output,
|
||||
error: ex.toString(),
|
||||
});
|
||||
failures++;
|
||||
failed_files[file] = 1;
|
||||
}
|
||||
}
|
||||
} catch (ex) {
|
||||
log("!!! Execution of input failed\n---INPUT---\n{input}\n--ERROR--\n{error}\n\n", {
|
||||
input: input_code,
|
||||
error: ex.toString(),
|
||||
});
|
||||
failures++;
|
||||
failed_files[file] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var tests = parse_test(path.resolve(dir, file));
|
||||
@@ -214,6 +260,23 @@ function parse_test(file) {
|
||||
}));
|
||||
}
|
||||
|
||||
function read_string(stat) {
|
||||
if (stat.TYPE == "SimpleStatement") {
|
||||
var body = stat.body;
|
||||
switch(body.TYPE) {
|
||||
case "String":
|
||||
return body.value;
|
||||
case "Array":
|
||||
return body.elements.map(function(element) {
|
||||
if (element.TYPE !== "String")
|
||||
throw new Error("Should be array of strings");
|
||||
return element.value;
|
||||
}).join("\n");
|
||||
}
|
||||
}
|
||||
throw new Error("Should be string or array of strings");
|
||||
}
|
||||
|
||||
function get_one_test(name, block) {
|
||||
var test = { name: name, options: {} };
|
||||
var tw = new U.TreeWalker(function(node, descend){
|
||||
@@ -226,12 +289,13 @@ function parse_test(file) {
|
||||
return true;
|
||||
}
|
||||
if (node instanceof U.AST_LabeledStatement) {
|
||||
var label = node.label;
|
||||
assert.ok(
|
||||
["input", "expect", "expect_exact", "expect_warnings"].indexOf(node.label.name) >= 0,
|
||||
["input", "expect", "expect_exact", "expect_warnings", "expect_stdout"].indexOf(label.name) >= 0,
|
||||
tmpl("Unsupported label {name} [{line},{col}]", {
|
||||
name: node.label.name,
|
||||
line: node.label.start.line,
|
||||
col: node.label.start.col
|
||||
name: label.name,
|
||||
line: label.start.line,
|
||||
col: label.start.col
|
||||
})
|
||||
);
|
||||
var stat = node.body;
|
||||
@@ -239,15 +303,16 @@ function parse_test(file) {
|
||||
if (stat.body.length == 1) stat = stat.body[0];
|
||||
else if (stat.body.length == 0) stat = new U.AST_EmptyStatement();
|
||||
}
|
||||
if (node.label.name === "expect_exact") {
|
||||
if (!(stat.TYPE === "SimpleStatement" && stat.body.TYPE === "String")) {
|
||||
throw new Error(
|
||||
"The value of the expect_exact clause should be a string, " +
|
||||
"like `expect_exact: \"some.exact.javascript;\"`");
|
||||
if (label.name == "expect_exact") {
|
||||
test[label.name] = read_string(stat);
|
||||
} else if (label.name == "expect_stdout") {
|
||||
if (stat.TYPE == "SimpleStatement" && stat.body instanceof U.AST_Boolean) {
|
||||
test[label.name] = stat.body.value;
|
||||
} else {
|
||||
test[label.name] = read_string(stat) + "\n";
|
||||
}
|
||||
test[node.label.name] = stat.body.start.value
|
||||
} else {
|
||||
test[node.label.name] = stat;
|
||||
test[label.name] = stat;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -269,3 +334,17 @@ function evaluate(code) {
|
||||
code = make_code(code, { beautify: true });
|
||||
return new Function("return(" + code + ")")();
|
||||
}
|
||||
|
||||
function run_code(code) {
|
||||
var stdout = "";
|
||||
var original_write = process.stdout.write;
|
||||
process.stdout.write = function(chunk) {
|
||||
stdout += chunk;
|
||||
};
|
||||
try {
|
||||
new vm.Script(code).runInNewContext({ console: console }, { timeout: 5000 });
|
||||
return stdout;
|
||||
} finally {
|
||||
process.stdout.write = original_write;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user